Кодовый замок с OTP паролем (одноразовый пароль) привязанным к реальному времени (одноразовый пароль)
- Войдите на сайт для отправки комментариев
Втр, 30/10/2018 - 20:45
Доброго времени суток! Помогите решить проблему... решил реализовать проэкт но возникла проблемма в скетче.. так как я только начинаю разбиратся то не могу понять в чем проблемма...
Скетсч=>
// Libraries for DS1307 RTC #include <Wire.h> #include <DS1307.h> // Keyboard libraries #include <Key.h> #include <Keypad.h> // Libraries for creating OTP codes #include <sha1.h> #include <TOTP.h> // Serial software for the display #include <SoftwareSerial.h> // config file #include "CONFIG.h" // variables RTC_DS1307 rtc; Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEY_ROWS, KEY_COLUMNS); SoftwareSerial displaySerial(A1, A2); TOTP totp = TOTP(hmacKey, 10); char codiceInserito[7]; int codiceIndex; char bufferSeriale[14]; int serialIndex; void setup() { // Initialize RTC is configured the time when the sketch was compiled Wire.begin(); rtc.begin(); rtc.adjust(DateTime(__DATE__, __TIME__)); // Initialize serial communication Serial.begin(9600); displaySerial.begin(9600); // Expect the display boot and the disappearance of the splash screen delay(500); Serial.println("Serratura OTP"); Serial.println(); // Initialization PIN pinMode(PIN_BUZZER, OUTPUT); pinMode(PIN_LEDROSSO, OUTPUT); pinMode(PIN_LEDVERDE, OUTPUT); pinMode(PIN_RELAY, OUTPUT); // Initialize variables codiceIndex = -1; serialIndex = -1; // Initial state, lock CLOSED pulisciSchermo(); cambiaStatoSerratura(false); aggiornaSecondaRiga(); } void loop() { // Check whether you have received a serial character if (Serial.available() > 0) { byte inByte = Serial.read(); // If the received byte is the character of NewLine (0x0A) interpret the command received if(inByte == 0x0A) eseguiComandoSeriale(); // Otherwise I record in the buffer else { serialIndex++; if(serialIndex == 14) serialIndex = 0; bufferSeriale[serialIndex] = inByte; } } // Check if you press a key on the keyboard char key = keypad.getKey(); if (key != NO_KEY){ // Emit a sound #ifdef BUZZER_ON tone(PIN_BUZZER, 440); delay(100); noTone(PIN_BUZZER); #endif // If the key is a number, I visualize and memorize the array if(key - '0' >= 0 && key - '0' < 10) { codiceIndex++; codiceInserito[codiceIndex] = key; displaySerial.write(key); // If it were inserted 6 digits, check the code if(codiceIndex == 5) verificaCodice(); } // If the button is '*' gate the last number entered else if(key == '*' && codiceIndex >= 0) { codiceIndex--; aggiornaSecondaRiga(); } // If the button is '#' it resets the insertion else if(key == '#') { codiceIndex = -1; aggiornaSecondaRiga(); } } } void eseguiComandoSeriale() { // Possible commands are: //? displays date and time from the RTC beds //! GgMMaahhmmss sets the new date and time (dd / mm / yy hh: mm: ss) RTC // Reset the buffer serialIndex = -1; if(bufferSeriale[0] == '?') stampaDataOra(); else if(bufferSeriale[0] == '!') { // Verify that the twelve following characters are numbers for(int i = 1; i < 13; i++) if(!isDigit(bufferSeriale[i])) { Serial.print(F("Carattere non valido (non e' un numero): ")); Serial.println(bufferSeriale[i]); return; } // Convert in two by two in number characters int giorno = (bufferSeriale[1] - '0') * 10 + (bufferSeriale[2] - '0'); int mese = (bufferSeriale[3] - '0') * 10 + (bufferSeriale[4] - '0'); int anno = 2000 + (bufferSeriale[5] - '0') * 10 + (bufferSeriale[6] - '0'); int ora = (bufferSeriale[7] - '0') * 10 + (bufferSeriale[8] - '0'); int minuti = (bufferSeriale[9] - '0') * 10 + (bufferSeriale[10] - '0'); int secondi = (bufferSeriale[11] - '0') * 10 + (bufferSeriale[12] - '0'); // I perform data validation checks if(giorno < 1 || giorno > 31) { Serial.print(F("Il giorno specificato non e' valido: ")); Serial.println(giorno); return; } if(mese < 1 || mese > 12) { Serial.print(F("Il mese specificato non e' valido: ")); Serial.println(mese); return; } if(ora > 24) { Serial.print(F("L'ora specificata non e' valida: ")); Serial.println(ora); return; } if(minuti > 59) { Serial.print(F("I minuti specificati nono sono validi: ")); Serial.println(minuti); return; } if(secondi > 59) { Serial.print(F("I secondi specificati non sono validi: ")); Serial.println(secondi); return; } // Save time and visualize updated rtc.adjust(DateTime(anno, mese, giorno, ora, minuti, secondi)); Serial.println(F("RTC aggiornato")); stampaDataOra(); } else { Serial.print(F("Comando sconosciuto: ")); Serial.println(bufferSeriale[0]); } } void stampaDataOra() { DateTime now = rtc.now(); Serial.print(F("Data e ora attuali: ")); Serial.print(now.day(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.year(), DEC); Serial.print(" "); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println(); } void cambiaStatoSerratura(bool serraturaAperta) { if(serraturaAperta) { digitalWrite(PIN_RELAY, HIGH); digitalWrite(PIN_LEDVERDE, HIGH); digitalWrite(PIN_LEDROSSO, LOW); displaySerial.write(254); displaySerial.write(128); displaySerial.write(" APERTA "); } else { digitalWrite(PIN_RELAY, LOW); digitalWrite(PIN_LEDVERDE, LOW); digitalWrite(PIN_LEDROSSO, HIGH); displaySerial.write(254); displaySerial.write(128); displaySerial.write(" CHIUSA "); } } void pulisciSchermo() { displaySerial.write(254); displaySerial.write(128); displaySerial.write(" "); displaySerial.write(" "); } void aggiornaSecondaRiga() { displaySerial.write(254); displaySerial.write(192); displaySerial.write("PIN --> "); displaySerial.write(254); displaySerial.write(200); for(int i = 0; i <= codiceIndex; i++) displaySerial.write(codiceInserito[i]); } void verificaCodice() { // Get the current timestamp from the RTC and I divide it by 30 (TimeStep Google Authenticator) DateTime now = rtc.now(); long GMT = now.unixtime(); long timeStep = GMT / 30; // Verify if the code matches one of the three codes "close" to the current timestamp bool codiceOk = false; for(int i = -1; i <= 1; i++) { char* codiceGenerato = totp.getCodeFromSteps(timeStep + i); Serial.println(codiceGenerato); if(strcmp(codiceInserito, codiceGenerato) == 0) codiceOk = true; } // I clean the screen pulisciSchermo(); // If the code is ok, it emits a sound and I open the lock if(codiceOk) { #ifdef BUZZER_ON tone(PIN_BUZZER, 660); delay(100); noTone(PIN_BUZZER); delay(200); tone(PIN_BUZZER, 660); delay(100); noTone(PIN_BUZZER); #endif cambiaStatoSerratura(true); // If the mode is MODO_IMPULSO, look TEMPO_APERTURA milliseconds so I close the lock if(modoSerratura == MODO_IMPULSO) { delay(TEMPO_APERTURA); cambiaStatoSerratura(false); } // If it is MODO_STABILE, expect the pressure of TASTO_CHIUSURA button then close the lock else { char key; do { key = keypad.getKey(); } while(key != TASTO_CHIUSURA); cambiaStatoSerratura(false); } } // If the code is wrong, I see a message and emit a sound else { for(int i = 0; i < 3; i++) { #ifdef BUZZER_ON tone(PIN_BUZZER, 220); #endif displaySerial.write(254); displaySerial.write(128); displaySerial.write(" CODICE ERRATO! "); delay(500); #ifdef BUZZER_ON noTone(PIN_BUZZER); #endif pulisciSchermo(); delay(500); } displaySerial.write(254); displaySerial.write(128); displaySerial.write(" CHIUSA "); } // reset codiceIndex = -1; aggiornaSecondaRiga(); }
CONFIG.H
// Private key for generating the OTP codes uint8_t hmacKey[] = {0x65, 0x6c, 0x65, 0x74, 0x74, 0x72, 0x6f, 0x2d, 0x69, 0x6e}; // Buzzer on / off (comment out the line below to disable it #define BUZZER_ON // Of the lock operation mode // MODO_IMPULSO = // if the code is ok, the lock remains open for many milliseconds (defined below) // MODO_STABILE = // if the code is ok, the lock remains open until you press a key (defined below) #define MODO_IMPULSO 0 #define MODO_STABILE 1 byte modoSerratura = MODO_IMPULSO; // Of the lock opening time (in milliseconds) if MODO_IMPULSO #define TEMPO_APERTURA 2000 // Button to close the lock if MODO_STABILE #define TASTO_CHIUSURA 'D' // ----- Usually you not need to change anything below this line ----- // Definition of PIN #define PIN_BUZZER 6 #define PIN_LEDROSSO 11 #define PIN_LEDVERDE 12 #define PIN_RELAY 13 // Keyboard configuration #define KEY_ROWS 4 #define KEY_COLUMNS 4 char keys[KEY_ROWS][KEY_COLUMNS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[KEY_ROWS] = {2,3,4,5}; byte colPins[KEY_COLUMNS] = {7,8,9,10};
Строка 36 лишняя.
да но это стандартная часть скетча для клавиатури 4x4.. будет ли она после этого работать?
Будет.
убрал ошибка в 35 строке (redefinition of'char keys 4[4][4]'
Убирать из первого фрагмента нужно было.
Прошу прощения за тупость откуда именно?
У вас сколько 36-х строк?
rtc.adjust(DateTime(__DATE__, __TIME__));
Вот она лишняя. Эта строчка будет настраивать часы на время компиляции скетча. При каждом включении устройства.
Неплохо бы описать, в чём вы видите проблему (симптомы)? Я попробовал собрать проект, но не знаю, какую из библиотек для RTC1307 вы используете.
Ого спасибо.. мин через 29 смогу скинуть библиотеку
Ого спасибо.. мин через 29 смогу скинуть библиотеку
Лучше опишите проблему.
Сейчас приду домой смогу описать лог ошибки... а так вобщем непроходит компиляцию... выдает ошибку на ошибке
https://drive.google.com/open?id=1pC8yC-z2C9XypwjtOvqh1ymEz09cuZtm - это библиотека DS1307
ПОЛНЫЙ ЛОГ ПОСЛЕ КОМПИЛЯЦИИ КУЧА ОШИБОК..
Похоже, что вы не сами написали этот код, а скопипастили откуда-то. Вот и затесался посторонний символ, на который ругается компилятор.
код скинул один знакомый когда то.... а я только начинаю работу с arduino.... может знаете хоть куда копать?...
код скинул один знакомый когда то.... а я только начинаю работу с arduino.... может знаете хоть куда копать?...
1) Библиотека для RTC1307 по вашей ссылке не соответствует той, что этот скетч пытается использовать: 'RTC_DS1307' does not name a type
2) У меня не ругается на недопустимый символ ("Key.h:5:1: error: stray '\221' in program"), решите вопрос с библиотекой Kaypad. Попробуйте обновить. Похоже, я ошибся, когда сказал, что этот символ в коде и попал с копипастой.
Дальше не копал.
перекопав весь код (по вашему совету) в очередной раз было обнажено множество ошибок в тексте (часть кода была на Итальянском с ошибками... постарался исправить... но не все ошибки пропали... немного исправленный скетч с изменениями==>
Первая и единственная пока что ошибка в том, что разбираться надо начинать не с этого.
Поставил на телефон приложенте (ArduinoCode) и загрузив в него данный код был впечетлен... там есть вкладка в которой список ошибок в коде... часть подправил а с остальнимы не знаю что делать ...
список строк с ошибками==>
подскажите что в них не так?
Поставил на телефон приложенте (ArduinoCode) и загрузив в него данный код был впечетлен... там есть вкладка в которой список ошибок в коде... часть подправил а с остальнимы не знаю что делать ...
список строк с ошибками==>
подскажите что в них не так?
Если между buffer и serial - пробел, то это и есть ошибка.
Вообще вам правильно сказали - не с того начинаете. Если вы не знакомы с программированием, то вы взяли для старта слишком трудный код для себя. Поразбирайтесь сначала с примерами из Arduino IDE и почитайте учебник по Arduino (хотя бы http://arduino.ru/Reference). Без этого вы только тратите своё и чужое время и внимание впустую.