Проблема с кодовым замком
- Войдите на сайт для отправки комментариев
Вс, 25/06/2017 - 22:31
Всем привет. Есть такая проблемка. Хочу добавить в кодовый замок функцию возврата на экран приветствия, по истечению некоторого времени (скажем 10 секунд) , если пароль введён не полностью и висит на экране ввода.
Тоесть мне нужно, чтобы после нажатия какой либо клавиши, он считал 10 секунд (и при этом программа не останавливалась) и если никакая клавиша не была, то автоматически возвращался начальный экран...никак не могу понять как это реализовать. Спасибо заранее за помощь.
#include <Password.h> #include <Keypad.h> #include <LiquidCrystal.h> Password password = Password("3355770"); // Пароль int dlugosc = 7; // Длина пароля LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); // Значки состояния замка byte unlocked[8] = { 0b11111, 0b10001, 0b10000, 0b10000, 0b11111, 0b10101, 0b10001, 0b11111 }; byte locked[8] = { 0b11111, 0b10001, 0b10001, 0b10001, 0b11111, 0b10101, 0b10001, 0b11111 }; int p = 9; // Выход пъезоэлемента на 9 пин int ledRed = 10; int ledGreen = 11; int relay = 12; int ilosc; // Число нажатий // Таймер обратного отсчёта на 10 секунд int runTimer = 1; int runFor = 10; // Время в секундах const byte ROWS = 4; // 4 строки const byte COLS = 3; // 3 столбца char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'*', '0', '#'} }; byte rowPins[ROWS] = {2, 3, 4, 5}; // Подключить к выводам строк byte colPins[COLS] = {6, 7, 8}; // Подключить к выводам столбцов Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup() { Serial.begin(9600); keypad.addEventListener(keypadEvent); pinMode(ledRed, OUTPUT); pinMode(ledGreen, OUTPUT); pinMode(p, OUTPUT); pinMode(relay, OUTPUT); digitalWrite(ledRed, HIGH); digitalWrite(ledGreen, LOW); digitalWrite(relay, HIGH); lcd.begin(16, 2); lcd.createChar(0, unlocked); lcd.createChar(1, locked); lcd.setCursor(1, 0); lcd.print(" :Welcome:"); lcd.setCursor(0, 1); lcd.print("PLEASE ENTER PIN"); startupsound(); } // Настраиваем таймер void timer() { for (int timer = runFor; timer > 0; --timer) { if (timer >= 10) { lcd.setCursor(14, 0); } else { lcd.setCursor(14, 0); lcd.print("0"); lcd.setCursor(15, 0); } lcd.print(timer); blink(); delay(1000); } } // Мигаем светодиодом void blink() { digitalWrite(ledRed, HIGH); delay(50); digitalWrite(ledRed, LOW); } //Индикация нажатия кнопок void clickbuttonindication() { digitalWrite(ledGreen, HIGH); tone(p, 900); delay(50); noTone(p); digitalWrite(ledGreen, LOW); } void startupsound() { tone(p, 1000); delay(500); noTone(p); } // Звук открытия void unlockedsound() { tone(p, 500); delay(100); noTone(p); tone(p, 600); delay(100); noTone(p); tone(p, 800); delay(100); noTone(p); } // Звук закрытия void lockedsound() { tone(p, 800); delay(100); noTone(p); tone(p, 600); delay(100); noTone(p); tone(p, 500); delay(100); noTone(p); } // Индикация неверного пароля void wrongpinindication() { digitalWrite(ledRed, LOW); tone(p, 200); delay(100); noTone(p); digitalWrite(ledRed, HIGH); tone(p, 200); delay(100); noTone(p); digitalWrite(ledRed, LOW); tone(p, 200); delay(150); noTone(p); } void loop() { keypad.getKey(); } void keypadEvent(KeypadEvent eKey) { switch (keypad.getState()) { case PRESSED: clickbuttonindication(); int i; for ( i = 1; i <= 1; i++ ) Serial.print("Pressed: "); Serial.println(eKey); switch (eKey) { /* case '#': break; case '*': break; */ default: ilosc = ilosc + 1; password.append(eKey); } if (ilosc == 1) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("*_"); } if (ilosc == 2) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("**_"); } if (ilosc == 3) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("***_"); } if (ilosc == 4) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("****_"); } if (ilosc == 5) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("*****_"); } if (ilosc == 6) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("******_"); } if (ilosc == 7) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("*******_"); } if (ilosc == 8) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("********"); } if (ilosc == 9) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("*********"); } if (ilosc == 10) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(" < PIN >"); lcd.setCursor(0, 1); lcd.print("**********"); } if (ilosc == dlugosc) { delay(250); checkPassword(); ilosc = 0; } } } // Проверка пароля void checkPassword() { if (password.evaluate()) { int i; for ( i = 1; i <= 2; i++ ) ilosc = 0; // Верный пароль: Открываем дверь, считаем 10 секунд, закрываем дверь, сбрасываем пароль, возвращаемся на экран приветствия. delay(300); digitalWrite(ledRed, LOW); digitalWrite(ledGreen, HIGH); digitalWrite(relay, LOW); lcd.clear(); lcd.setCursor(0, 1); lcd.print(" << UNLOCKED >>"); lcd.setCursor(7, 0); lcd.write((uint8_t)0); unlockedsound(); delay(1000); timer(); digitalWrite(ledRed, HIGH); digitalWrite(ledGreen, LOW); digitalWrite(relay, HIGH); lcd.clear(); lcd.setCursor(0, 1); lcd.print(" << LOCKED >>"); lcd.setCursor(7, 0); lcd.write((uint8_t)1); lockedsound(); delay(1000); lcd.clear(); lcd.setCursor(1, 0); lcd.print(" :Welcome:"); lcd.setCursor(0, 1); lcd.print("PLEASE ENTER PIN"); password.reset(); } else { int i; for ( i = 1; i <= 1; i++ ) ilosc = 0; // Неверный пароль: Сбрасываем пароль, пищим, считаем 10 секунд, возвращаемся на экран приветствия password.reset(); delay(300); lcd.clear(); lcd.setCursor(2, 0); lcd.print(" WRONG PIN"); lcd.setCursor(0, 1); lcd.print("<ACCESS DENIED!>"); wrongpinindication(); delay(1000); timer(); digitalWrite(ledRed, HIGH); lcd.clear(); lcd.setCursor(2, 0); lcd.print(" TRY AGAIN"); tone(p, 150); delay(500); noTone(p); delay(500); lcd.clear(); lcd.setCursor(1, 0); lcd.print(" :Welcome:"); lcd.setCursor(0, 1); lcd.print("PLEASE ENTER PIN"); } }
зачем вам в коде столько делеев?
с таким познаниями программирования - не мудрено, что не знаете. От кода жуть берет. Почитайте какую-нибудь книжку о циклах, что ли. Что у вас происходит в строке 170, как вы думаете? Зачем вам сотня строк от 170-х до 270х?
По-другому пока не умею)
учитесь. Чтобы правильно вставить задержку 10 сек - нужно перписать код без делеев
Можешь примерно объяснить что именно выкинуть из кода и как переделать?
каждый delay() останавливает выполнение программы и контролер выполняет каждый такт одну инструкцию nop - ничего. просто подсчитайте, какое время у вас контролер делает ничего, именно делает.
тебе правильно уже обьяснили - выкинь delay() из кода, но просто замениь его уже не получится, придется переписывать код с использованием.... ну можно почитать тему рядом с твоей например
1. Для начала почитайте blink without delay.
Прочувствуйте, чем оне отличается от обычного blink.
Переришите blink without delay для случая 4-5 светодиодов с разными частотами мигания.
2. Теперь потренируйтесь с реализацией в освоеной технике последовательности действий.
Выберите какую-нибудь мелодию. Достаточно 3-5 нот различной длительности.
Запрограммируйте ее при помощи освоенной техники, для чего заведите переменную состояния, которая должна соответствовать текущей ноте. Если непонятно, как, ищите в И-нете по словам "конечный автомат".
3. Проверьте, что все сделанное в п.2. использует массивы и циклы. Если нет - переделайте. Сделайте мелодию на 20-30 нот.
Думаю, после этого Вы способны будете нужным образом переделать Ваш скетч.