Кодовый замок с 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. Попробуйте обновить. Похоже, я ошибся, когда сказал, что этот символ в коде и попал с копипастой.
Дальше не копал.
перекопав весь код (по вашему совету) в очередной раз было обнажено множество ошибок в тексте (часть кода была на Итальянском с ошибками... постарался исправить... но не все ошибки пропали... немного исправленный скетч с изменениями==>
// 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 DS1307 rtc; Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEY_ROWS, KEY_COLUMNS); SoftwareSerial mySerial(SDA, SCL); TOTP totp = TOTP(hmacKey, 10); char code [7]; char buffer serial [14]; int serial ; void setup () { Wire.begin (); rtc.begin (); // Initialize serial communication Serial.begin (9600); Serial.begin display (9600); // Expect the display boot and the disappearance of the splash screen delay (500); Serial.println ("OTP lock"); Serial.print ln (); // Initialization PIN pinMode (PIN_BUZZER, OUTPUT); pinMode (PIN_LEDROSSO, OUTPUT); pinMode (PIN_LEDVERDE, OUTPUT); pinMode (PIN_RELAY, OUTPUT); // Initialize variables Index code = -1; serial Index = -1; // Initial state, lock CLOSED Screen cleaner (); change Status Lock (false); update Second Line (); } void loop () { // Check if you have received a serial character if (Serial.available ()> 0) { byte in byte = Serial.read (); // If the received message was received by the newline (0x0A) interpret the command received if (in byte == 0x0A) execute serial command (); // Otherwise Records in the buffer else { serial Index ++; if (serial Index == 14) serial Index = 0; Serial buffer [serial Index] = in byte; } } // 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 store the array if (key - '0'> = 0 && key - '0' <10) { Index code ++; Entered code [IndexIndex] = key; Serial.write display (key); // If it were inserted 6 digits, check the code if (code Index == 5) verification Code (); } // If the button is '*' gate the last number entered else if (key == '*' && index code> = 0) { Index code--; update Second Line (); } // If the button is '#' it resets the insertion else if (key == '#') { Index code = -1; update Second Line (); } } } void command execute serial () { // Possible commands are: //? displays date and time from the RTC beds //! GTCMaahhmmss sets the new date and time (dd / mm / yy hh: mm: ss) RTC // Reset the buffer serial Index = -1; if (buffer Serial [0] == '?') print Date Time (); else if (Serial buffer [0] == '!') { // Verify that the twelve following characters are numbers for (int i = 1; i <13; i ++) if (! is Digit (bufferSeriale [i])) { Serial.print (F ("Invalid character (not a number):")); Serial.print ln (bufferSeriale [i]); return; } // Convert to one of two int day = (Serial buffer [1] - '0') * 10 + (Serial buffer [2] - '0'); int month = (Serial buffer [3] - '0') * 10 + (Serial buffer [4] - '0'); int year = 2000 + (Serial buffer [5] - '0') * 10 + (bufferSerial [6] - '0'); int now = (Serial buffer [7] - '0') * 10 + (bufferSerial [8] - '0'); int minutes = (Serial buffer [9] - '0') * 10 + (Serial buffer [10] - '0'); int seconds = (Serial buffer [11] - '0') * 10 + (Serial buffer [12] - '0'); // The perform data validation checks if (day <1 || day> 31) { Serial.print (F ("The specified day is not valid:")); Serial.print ln (day); return; } if (month <1 || month> 12) { Serial.print (F ("The specified month is not valid:")); Serial.print ln (month); return; } if (now> 24) { Serial.print (F ("The specified time is not valid:")); Serial.print ln (now); return; } if (minutes> 59) { Serial.print (F ("The specified minutes are not valid:")); Serial.print ln (minutes); return; } if (seconds> 59) { Serial.print (F ("The specified seconds are not valid:")); Serial.print ln (seconds); return; } // Save time and visualize updated rtc.adjust (Date Time (year, month, day, hour, minute, second)); Serial.print ln (F ("Updated RTC")); printing Date Time (); } else { Serial.print (F ("Unknown command:")); Serial.print ln (Serial buffer [0]); } } void print Date Time () { DateTime now = rtc.now (); Serial.print (F ("Current date and time:")); 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.print ln (); } void changes of status lock (Open lock bool) { if open lock { digital Write (PIN_RELAY, HIGH); digital Write (PIN_LED GREEN, HIGH); digital Write (PIN_LED RED, LOW); Serial.write display (254); Serial.write display (128); Serial.write display ("OPEN"); } else { digital Write (PIN_RELAY, LOW); digital Write (PIN_LED GREEN, LOW); digital Write (PIN_LED RED, HIGH); Serial.write display (254); Serial.write display (128); Serial.write display ("CLOSED"); } } clean screen (); Serial.write display (254); Serial.write display (128); Serial.write display (""); Serial.write display (""); } void updates second row () { Serial.write display (254); Serial.write display (192); Serial.write display ("PIN ->"); Serial.write display (254); Serial.write display (200); for (int i = 0; i <= code Index; i ++) Serial.write display (code Inserted [i]); } void verification Code () { // Get the current timestamp from the RTC and google authenticator date time now = rtc.now (); long GMT = now.unixtime (); long timestep = GMT / 30; // Verify the current timestamp bool code Ok = false; for (int i = -1; i <= 1; i ++) { char * Generated code = totp.get Code From Steps (time Step + i); Serial.println (Generated code); if (strcmp (code inserted, code generated) == 0) code Ok = true; } // I clean the screen clean screen (); // it is the lock if (Ok code) { #if def BUZZER_ON tone (PIN_BUZZER, 660); delay (100); noTone (PIN_BUZZER); delay (200); tone (PIN_BUZZER, 660); delay (100); noTone (PIN_BUZZER); #endif change Lock Status (true); // If the mode is an impulse mode if (shared mode == shutter mode) { delay (opening time); change lock status (false); } // If it is stable, it will be stable. else { char key; do { key = keypad.getKey (); } while (key! = KEY_KEY); change status lock (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 Serial.write display (254); Serial.write display (128); Serial.write display ("CODE ERRATO!"); delay (500); #ifdef BUZZER_ON noTone (PIN_BUZZER); #endif clean screen (); delay (500); } Serial.write display (254); Serial.write display (128); Serial.write display ("CLOSED"); } // reset Index code = -1; update Second Line (); }Первая и единственная пока что ошибка в том, что разбираться надо начинать не с этого.
Поставил на телефон приложенте (ArduinoCode) и загрузив в него данный код был впечетлен... там есть вкладка в которой список ошибок в коде... часть подправил а с остальнимы не знаю что делать ...
список строк с ошибками==>
int code [7]; -(строка 24) char buffer serial [14]; -(строка 25) int serial ; -(строка 26) int cleaner(); -(строка 55) void command execute serial () { -(строка 115) void updates second row () { -(строка 222)подскажите что в них не так?
Поставил на телефон приложенте (ArduinoCode) и загрузив в него данный код был впечетлен... там есть вкладка в которой список ошибок в коде... часть подправил а с остальнимы не знаю что делать ...
список строк с ошибками==>
int code [7]; -(строка 24) char buffer serial [14]; -(строка 25) int serial ; -(строка 26) int cleaner(); -(строка 55) void command execute serial () { -(строка 115) void updates second row () { -(строка 222)подскажите что в них не так?
Если между buffer и serial - пробел, то это и есть ошибка.
Вообще вам правильно сказали - не с того начинаете. Если вы не знакомы с программированием, то вы взяли для старта слишком трудный код для себя. Поразбирайтесь сначала с примерами из Arduino IDE и почитайте учебник по Arduino (хотя бы http://arduino.ru/Reference). Без этого вы только тратите своё и чужое время и внимание впустую.