Проблема с кодовым замком
- Войдите на сайт для отправки комментариев
Вс, 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 нот.
Думаю, после этого Вы способны будете нужным образом переделать Ваш скетч.