Комментарии 0
...комментариев пока нет
Домофон, который знает, как вас зовут — своими руками
#include <avr/wdt.h> #include <MFRC522.h> #include <DFPlayer_Mini_Mp3.h> #define BUSY_PIN 4 // Пин BUSY для MP3 пдеера #define RST_PIN 9 // Пин RST для rfid модуля #define SS_PIN 10 // Пин SS для rfid модуля #define RX 2 // назначить пин RX SoftSerial #define TX 3 // назначить пин TX SoftSerial #define modeRes 11 // пин для сброса памяти ключей #define look_PIN 5 // номер пина для подключения к нему реле открытия замка #define blue_PIN 8 #define green_PIN 7 #define red_PIN 6 #define interval 2000 // интервал сброса RFID модуля в мкс #define time_reset_mp3 600000 // интервал сброса MP3 плеера #define volume 25 // громкость MP3 от 0 до 30 #define equalizer 0 // эквалайзер(POP=1) от 0 до 5 Normal/Pop/Rock/Jazz/Classic/Bass #define sumName 7 // количество имен пользователей записанных на флешке начинаются с 0001.mp3, 0002.mp3 ... и т.д. uint32_t rebootTimer=0, oldTime=0; // Переменная для таймера MFRC522 rfid(SS_PIN, RST_PIN); // Назначить пины SS и RST SoftwareSerial mySerial(RX, TX); // назначить пины RX, TX SoftSerial void setup() { // pinMode(look_PIN, OUTPUT); // пин для подключения реле открытия замка // digitalWrite(look_PIN, LOW); pinMode(red_PIN, OUTPUT); pinMode(green_PIN, OUTPUT); pinMode(blue_PIN, OUTPUT); pinMode(modeRes, INPUT_PULLUP); // пин сброса памяти ключей mySerial.begin (9600); // Инициализация Soft Serial mp3_set_serial (mySerial); delay (1000); mp3Reset(); // инициализация плеера uint8_t memClear = digitalRead(modeRes); // проверяем состояние пина сброса памяти if(!memClear) // Если установлена перемычка на GND и пин D11 { digitalWrite (green_PIN, HIGH); digitalWrite (red_PIN, HIGH); eeprom_write_byte(0, 255); // то обнуляем счетчик ключей mp3play (113, 13000); // память обнулена while(true); // зависаем и ждем нажатия reset } SPI.begin(); // Инициализация SPI firstStart(); // проверка наличия Мастер ключа и добавление его mp3play (109, 9500); // система активирована //Serial.begin(115200); // Инициализация Serial //wdt_enable(WDTO_8S); } void loop() { digitalWrite (green_PIN, HIGH); digitalWrite (red_PIN, HIGH); digitalWrite (blue_PIN, HIGH); uint8_t sumKey = eeprom_read_byte(0); // считываем из EEPROM с адреса 0 информацию о количестве сохраненных ключей uint32_t master = ReadEEPROM_Long(1); // читаем из EEPROM uid мастер ключа uint32_t uid_tmp = ReadUID(); // ждем когда приложат ключ к считывателю и Читаем UID ключа //Serial.println(sumKey); //Serial.println(master); //Serial.println(uid_tmp); if(uid_tmp == master) { digitalWrite (red_PIN, LOW); digitalWrite (blue_PIN, LOW); addKey(sumKey); // если к считывателю поднесли мастер ключ, то переходим в режим добавления новых ключей } if(sumKey>=0 && uid_tmp != master) // если в EEPROM больше 1 ключа и UID прочитан с RFID то сравниваем все имеющиеся в EEPROM ключи со считанным 1 { uint8_t nameKey = searchKey(sumKey, uid_tmp); // считываем все ключи по очереди из EEPROM и сравниваем их с UID приложенного к считывателю ключа if(nameKey > 0) // в nameKey номер(индекс) ключа { sumKey = eeprom_read_byte(nameKey*5); // читаем из EEPROM привязанное к uid имя пользователя //digitalWrite (look_PIN, HIGH); // открываем замок digitalWrite (green_PIN, LOW); mp3play (106, 1480); // фраза "Здравствуйте" mp3play (sumKey, 1200); // проигрываем привязанное имя пользователя к uid mp3play (107, 5000); // фраза "Добро пожаловать" //digitalWrite (look_PIN, LOW); // закрываем замок } else { digitalWrite (red_PIN, LOW); mp3play(104, 6500); } // фраза "Доступ запрещен, Ключ не найден" } if (millis() - oldTime > time_reset_mp3) // интервал таймера для сброс плеера { oldTime = millis(); } } //********************************************* uint32_t ReadUID(void) // опрашиваем считыватель каждую 0,2сек { for (;;) // бесконечный цикл { ResetRFID(); // перезагружаем RFID модуль каждые 2 секунды delay(100); if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) // Если метка найдена и она прочитана { return uidTolong(); // прервать цикл и возвратить UID } } } //----------------------------------------- uint8_t searchKey( uint8_t sumKey, uint32_t uid ) // поиск ключа в EEPROM. sumKey-количество сохраненных ключей вEEPROM { for (uint8_t i = 1; i <= sumKey; i++) { uint32_t tmp=ReadEEPROM_Long(i*5+1); //читаем по очереди все сохраненные UID и сравниваем их с UID полученным c RFID if(tmp == uid) { return i; } // сравниваем считанный из памяти UID с прочитанным UID и если найден, то возвращаем номер совпавшего ключа } return 0; // если в базе нет такого ключа то возвращаем 0 } //--------------------------------------- void addKey(uint8_t sumKey) // sumKey-количество сохраненных ключей в EEPROM { mp3play(101, 15000); // для добавления нового UID после того как услышите имя которое нужно привязать к UID поднесите ключ к считывателю RFID for (uint8_t i = 1; i <= sumName; i++) // перебираем все имена по очереди { mp3play(110, 1000); // проигрывание звука next ResetRFID(); pinMode(TX, OUTPUT); // восстанавливаем выход для TX mp3_play (i); // проигрываем в фоновом режиме в порядке возрастания все записанные на флешку имена mp3_set_volume (volume); // устанавливаем заданную громкость for (uint8_t ti = 0; ti < 20; ti++) // цикл таймер, 20*100мс=2 сек на опрос считывателя RFID пока проигрывается имя пользователя { if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) // Если определена метка и она прочитана { uint32_t uid = uidTolong(); // преобразуем uid из массива в ulong uint8_t dub = searchKey(sumKey, uid); // ищем в EEPROM совпадение, проверяем ключ на дубли if(dub == 0) // если такого ключа нет в памяти то добавляем его { // или если ключ есть то в dub номер ключа sumKey++; // инкрементируем счетчик ключей eeprom_write_byte(0, sumKey); // счетчик ключей в EEPROM eeprom_write_byte(sumKey*5, i); // сохраняем в EEPROM привязанное к ключу имя WriteEEPROM_Long (sumKey*5+1, uid); // сохраняем UID ключа в EEPROM delay(500); // для того,что бы имя проигралось до конца mp3play(103, 4500); // фраза "новый ключ сохранен" mp3play(112, 9000); // фраза "мастер режим завершен" return; } else { digitalWrite (blue_PIN, HIGH); delay(1000); mp3play(111, 9000); // прочитанный ключ уже имеется в системе digitalWrite (red_PIN, HIGH); mp3play(112, 9000); // фраза "мастер режим завершен" return; } } delay(100); } } mp3play(108, 9000); // Время ожидание ключа истекло. } //---------------------------------------- void firstStart(void) { uint8_t tmp = eeprom_read_byte(0); // проверяем записан ли мастер ключ в EEPROM if(tmp==255) // если его там нет, то нужно добавить { mp3play(100, 12500); // фраза добавить мастер ключ uint32_t uid_tmp = ReadUID(); // прочитать UID мастер ключа со считывателя RFID if( uid_tmp > 0 ) // если ключ прочитан то записываем его в EEPROM { eeprom_write_byte (0, 0); // по адресу 000 записываем счетчик ключей не более 51 шт.------------------ WriteEEPROM_Long (1, uid_tmp); // по адресу 001 может быть записан только мастер ключ mp3play(102, 3500); // фраза мастер ключ добавлен } } } //---------------------------------------- void ResetRFID(void) // Таймер сброса RFID защита от зависания { if (millis() - rebootTimer > interval) // интервал таймера { rebootTimer = millis(); // Обновляем таймер digitalWrite(RST_PIN, HIGH); // Сбрасываем модуль delayMicroseconds(100); // длительность сброса 100 мкс digitalWrite(RST_PIN, LOW); // Отпускаем сброс rfid.PCD_Init(); // Инициализируем RFID rfid.PCD_AntennaOn(); // Включаем антенну } } //--------------------------------------- void mp3Reset(void) // можно так же использовать как остановку трека { mp3_reset (); delay (1000); // mp3_set_device(2); // 2-работа с SD Card. 1/2/3/4/5 U/SD/AUX/SLEEP/FLASH // mp3_DAC (true); mp3_set_EQ (equalizer); // эквалайзер Normal/Pop/Rock/Jazz/Classic/Bass delay (100); mp3_set_volume (volume); // устанавливаем громкость delay (200); pinMode(TX, INPUT_PULLUP); // Отключаем TX, что бы в динамике исчез шум/наводка } void mp3play(uint16_t track, uint16_t time) { pinMode(TX, OUTPUT); // восстанавливаем выход TX mp3_play(track); // проиграть трек // mp3_set_volume (volume); // устанавливаем заданную громкость //wdt_reset(); delay(time); // длительность проигрывания // mp3_set_volume (0); // выключаем звук, что бы не было шума в динамике pinMode(TX, INPUT_PULLUP); // Отключаем TX, что бы в динамике исчез шум/наводка } //--------------------------------------- uint32_t uidTolong(void) { uint32_t uid_long=0; uid_long = rfid.uid.uidByte[3]; // преобразуем uid массив в тип uint32_t uid_long = ((uid_long << 8) | rfid.uid.uidByte[2]); uid_long = ((uid_long << 8) | rfid.uid.uidByte[1]); return (uid_long = ((uid_long << 8) | rfid.uid.uidByte[0])); //прервать цикл и передать UID } void WriteEEPROM_Long(uint8_t addr, uint32_t data) //преобразовать из long и сохранить в EEPROM { eeprom_write_byte((uint8_t*)addr, data & 0xFF); eeprom_write_byte((uint8_t*)addr+1, (data & 0xFF00) >> 8); eeprom_write_byte((uint8_t*)addr+2, (data & 0xFF0000) >> 16); eeprom_write_byte((uint8_t*)addr+3, (data & 0xFF000000) >> 24); } uint32_t ReadEEPROM_Long(uint8_t addr) // считываем значение из EEPROM и преобразуем в long { uint32_t ir_code = eeprom_read_byte((uint8_t*)addr+3); ir_code = (ir_code << 8) | eeprom_read_byte((uint8_t*)addr+2); ir_code = (ir_code << 8) | eeprom_read_byte((uint8_t*)addr+1); return ((ir_code << 8) | eeprom_read_byte((uint8_t*)addr)); }