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
в противном случае.
Большое спасибо за ваше время на исправления и за ваши подробные объяснения. Ваше предложение было проверено и полностью работоспособно. С наилучшими пожеланиями!, @Luiz Vaughan
- Печать string and integer LCD
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Глобальные переменные занимают много места в динамической памяти.
- (Код ультразвукового датчика: такого файла или каталога нет)
- rfid_default_keys проверить с помощью RC522
- Команда strtok() с Serial связью
«Это не работает» — не совсем верное описание того, что происходит... пожалуйста, опишите, что на самом деле происходит., @jsotola
У вас нет цикла в
changepasswd()
, чтобы получить более одного символа в пароле. Кроме того, вы просто используете значение изgeKey()
без предварительной проверки, была ли действительно нажата допустимая клавиша после инициирования изменения. Разработайте логику своих функций., @chrisl@jsotola Пароль не меняется. Вот описание. Часть ввода по умолчанию "123A4" работает, и появляется сообщение ОК. Если вы вводите неверный код, он говорит "Неверный пароль". Пока все хорошо. Но когда дело доходит до изменения пароля с клавиатуры, он говорит "Пароль изменен на " и ничего не показывает. Если вы вводите новый пароль, он говорит "Неверный пароль"... если вы вводите пароль по умолчанию, он говорит "Неверный пароль"., @Luiz Vaughan
@chrisl Я работаю над этим целую неделю. Я не могу самостоятельно разобраться в логике своих функций на данном этапе. Этот код — лучшее, что я смог сделать, и поэтому я прошу помощи в его исправлении, потому что я больше не могу двигаться дальше., @Luiz Vaughan
@LuizVaughan,
если вы вводите пароль по умолчанию, он сообщает: "Неверный пароль"
.... так почему вы говорите, что пароль не меняется? .... из того, что вы сказали, он меняется .... вы просто не знаете, на что он меняется ..... я предлагаю вам потратить время на выяснение нового пароля и изменить свой код так, чтобы он сохранял тот пароль, который вам нужен, @jsotola**per1234; VE7JRO, sempaiscuba, MatsK** и **gre_gor**. Извините, но только вы, ребята, считаете этот пост непонятным. Проблема была хорошо понята и, кстати, решена за много часов до того, как вы все "поставили на паузу"., @Luiz Vaughan