замОк на RFID Reader RDM6300 + Arduino NANO
- Войдите на сайт для отправки комментариев
Доброго всем здоровья !
Заморочился на тему установки домой электромеханического замка, который будет открываться ключём от подъезда. Собрал девайс, написал код. Идея была такая: По нажатию кнопки можно записать ID ключа в EEPROM ардуины. "Длина" ключа 14-байт. Пакет данных всегда начинается с "2" и заканчивается "3" это первый и последний байт ключа. Ну а после того, как ключи записаны , собственно можно по ним открывать замок. Ну и классика жанра: В принципе всё работает, но работает не совсем так, как нужно. Одна из основных проблем в том, что когда ключ считывается, он считывается в буфер, размер которого как я понял - 64 байта. Считывается он туда многократно, всё зависит от времени нахождения ключа в зоне катушки. Так вот отсюда начинаются проблемы: реле срабатывает ровно столько раз, сколько раз ключ был считан в буфер Хотя должно сработать один раз и всё. Как бы очистить этот буфер после получения одного пакета с данными ?
#include <SoftwareSerial.h> #include <EEPROM.h> //#include <Bounce2.h> //#define BUTTON_PIN 5 #define LED_PIN 13 SoftwareSerial RfidReader(2, 3); int num = 0; int count = 0; int prekey[14]; int key[12]; int testrom[122]; int index = 0; int i, a, b, h; int keys =0; bool keyOk = false; bool CheckOk = false; bool wrmem = false; int switchPin = 5; int Relay = 6; boolean lastButton = HIGH; boolean currentButton = HIGH; void setup(){ Serial.begin(9600); RfidReader.begin(9600); // Setup the button with an internal pull-up : pinMode(switchPin,INPUT_PULLUP); pinMode(LED_PIN,OUTPUT); pinMode(Relay, OUTPUT); } boolean debounce(boolean last) { boolean current = digitalRead(switchPin); if (last != current) { delay(5); current = digitalRead(switchPin); } return current; } void ReadID() { count = 0; for (count =0; count <=13; count++) { if (RfidReader.available() > 0) //Если присутствуют данные со считывателя карт { Serial.print("ReadID Function"); num = RfidReader.read(); // Присваеваем переменной num первый считанный байт prekey[count] = num ; // Заполняем массив от 0 до 13 значениями полученных байт в num Serial.print("count="); Serial.println(count); Serial.print("num="); Serial.println(num, DEC); if(count >= 13) //Если считали 14 байт, .... { if (prekey[0] == 2 && prekey[13] == 3) // Если первый элемент массива равен 2 а последний 3 { keyOk = true; Serial.print ("keyOk="); Serial.print (keyOk); Serial.println (' '); Serial.print ("key="); for (a=0; a<=11; a++) { b = a+1; key[a] = prekey[b]; Serial.print (key[a]); } return; } else { Serial.print ("Key is not very" ); keyOk = false; count = 0; num =0; } delay (1000); Serial.println (' '); Serial.print("prekey="); for(i=0; i<=13; i++) { int x= prekey[i]; Serial.print(x); } Serial.println(' '); count = 0; delay (1000); } } else { count = 0; num = 0; keyOk = false; break; } } } void CheckMem () // функция проверки наличия ключа в памяти { Serial.println("CheckMem function"); keys = testrom[0]; // num - ячейка количества записанных ключей int n = keys*12+2; // n - номер первой чистой ячейки int k; int g; int j; int CheckCount =0; for (k=0; k<=(n-1); k=k+12) // цикл пересчитывает блоки ключей, каждый блок 12 байт { Serial.print("k="); Serial.println(k); for (j=0; j<=11; j++) // цикл пересчитывает, сравнивает каждый байт массива ключа и массива памяти { g = (j+k+2); // переменная указывает на нужный байт в памяти соответствующий или не соответствующий байту ключа Serial.print("key_j="); Serial.println(key[j]); Serial.print("testrom_g="); Serial.println(testrom[g]); if (key[j] == testrom[g]) // сравнение ключа с сохранённым в памяти побайтово { CheckCount ++; // прибавляет единицу если байты соответствуют друг другу Serial.print("CheckCount="); Serial.println(CheckCount); } else { CheckCount =0; // если нет совпадения в байтах, сбросить счётчик в 0 } } if (CheckCount == 12) //Если все 12 байт подряд равны, { CheckOk = true; //Меняем значение переменной в true Serial.println(' '); Serial.print("Key found in memory"); break; //Прекращаем цикл, так как такой ключ есть в памяти устройства } else { Serial.println(' '); Serial.println("key not found"); CheckOk = false; // Стафим флаг , о том что такого ключа не найдено } } } void WriteMem () // Функция сохранения в энергонезависимой памяти устройства { Serial.println("WriteMem Function"); keys = testrom[0]; // В нулевой ячейке памяти сохраняется количество записанных ключей . Присваеваем переменной keys это значение int n = (keys*12+2); // Переменная n соответствует значению первой свободной ячейки памяти для записи нового ключа Serial.print("n="); Serial.println(n); for (int j=0; j<=11; j++) // Цикл записи байт данных в память { Serial.print("j="); Serial.println(j); int g = (n+j); Serial.print("g="); Serial.println(g); testrom[g] = key[j]; } for( int m=2; m<=13; m++) { Serial.print("Testrom="); Serial.println(testrom[m]); Serial.println(' '); } testrom[0]= testrom[0] + 1; // Увеличиваем ячейку памяти 0 на единицу wrmem = true; } void loop() { currentButton = debounce(lastButton); if (lastButton == HIGH && currentButton == LOW) { digitalWrite(LED_PIN, HIGH ); delay(100); while(wrmem == 0 || CheckOk ==0) { ReadID(); if ( keyOk == 1) { CheckMem(); if ( CheckOk == 0) { WriteMem(); } else { Serial.println("I have this key"); break; } } else {} } digitalWrite(LED_PIN, LOW ); } lastButton = currentButton; ReadID(); if ( keyOk == 1) { Serial.println (' '); Serial.print("CardNumberIS:"); for (a=0; a<=11; a++) { Serial.print (key[a]); } Serial.println (' '); CheckMem(); if ( CheckOk == 1) { Serial.println(' '); Serial.print("Open Door"); digitalWrite(Relay, HIGH ); delay(2500); digitalWrite(Relay, LOW ); } else { } } int prekey[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int key[] = {0,0,0,0,0,0,0,0,0,0,0,0}; num = 0; count = 0; index = 0; i, a, b, h =0; keyOk = false; CheckOk = false; wrmem = false; }
Может у кого есть идеи по оптимизации ?
https://www.youtube.com/watch?v=KCt7vpDJEVw
Конечно есть. Поставьте временные ограничения на открытие замка. Какое время ставить - вам решать. Оно может быть 10, 20 секунд, может быть несколько минут.
Почитайте про программный антидребезг кнопок - реализация будет той же, только временные рамки иные.
Конечно есть. Поставьте временные ограничения на открытие замка.
Т.е. ввести переменную, которая будет отсчитывать например 10 секунд с момента открытия, чтобы на это время запретить повторное открытие ?
Почитайте про программный антидребезг кнопок - реализация будет той же, только временные рамки иные.
А функция debounce не является программным антидребезгом ?
Все верно поняли. debounce и есть программный антидребезг, ведь ее еще написать надо. Вот только через delay было неверным решением ее писать. Так она блокирует выполнение программы (хоть и 5мс, но тоже время, а если поставить 10с, то программа "зависнет").
Дебажил, дебажил - совсем всё сломал ))) Буду заново переписывать код )
Последний работает совсем непойми как, работает так, как ему хочется )
Да и в функциях нашел ошибки и лишние движения.
Всё исправил, вот рабочий код. Ключи пишутся в EEPROM. Ложные - повторные срабатывания устранены. Антидребезг оставил таким какой он был.
Комменты в коде писал для себя, так что не везде они есть. )
А схемку можно замка.
был бы очень признателен
А схемку можно замка.
был бы очень признателен
да какая там схема, ридер на 2 и 3 пине, кнопка на 5, реле на 6 вот и вся схема
Спасибо.
Еше один вопрос
А как запись меток происходит
нажатием кнопки
Я даже не успеваю отвечать )))) все верно , запись происходит нажатием кнопки. Можно прикрутить механизм, чтобы был мастер ключ, прислоняете ма стен, потом новый ключ записываете
в большом коллективе клювом не щёлкают )))
привет, подскажи пожалуйста, как именно происходит запись
Здравствуйте, подскажи пожалуйста, на 131 строчки при компиляции выдаёт ошибку как исправить.и как писать ключи.пишет bad key/
и еще вопрос?вы можете поправить чтобы при считывание пин 6 сработал.а при повторном считывание пин 7.и по новой пин 6 пин 7.
Доброго дня! К сожалению ардуину в руки не брал года 3-4, подзабыл что и как там, думаю проще тебе изучить код и самому все поправить.
последний скетч не пишет ключи!!!!
кнопку нажимаешь ? добавь вывод в терминал, посмотри, что происходит
на 131 строчки при компиляции выдаёт ошибку как исправить.и как писать ключи.пишет bad key/
на 131 строчки при компиляции выдаёт ошибку
Мошт потому, что в строке "003" дефайн закоментирован?
Что делать? Не хочет писать ключ. bad key
почему закоментирована строка int EEPROM[64]; ?
Я понимаю это команда записи в епром?