This shows you the differences between two versions of the page.
pm:prj2022:arosca:safebox [2022/05/10 21:23] mihai.ionescu0911 [Download] |
pm:prj2022:arosca:safebox [2022/06/02 08:07] (current) mihai.ionescu0911 [Hardware Design] |
||
---|---|---|---|
Line 7: | Line 7: | ||
* Ca măsură alternativă de securitate, dacă identificatorul cardului nu este recunoscut, în maxim 10 secunde trebuie introdusă o parolă pe keypad. Se va aprinde intermitent un LED. | * Ca măsură alternativă de securitate, dacă identificatorul cardului nu este recunoscut, în maxim 10 secunde trebuie introdusă o parolă pe keypad. Se va aprinde intermitent un LED. | ||
* Dacă trece timpul, un buzzer va emite zgomot, alertând astfel o tentativă de acces neautorizat. În cazul autentificării corecte, încuietoarea seifului se deschide, prin acționarea unui servomotor. | * Dacă trece timpul, un buzzer va emite zgomot, alertând astfel o tentativă de acces neautorizat. În cazul autentificării corecte, încuietoarea seifului se deschide, prin acționarea unui servomotor. | ||
+ | * Dacă seiful este deschis, scanarea unui card RFID corect va determina închiderea acestuia. | ||
* Scopul proiectului este posibilitatea de depozitare a unor bunuri în mod sigur. | * Scopul proiectului este posibilitatea de depozitare a unor bunuri în mod sigur. | ||
===== Descriere generală ===== | ===== Descriere generală ===== | ||
Line 18: | Line 19: | ||
* keypad | * keypad | ||
* modul RFID (RC522) | * modul RFID (RC522) | ||
- | * card de proximitate RFID | + | * card, tag de proximitate RFID |
* servomotor | * servomotor | ||
* buzzer | * buzzer | ||
- | * LED | + | * LED multicolor |
- | * rezistențe | + | * rezistențe (1 x 100Ω, 2 x 220Ω) |
- | * fire | + | * jumpere |
+ | * headere | ||
+ | |||
+ | {{:pm:prj2022:arosca:safebox_circuit1.jpeg?300|}} | ||
+ | {{:pm:prj2022:arosca:safebox_circuit2.jpeg?300|}} | ||
+ | |||
+ | Schema electrică: | ||
+ | |||
+ | {{:pm:prj2022:arosca:safebox_schematic.png|}} | ||
===== Software Design ===== | ===== Software Design ===== | ||
+ | Codul sursă: | ||
+ | <code cpp> | ||
+ | // C++ code | ||
+ | // | ||
+ | #include <SPI.h> | ||
+ | #include <Servo.h> | ||
+ | #include <Keypad.h> | ||
+ | #include <MFRC522.h> | ||
+ | #define SERVO_PIN 2 | ||
+ | #define LED_GREEN_PIN A3 | ||
+ | #define LED_RED_PIN A4 | ||
+ | #define BUZZER_PIN A5 | ||
+ | #define SDA_PIN 10 | ||
+ | #define RST_PIN 9 | ||
- | <note tip> | + | #define WAIT 1000 |
- | TODO | + | #define WARNING_BUZZ_INTERVAL 700 |
+ | #define WARNING_TIMEOUT 10000 | ||
- | Descrierea codului aplicaţiei (firmware): | + | #define MAX_PASSWD_LENGTH 64 |
- | * mediu de dezvoltare (if any) (e.g. AVR Studio, CodeVisionAVR) | + | |
- | * librării şi surse 3rd-party (e.g. Procyon AVRlib) | + | |
- | * algoritmi şi structuri pe care plănuiţi să le implementaţi | + | |
- | * (etapa 3) surse şi funcţii implementate | + | |
- | </note> | + | |
- | ===== Rezultate Obţinute ===== | + | Servo servo; |
- | <note tip> | + | const byte ROW_NUM = 4; //four rows |
- | TODO | + | const byte COLUMN_NUM = 3; //3 columns |
- | Care au fost rezultatele obţinute în urma realizării proiectului vostru. | + | char keys[ROW_NUM][COLUMN_NUM] = { |
- | </note> | + | {'1','2','3'}, |
+ | {'4','5','6'}, | ||
+ | {'7','8','9'}, | ||
+ | {'*','0','#'} | ||
+ | }; | ||
- | ===== Concluzii ===== | + | // https://electropeak.com/learn/interfacing-4x3-membrane-matrix-keypad-with-arduino/ |
- | TODO | + | //byte pin_rows[ROW_NUM] = {5, 10, 9, 7}; //connect to the row pinouts of the keypad |
- | ===== Download ===== | + | //byte pin_column[COLUMN_NUM] = {6, 4, 8}; //connect to the column pinouts of the keypad |
- | TODO | + | byte pin_rows[ROW_NUM] = {3, 8, 7, 5}; //connect to the row pinouts of the keypad |
+ | byte pin_column[COLUMN_NUM] = {4, A2, 6}; //connect to the column pinouts of the keypad | ||
- | <note warning> | + | // Init keypad |
- | O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului: surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-). | + | Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM ); |
- | Fişierele se încarcă pe wiki folosind facilitatea **Add Images or other files**. Namespace-ul în care se încarcă fişierele este de tipul **:pm:prj20??:c?** sau **:pm:prj20??:c?:nume_student** (dacă este cazul). **Exemplu:** Dumitru Alin, 331CC -> **:pm:prj2009:cc:dumitru_alin**. | + | // Init RC522 |
- | </note> | + | MFRC522 rc522(SDA_PIN, RST_PIN); |
- | ===== Jurnal ===== | + | String enteredPasswd; |
+ | const String correctPasswd = "5378"; | ||
+ | const byte correctCodeSize = 4; | ||
+ | const byte correctCode[4] = {99, 88, 50, 25}; | ||
+ | | ||
+ | volatile int safeState; // 0 = open, 1 = closed | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | Serial.begin(9600); | ||
+ | SPI.begin(); | ||
+ | rc522.PCD_Init(); | ||
+ | Serial.println("Aproprie cardul.."); | ||
+ | enteredPasswd = ""; | ||
+ | pinMode(BUZZER_PIN, OUTPUT); | ||
+ | pinMode(LED_GREEN_PIN, OUTPUT); | ||
+ | pinMode(LED_RED_PIN, OUTPUT); | ||
+ | servo.attach(SERVO_PIN); | ||
+ | servo.write(0); | ||
+ | delay(500); | ||
+ | } | ||
+ | |||
+ | volatile int servoPos = 0; // var to store the servo pos | ||
+ | volatile bool wrongTag = false; | ||
+ | volatile bool proceed = false; | ||
+ | volatile bool state = 0; // 0 = closed, 1 = open | ||
+ | volatile unsigned long lastReadTime = 0; | ||
+ | volatile unsigned long previousMillisBuzz = 0; | ||
+ | volatile unsigned long warningStateStart = 0; | ||
+ | |||
+ | bool checkPasswd(String enteredPasswd) { | ||
+ | int length = enteredPasswd.length(); | ||
+ | if (length != correctPasswd.length()) { | ||
+ | return false; | ||
+ | } | ||
+ | | ||
+ | for (int i = 0; i < length; i++) { | ||
+ | if (correctPasswd[i] != enteredPasswd[i]) { | ||
+ | return false; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return true; | ||
+ | } | ||
+ | |||
+ | void actLED() { | ||
+ | if (!state) { | ||
+ | analogWrite(LED_GREEN_PIN, 0); | ||
+ | analogWrite(LED_RED_PIN, 255); | ||
+ | } else { | ||
+ | analogWrite(LED_RED_PIN, 0); | ||
+ | analogWrite(LED_GREEN_PIN, 255); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void actBuzzer() { | ||
+ | if (!state) { | ||
+ | tone(BUZZER_PIN, 100, 300); | ||
+ | } else { | ||
+ | tone(BUZZER_PIN, 100, 100); | ||
+ | delay(200); | ||
+ | tone(BUZZER_PIN, 300, 100); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void warningBuzz() { | ||
+ | unsigned long currentMillis = millis(); | ||
+ | |||
+ | if (currentMillis - previousMillisBuzz >= WARNING_BUZZ_INTERVAL) { | ||
+ | previousMillisBuzz = currentMillis; | ||
+ | tone(BUZZER_PIN, 350, 200); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void wrongPasswordBuzz() { | ||
+ | tone(BUZZER_PIN, 450); | ||
+ | delay(1000); | ||
+ | noTone(BUZZER_PIN); | ||
+ | } | ||
+ | |||
+ | void angryBuzz() { | ||
+ | Serial.println("INTRUDER"); | ||
+ | for (int i = 0; i < 80; i++) { | ||
+ | if (i % 2 == 0) { | ||
+ | analogWrite(LED_GREEN_PIN, 0); | ||
+ | analogWrite(LED_RED_PIN, 255); | ||
+ | } else { | ||
+ | analogWrite(LED_GREEN_PIN, 255); | ||
+ | analogWrite(LED_RED_PIN, 0); | ||
+ | } | ||
+ | tone(BUZZER_PIN, 50); | ||
+ | delay(50); | ||
+ | } | ||
+ | |||
+ | noTone(BUZZER_PIN); | ||
+ | } | ||
+ | |||
+ | void lock_unlock() { | ||
+ | servo.write(90 - servoPos); | ||
+ | servoPos = 90 - servoPos; | ||
+ | state = !state; | ||
+ | |||
+ | actLED(); | ||
+ | actBuzzer(); | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | // LED CODE | ||
+ | actLED(); | ||
+ | // RFID READER CODE | ||
+ | | ||
+ | if (!wrongTag) { | ||
+ | // Look for new cards | ||
+ | if (rc522.PICC_IsNewCardPresent()) { | ||
+ | // Select one of the cards | ||
+ | unsigned long time = millis(); | ||
+ | if (time - lastReadTime >= WAIT) { | ||
+ | lastReadTime = time; | ||
+ | if (rc522.PICC_ReadCardSerial()) { | ||
+ | //Show UID on serial monitor | ||
+ | byte letter; | ||
+ | | ||
+ | for (byte i = 0; i < correctCodeSize; i++) { | ||
+ | if (rc522.uid.uidByte[i] != correctCode[i]) { | ||
+ | Serial.println("ERROR! Invalid tag! Enter keys!"); | ||
+ | // TODO: intermittent buzz | ||
+ | warningStateStart = millis(); | ||
+ | enteredPasswd = ""; | ||
+ | wrongTag = true; | ||
+ | } else { | ||
+ | Serial.println("OK"); | ||
+ | proceed = true; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } else { | ||
+ | warningBuzz(); | ||
+ | |||
+ | unsigned long currTime = millis(); | ||
+ | if (currTime - warningStateStart >= WARNING_TIMEOUT) { | ||
+ | angryBuzz(); | ||
+ | warningStateStart = millis(); // reset | ||
+ | } | ||
+ | | ||
+ | // Wrong tag => have to read keypad | ||
+ | char key = keypad.getKey(); | ||
+ | if (key) { | ||
+ | if (key == '#') { | ||
+ | bool validPasswd = checkPasswd(enteredPasswd);p | ||
+ | if (validPasswd) { | ||
+ | Serial.println("OK!"); | ||
+ | proceed = true; | ||
+ | wrongTag = false; | ||
+ | } else { | ||
+ | wrongPasswordBuzz(); | ||
+ | } | ||
+ | | ||
+ | enteredPasswd=""; | ||
+ | } | ||
+ | | ||
+ | else { | ||
+ | enteredPasswd += key; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (proceed) { | ||
+ | lock_unlock(); | ||
+ | } | ||
+ | proceed = false; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ===== Rezultate Obţinute ===== | ||
+ | Proiectul funcționează conform descrierii. RFID Readerul și Keypadul acționează închiderea/deschiderea ușii. | ||
+ | |||
+ | {{:pm:prj2022:arosca:safebox_open.jpeg?200|}} | ||
+ | {{:pm:prj2022:arosca:safebox_closed.jpeg?200|}} | ||
+ | |||
+ | ===== Concluzii ===== | ||
+ | Proiectul a fost util pentru deprinderea atât cu programarea în Arduino, cât și implementarea hardware. | ||
+ | ===== Download ===== | ||
+ | Arhiva cu codul sursă: {{:pm:prj2022:arosca:safebox_pm_mihai_ionescu.zip|}} | ||
+ | ===== Jurnal ===== | ||
<note tip> | <note tip> | ||
- | Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. | + | **10.05.2022** - Creare pagină wiki (introducere + schemă bloc + listă piese) |
+ | |||
+ | **31.05.2022** - Finalizare proiect | ||
+ | |||
+ | **02.01.2022** - Completare documentație | ||
</note> | </note> | ||
===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||
+ | [[https://www.arduino.cc/reference/en/libraries/keypad/]] | ||
- | <note> | + | [[https://www.arduino.cc/reference/en/libraries/mfrc522/]] |
- | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | + | |
- | </note> | + | [[https://www.arduino.cc/reference/en/libraries/easy-mfrc522/]] |
<html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | ||