Заполнение массива символов пробелами
Когда я запускаю этот код, мои массивы pin
и pinCheck
не заполняются результатами keypad.getKey()
. Если я напечатаю значение для каждого индекса, результат будет пустым. Насколько я могу судить, я либо не записываю символ в массив, либо неправильно читаю массив, когда приходит время печатать на последовательном мониторе, либо .getKey()
работает только в основные или циклические функции.
#include <Key.h>
#include <Keypad.h>
void armDisarm(void);
boolean array_cmp(char, char, int, int);
bool isArmed = 0;
char pin[3];
char pinCheck[3];
const byte ROWS = 4; // количество строк
const byte COLS = 4; // Число столбцов
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'#','0','*','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; // распиновка ряда клавиатуры R1 = D8, R2 = D7, R3 = D6, R4 = D5
byte colPins[COLS] = {5, 4, 3, 2}; // распиновка столбцов клавиатуры C1 = D4, C2 = D3, C3 = D2
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (isArmed == 1)
{
Serial.println("SYSTEM ARMED! ENTER PIN TO DISARM!");
}
else
{
Serial.println("SYSTEM DISARMED! ENTER PIN TO ARM!");
}
armDisarm();
}
void armDisarm(void)
{
while(true)
{
if (isArmed == 0)
{
for (int i = 0; i < 4;)
{
if (keypad.getKey() == NO_KEY)
{
continue;
}
pin[i] = keypad.getKey();
Serial.println(pin[i]);
i++;
}
isArmed = 1;
return;
}
else if (isArmed == 1)
{
for (int j = 0; j < 4;)
{
if (keypad.getKey() == NO_KEY)
{
continue;
}
pinCheck[j] = keypad.getKey();
Serial.println(pin[j]);
j++;
}
for (int k = 0; k < 4; k++)
{
if(pinCheck[k] != pin[k])
{
isSame = 0;
break;
}
else
{
isSame = 1;
}
}
if (array_cmp(pin, pinCheck, sizeof(pin), sizeof(pinCheck)) == 1)
{
Serial.println("same pin"); //используется для отладки
isArmed = 0;
return;
}
else
{
Serial.println("INCORRECT PIN! CLAYMORE ROOMBA DEPLOYED!");
}
}
}
}
boolean array_cmp(char a[sizeof(pin)], char b[sizeof(pinCheck)], int len_a, int len_b)
{
int n;
// если их длины разные, возвращаем false
if (len_a != len_b)
{
return false;
}
// Проверяем, чтобы все элементы были одинаковыми. если нет, вернуть false
for (n = 0 ;n < len_a; n++)
{
if (a[n]!= b[n])
{
return false;
}
}
//ок, если мы еще не вернулись, они равны :)
return true;
}
@Ryan, 👍-1
2 ответа
Лучший ответ:
Прежде всего, есть одна важная особенность библиотеки Keypad, которую вы
надо понимать: он неблокирующий. Когда вы вызываете keypad.getKey()
,
он возвращается немедленно и почти всегда возвращает NO_KEY
для сигнала
что ни одна клавиша не была нажата с момента последней проверки. Если ключ был
нажата, keypad.getKey()
возвращает эту клавишу, а затем, при следующем
вызов, он снова возвращает NO_KEY
, так как ни одна клавиша не была нажата с момента
последний раз, когда вы проверяли.
Важно понимать, что всякий раз, когда нажимается клавиша, эта клавиша
возвращается только один раз с помощью keypad.getKey()
. Вы должны успеть не промахнуться
это!
Теперь рассмотрим этот цикл:
for (int i = 0; i < 4;)
{
if (keypad.getKey() == NO_KEY)
{
continue;
}
pin[i] = keypad.getKey();
Serial.println(pin[i]);
i++;
}
Это будет работать очень быстро и почти всегда
Оператор continue
. При нажатии клавиши keypad.getKey()
возвращает
значение отличается от NO_KEY
(и это значение потеряно), тест
внутри if
является ложным, и следующий за ним оператор выполняется,
а именно:
pin[i] = keypad.getKey();
Но это другой вызов keypad.getKey()
, который возвращает NO_KEY
,
так что это то, что сохраняется в массиве.
Вот как я бы написал этот цикл:
for (int i = 0; i < 3; i++)
{
char key = NO_KEY;
while (key == NO_KEY)
{
key = keypad.getKey();
}
pin[i] = key;
Serial.println(pin[i]);
}
Обратите внимание, что:
Значение, возвращаемое
keypad.getKey()
, всегда сохраняется в переменная, вы не хотите ее потерять! Когда мы получаем что-то другое чемNO_KEY
, сохраняется значение, ранее сохраненное в переменной в массиве.Я переместил
i++
на место, чтобы избежать запутанный способ управления циклом.if
сталwhile
, потому что мы не хотим переходить к следующую итерацию, пока мы действительно не прочитаем действительный ключ.Цикл выполняет только три итерации, поскольку это длина массив
pin
, который в противном случае был бы переполнен.
В дополнение к ответу Эдгара Бонца. Я должен предупредить вас, что ваш код продолжает добавлять позицию, поскольку каждый раз, когда вы проверяете массив, вы увеличиваете значение i. В результате вы заполняете массивы NO_KEY.
Кроме того, ранее у нас была встроенная сигнализация безопасности на Arduino (или мы не должны знать, что вы делаете?). Я должен предупредить вас, что ожидание ввода с клавиатуры означает, что вы не проверяете тампер или тревогу, даже когда она включена, потому что вы застрял внутри функции без цикла, ожидая ввода. Я лично ввел глобальную структуру
struct foo{
char digits[4];
byte digit=0;
} pinCode;
Вы можете либо взять экземпляр структуры в качестве параметра своей функции, либо использовать ее для внутреннего использования, потому что она глобальная.
bool addDigit(char button){
/*здесь мы имеем дело со многими потенциальными входными данными*/
затем вы можете внутри своей функции назначить нажатую кнопку как
pinCode.digits[pinCode.digit]=button;
pinCode.digit++;
если вы передаете экземпляр структуры в качестве указателя, он изменится на
pinCode->digits[pinCode->digit]=button;
pinCode->digit++;
затем вы можете проверить эту функцию, если пароль подтвержден (нажата кнопка OK) и вернуть true.
Пока не достигнут конец пароля, просто верните false. ТАК внутри цикла у вас будет что-то вроде:
key = keypad.getKey();
if(key!=NO_KEY){
if(addDigit(key)) //Здесь выполняем действие на основе входных данных
}
// Делаем все остальное, что должен делать сигнал тревоги
- Хранение и секвенирование выходного значения (arduino)
- Ошибка при попытке динамического моделирования температуры
- Указатель на массив символов
- Программа для умножения чисел на самом деле не будет их умножать
- Проверить, возвращает ли какая-либо из внутренностей цикла 1, и удерживать ее, пока весь цикл снова не станет 0.
- Возможно ли иметь массив массивов int?
- Замена нескольких выводов pinMode() и digitalWrite() на массив
- Ошибка: invalid application of 'sizeof' to incomplete type 'int []' при попытке вычислить размер массива в библиотеке