Радиочастотная идентификация (Radio Frequency Identification, RFID) – это простая и дешевая технология, позволяющая считывать с помощью специального устройства значение радиочастотных меток. Она находит широкое применение в системах контроля доступа, системах безопасности, для маркировки товаров в супермаркетах и т.д. На нашем сайте вы можете посмотреть все проекты, в которых использовалась радиочастотная идентификация, по этой ссылке.
В данной статье мы рассмотрим создание системы учета посетителей на основе радиочастотной идентификации и платы NodeMCU ESP8266, с помощью которой можно будет не только мониторить лог событий захода посетителей, но также передавать этот лог событий на удаленный сервер.
Необходимые компоненты
- NodeMCU ESP8266 (купить на AliExpress).
- Модуль чтения RFID меток EM-18 и карты (метки) к нему (купить на AliExpress).
- ЖК дисплей 16x2 и модуль I2C для него (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Модуль считывания RFID меток EM-18
Внешний вид модуля считывания RFID меток EM-18 показан на следующем рисунке.
Принцип технологии RFID (радиочастотной идентификации) достаточно прост. В данной технологии цифровые данные закодированы в виде RFID меток, которые могут быть декодированы (расшифрованы) с помощью считывателя RFID меток с использованием радиоволн. В этом плане технология радиочастотной идентификации во многом похожа на технологию привычных нам штрих-кодов, считывание которых осуществляется специальными устройствами.
Модуль чтения RFID меток EM-18 позволяет считывать информацию об идентификаторах (ID information), размещенных в RFID метках. Идентификатор RFID метки содержит уникальный 12-значный номер, который может быть считан модулем EM18 когда радиочастотная метка попадает в поле его действия (8-12 см). Модуль работает на частоте 125 кГц, содержит встроенную антенну и запитывается от напряжения 5 В постоянного тока. Считанные данные модуль передает другим устройствам с помощью последовательной связи со скоростью 9600 бод (8 бит данных и 1 стоповый бит).
Модуль EM-18 широко применяется во встраиваемой электронике и имеет ряд интересных особенностей. К примеру, его можно запитывать напряжением в диапазоне от +4.5V до 5.5V DC. Модуль во время своей работы потребляет всего 50mA тока, поэтому его можно использовать в устройствах, получающих питание от батарей и аккумуляторов. Используемая им частота 125 кГц позволяет ему работать со множеством типов RFID карт. Встроенная в него антенна позволяет ему производить считывание RFID меток на расстояниях от 8 до 12 см. Модуль работоспособен в диапазоне температур 0-80 °C, что позволяет его использовать в "жестких" условиях окружающей среды.
Назначение контактов (распиновка) модуля EM-18 показано на следующем рисунке.
Ранее модуль EM-18 использовался на нашем сайте в следующих проектах:
- система контроля доступа на Raspberry Pi и радиочастотной идентификации;
- электронный замок на основе радиочастотных меток (RFID) и Arduino (в ней вы также можете прочитать о формате данных, передаваемых модулем EM-18);
- чтение радиочастотных меток с помощью Arduino Uno;
- система радиочастотной идентификации на микроконтроллере AVR ATmega32.
Схема проекта
Схема системы учета посетителей на основе NodeMCU ESP8266 и радиочастотной идентификации показана на следующем рисунке.
Модуль EM-18 мы подключили к плате NodeMCU ESP8266 через последовательный порт связи. Поскольку модуль EM-18 имеет низкий потребляемый ток (50mA), то его можно запитать от NodeMCU. ЖК дисплей 16х2 мы подключили к плате NodeMCU ESP8266 с помощью интерфейса I2C. ЖК дисплей также запитывается от NodeMCU.
Настройка ThingSpeak
Данные нашего проекта мы будем передавать на сервис ThingSpeak, который является одной из лучших платформ для проектов, связанных с технологией интернета вещей (IoT). На нашем сайте мы уже рассматривали достаточно много проектов, использующих для хранения данных серверы ThingSpeak.
Для настройки аккаунта на сервисе ThingSpeak выполните следующую последовательность шагов.
Зайдите на сайт https://thingspeak.com/ и создайте там себе новый бесплатный аккаунт (Mathworks account). Войдите в свой созданный аккаунт.
Создайте себе новый канал в сервисе ThingSpeak, нажав на “New Channel”. Заполните настройки своего проекта: имя, имена полей и т.д. В нашем случае мы создали поля для хранения данных температуры и напряжения. После этого нажмите на “Save channel” (сохранить канал).
Выберите созданный канал и запишите с него (сохраните в блокнот) данные, которые в дальнейшем нам понадобятся при написании программы:
- идентификатор канала (Channel ID), находится в самом верху на странице канала;
- API ключ (API key), находится на вкладке "API Keys" страницы канала.
Более подробно про работу с сервисом ThingSpeak вы можете прочитать в этой статье.
Объяснение программы для NodeMCU ESP8266
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Добавление поддержки NodeMCU в Arduino IDE
Откройте Arduino IDE и в ней выберите пункт меню File–>Preferences–>Settings.
В открывшемся окне в поле ‘Additional Board Manager URL’ добавьте строку https://arduino.esp8266.com/stable/package_esp8266com_index.json и нажмите ‘Ok’.
Далее откройте пункт Tools > Board > Boards Manager. В менеджере плат (Boards Manager) в строке поиска введите ESP8266, затем в результатах поиска выберите последнюю версию и нажмите install (установить).
Когда установка будет закончена, в пункте меню Tools ->Board -> выберите NodeMCU 1.0 (ESP-12E Module). После этого вы сможете программировать вашу плату NodeMCU с помощью Arduino IDE.
Получение уникального RFID кода с RFID метки
Перед тем как программировать NodeMCU ESP8266, нам необходимо узнать уникальный 12-значный код нашей RFID метки. Когда мы подносим метку к считывателю RFID меток EM-18 он считывает с нее код и передает его NodeMCU через последовательный порт связи. Поэтому с помощью небольшой программы мы можем считать коды со всех необходимых нам RFID меток и сохранить их для последующего использования в основной программе.
После того как вы загрузите в NodeMCU ESP8266 код небольшой программы, приведенной ниже, откройте окно монитора последовательной связи (serial monitor) и установите в нем скорость 9600. Затем проведите RFID меткой рядом с модулем EM-18 и вы увидите как 12-значный код, считанный с метки, отобразится в окне монитора последовательной связи. Повторите эту операцию для всех RFID меток, которые будут использоваться в вашем проекте.
Код программы для считывания 12-значного кода с RFID меток
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
int count = 0; char card_no[12]; void setup() { Serial.begin(9600); } void loop() { if(Serial.available()) { count = 0; while(Serial.available() && count < 12) { card_no[count] = Serial.read(); count++; delay(5); } Serial.print(card_no); } } |
Объяснение кода основной программы
Первым делом в программе нам необходимо подключить используемые библиотеки. Для взаимодействия с платформой ThingSpeak мы будем использовать библиотеку ThingSpeak.h. Для взаимодействия с ЖК дисплеем по интерфейсу I2C мы будем использовать библиотеки “LiquidCrystal_I2C.h” и “wire. h”. Также мы будем использовать библиотеку time.h для получения временных меток.
1 2 3 4 5 |
#include "ThingSpeak.h" #include <ESP8266WiFi.h> #include<LiquidCrystal_I2C.h> #include<Wire.h> #include <time.h> |
Далее создадим объект для работы с ЖК дисплеем.
1 |
LiquidCrystal_I2C lcd(0x3f, 16, 2); |
Затем укажем параметры для подключения к Wi-Fi сети – идентификатор сети (SSID) и пароль. После этого укажем параметры для взаимодействия с сервисом ThingSpeak – номер канала (channel number) и API ключ, которые мы записали ранее. Убедитесь в том, что в программе вы исправили эти параметры в соответствии с данными из своего аккаунта ThingSpeak.
1 2 3 4 |
unsigned long ch_no = 123456 const char * write_api = "MCxxxxxxx"; char ssid[] = "admin"; char pass[] = "12345678"; |
Внутри функции setup() инициализируем последовательную связь со скоростью 9600 бод. Затем получим временную метку и инициализируем ЖК дисплей.
1 2 3 4 5 |
Serial.begin(9600); configTime(11 * 1800, 0, "pool.ntp.org", "time.nist.gov"); Wire.begin(D2, D1); lcd.begin(16, 2); lcd.init(); |
Для подключения nodeMCU к сети Интернет мы будем использовать функцию WiFi.begin(), параметрами в которой являются идентификатор сети и пароль для доступа к ней. После этого мы будем проверять успешно ли мы подключились к сети Wi-Fi или нет с помощью функции WiFi.status(), при успешном соединении мы будем выводить на экран ЖК дисплея сообщение “WiFi connected”.
1 2 3 4 5 6 7 8 9 10 |
WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi connected"); Serial.println(WiFi.localIP()); lcd.setCursor(0, 1); lcd.print("WiFi connected"); |
Внутри бесконечного цикла while(1) мы будем подсчитывать общее количество посетителей (visitors) и отображать их на экране ЖК дисплея с помощью функции lcd.print.
1 2 |
lcd.setCursor(0, 0); lcd.print("No. of Vis:" + String(vis_count)); |
Для получения текущей временной метки (timestamp) мы будем использовать функцию time(). Считанная временная метка будет сохраняться в символьном массиве.
1 2 |
time_t now = time(nullptr); str = ctime(&now); |
Уникальные 12-значные коды, считываемые нами с RFID меток, будут декодироваться и сохраняться в массиве. Далее эти элементы массива будут сравниваться с сохранёнными ранее метками чтобы распознать по ним конкретных посетителей.
1 2 3 4 5 6 7 8 9 |
if (Serial.available()) { count = 0; while (Serial.available() && count < 12) { input[count] = Serial.read(); count++; delay(5); } |
Затем мы сравниваем принятый массив с сохраненными кодами меток. Если коды совпадают (то есть посетитель опознан), мы показываем информацию о посетителе на экране ЖК дисплея.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
if (count == 12) { if ((strncmp(input, "0B00284F9AF6", 12) == 0) && (a == 0)) { lcd.setCursor(0, 1); lcd.print("Welcome Debasis "); vis_count++; a = 1; delay(2000); lcd.clear(); senddata("Debasis"); } } |
Запрограммируем функцию Senddata() для передачи данных посетителя в облако ThingSpeak. Затем с облака ThingSpeak мы можем скачать эти данные в формате excel чтобы просмотреть записанные детали: имя посетителя, время входа и т.д.
1 2 3 4 5 6 |
void senddata(String input) { ThingSpeak.setField(1,input); ThingSpeak.setField(2, str); ThingSpeak.writeFields(ch_no, write_api); } |
Тестирование работы проекта
Перед тестированием работы проекта убедитесь в том, что WiFi сеть, к которой вы будете подключать NodeMCU, доступна. Если подсоединение к сети WiFi прошло успешно, на экране ЖК дисплея высветится надпись “WiFi connected”.
Затем проведите картой с RFID меткой рядом с модулем EM-18. Данные посетителя должны отобразиться на экране ЖК дисплея как показано на следующем рисунке.
Далее, чтобы скачать эти данные с облака ThingSpeak, зайдите в ThingSpeak в свой аккаунт и нажмите в нем на вкладке “Data Import/Export”. Под меню экспорта (Export menu) выберите правильную временную зону (Time Zone) и нажмите на Download. После этого вы скачаете лист Excel в формате .csv, который будет выглядеть примерно следующим образом:
Более подробно работу проекта вы можете посмотреть на видео, представленном в конце статьи.
Исходный код программы (скетча)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
#include "ThingSpeak.h" #include <ESP8266WiFi.h> #include<LiquidCrystal_I2C.h> #include<Wire.h> #include <time.h> LiquidCrystal_I2C lcd(0x3f, 16, 2); unsigned long ch_no = 124555;//Replace with ThingSpeak Channel number (замените на свой номер канала) const char * write_api = "cvxxx";//Replace with ThingSpeak write API (замените на свой API ключ) char ssid[] = "admin"; char pass[] = "12345678"; int count = 0; int vis_count = 0; char input[12]; int a = 0, b = 0, c = 0, d = 0, e = 0; WiFiClient client; const char *str; void setup() { Serial.begin(9600); configTime(11 * 1800, 0, "pool.ntp.org", "time.nist.gov"); Wire.begin(D2, D1); lcd.begin(16, 2); lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print(" WELCOME TO "); lcd.setCursor(0, 1); lcd.print(" CIRCUIT DIGEST "); delay(2000); lcd.clear(); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi connected"); Serial.println(WiFi.localIP()); lcd.setCursor(0, 1); lcd.print("WiFi connected "); delay(2000); lcd.clear(); ThingSpeak.begin(client); } void loop() { lcd.setCursor(0, 0); lcd.print("No. of Vis:" + String(vis_count)); time_t now = time(nullptr); str = ctime(&now); if (Serial.available()) { count = 0; while (Serial.available() && count < 12) { input[count] = Serial.read(); count++; delay(5); } if (count == 12) { if ((strncmp(input, "0B00284F9AF6", 12) == 0) && (a == 0)) { lcd.setCursor(0, 1); lcd.print("Welcome Debasis "); vis_count++; a = 1; delay(2000); lcd.clear(); senddata("Debasis"); } else if ((strncmp(input, "0B002854EB9C", 12) == 0) && (b == 0)) { lcd.setCursor(0, 1); lcd.print("Welcome Manas "); b = 1; vis_count++; delay(2000); lcd.clear(); senddata("Manas"); } else if ((strncmp(input, "0B0029516C1F", 12) == 0) && (c == 0)) { lcd.setCursor(0, 1); lcd.print("Welcome Aswinth "); c = 1; vis_count++; delay(2000); lcd.clear(); senddata("Aswinth"); } else if ((strncmp(input, "0B00292F5E53", 12) == 0) && (d == 0)) { lcd.setCursor(0, 1); lcd.print("Welcome Sourav "); d = 1; vis_count++; delay(2000); lcd.clear(); senddata("Sourav"); } else if ((strncmp(input, "0B00283E6479", 12) == 0) && (e == 0)) { lcd.setCursor(0, 1); lcd.print("Welcome Rakesh "); e = 1; vis_count++; delay(2000); lcd.clear(); senddata("Rakesh"); } else { lcd.setCursor(0, 1); lcd.print("Welcome Back!!! "); delay(2000); lcd.clear(); } } } } void senddata(String input) { ThingSpeak.setField(1,input); ThingSpeak.setField(2, str); ThingSpeak.writeFields(ch_no, write_api); } |