Password.h и keypad.h меняют скетч пароля для Arduino
У меня фиксированный пароль. Если нажать на клавиатуре букву "D" и ввести правильный пароль, фиксированный пароль будет изменен. Этот новый введенный пароль теперь является правильным паролем, пока пользователь снова не решит сменить пароль. Это не работает. Как это исправить?
#include <Keypad.h>
#include <Password.h>
const byte ROWS = 4; //четыре строки
const byte COLS = 4; //четыре столбца
const char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
const byte rowPins[ROWS] = {9,8,7,6};
const byte colPins[COLS] = {5,4,3,2};
Keypad keypad { makeKeymap(keys), rowPins, colPins, ROWS, COLS };
Password passwd = Password("123A4");
char passwd2;
void setup() {
Serial.begin(9600);
}
void loop() {
char key = keypad.getKey();
if (key != NO_KEY){
delay(60);
switch (key){
case 'D': changepasswd(); break;
case '*': checkpasswd(); break;
case '#': passwd.reset(); break;
default: passwd.append(key);
}
}
}
void checkpasswd() {
Serial.print(passwd2);
if (passwd.evaluate()){
Serial.println(" OK.");
} else {
Serial.println(" Wrong password!");
}
passwd.reset();
}
void changepasswd() {
char key = keypad.getKey();
delay(60);
Serial.print(key);
passwd2 += key;
passwd.set(passwd2);
Serial.print("Password changed to ");
Serial.println(passwd2);
}
@Luiz Vaughan, 👍0
1 ответ
Лучший ответ:
Логика вашей функции искажена:
- Функция
checkpasswd()
: Большая часть функции в порядке, но вам не нужно отправлятьpasswd2
через Serial, так как он не имеет никакого отношения к этой функции. Вы используете переменную только для установки нового пароля. Вы можете выбросить этот оператор печати. - Функция
changepasswd()
: Здесь кроется проблема. Скорее всего,getKey()
возвращает здесьNO_KEY
, который определен как нулевой символ. Поэтому при выводе его в Serial вы ничего там не видите (нулевой символ отмечает конец строки в C/C++). Вы устанавливаете пароль как нулевой символ, который не может быть введен пользователем. Также есть еще одна ловушка: Сайт Arduino Playground для библиотекиPassword
утверждает для функцииset()
:Внимание: новый пароль должен быть глобальной переменной (не локальной) функциональная переменная), так как эта функция копирует указатель на новую пароль в библиотеку, а не копия пароля.
Поскольку переменная key
является только локальной, после функции библиотека Password
имеет свой внутренний указатель, указывающий на теперь освобожденное пространство памяти. В какой-то другой точке программы это пространство может быть записано снова, фактически меняя пароль на что-то другое.
И, наконец, функция не содержит никаких циклов, поэтому будет введен только 1 символ, а новый установленный пароль может быть длиной только 1 символ. Переменная буфера passwd2
имеет тип char
, поэтому также только 1 символ. Что вам действительно нужно, так это char []
(массив символов).
Вот фрагмент кода (не проверенный), который должен реализовать это правильно:
char passwd2[6]=""; //глобальный буфер для нового пароля
// 6 байт, так как строка C должна заканчиваться нулевым символом
void changepasswd(){
for(byte i=0;i<5;i++){
char key = NO_KEY;
while(key == NO_KEY || key=='*' || key=='#' || key=='D') key = keypad.getKey();
passwd2[i] = key;
delay(60);
}
passwd2[5] = '\0'; //обеспечиваем правильное окончание строки
passwd.set(passwd2);
}
Обратите внимание на следующие моменты:
- Эта реализация блокирует выполнение программ, пока не будет введен полный действительный пароль. Она будет игнорировать все недействительные символы, которые вы используете для других целей (
#
,*
иD
). passwd.set(passwd2)
на самом деле необходим только в первый раз, когда мы меняем пароль, чтобы объектPassword
имел указатель на наш буфер. После этого мы технически можем изменить пароль непосредственно в буфере, не вызывая функциюset()
. Я включил ее здесь для удобства чтения и для того, чтобы сделать код немного более отказоустойчивым (против неправильного дальнейшего кодирования).- Это жестко закодировано для приема только 5-значных паролей. Если вам нужны пароли произвольной длины, вы можете начать программирование с этой основы.
- Устранение дребезга кнопок с помощью простого
delay()
может быть недостаточным в какой-то момент. Но насколько я понимаю исходный код библиотекиKeypad
, он также включает код для устранения дребезга, проверяя только каждые 10 мс на наличие измененной кнопки и возвращаяNO_KEY
в противном случае.
- Печать string and integer LCD
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Глобальные переменные занимают много места в динамической памяти.
- (Код ультразвукового датчика: такого файла или каталога нет)
- rfid_default_keys проверить с помощью RC522
- Команда strtok() с Serial связью