Контроль доступа при помощи iocontrol.ru
Общие сведения
В этом проекте мы сделаем пример, на основе которого можно собрать домашнюю систему контроля доступа при помощи сервиса iocontrol
Видео
Нам понадобится
- Arduino UNO/Piranha UNO
- Raspberry Pi
- Ethernet Shield W5500
- Trema Shield
- Trema-модуль Матрица 8x8
- Trema-модуль Зуммер
- Trema-модуль Реле
- Модуль RFID RDM6300 UART
- Метка-брелок RFID 125 кГц
- провода "мама-мама"
- разъём питания Jack "мама"
- блоки питания (2x5V, 1x12V)
- провода USB (для Arduino, для Raspberry)
- Замок электромагнитный
- Контактные колодки
Создание и настройка панели на iocontrol.ru
- Создаём или входим в учётную запись на сайте iocontrol
- нажимаем "Создать панель". Придумываем название панели, например "myNewPanel" (название панели должно быть уникальным на сайте. Если панель с таким именем уже есть, сайт уведомит об этом). Нажимаем Создать.
- Создаём переменную текстового типа и назовем её
key. - Создаём переменную целочисленного типа и назовем её
lock. - Настраиваем вид переменной как кнопки(Нажимаем на пиктограмму шестерёнки в правом верхнем углу карточки переменной и в открывшейся странице выбираем вид "Кнопка".
Подключение
Установим Ethernet Shield на Arduino UNO/Piranha UNO

Установим Trema Sheild на Ethernet Sheild через проставки

Подключим модули и замок

Код
Скетч Arduino
// Подключаем библиотеки
#include <iocontrol.h>
#include <SPI.h>
#include <Ethernet.h>
#include <SoftwareSerial.h>
#include <iarduino_I2C_Matrix_8x8.h>
// Определяем выводы
#define LOCK_PIN 6
#define ZUM_PIN 5
#define RX 8
#define TX 9
// Определяем длительность работы замка (миллисекунды)
#define DURATION 5000
// Орпеделяем длину RFID ключа
#define KEY_SIZE 14
// Название панели на сайте iocontrol.ru
const char* myPanelName = "НАЗВАНИЕ_ВАШЕЙ_ПАНЕЛИ";
// Ключ доступа к панели
const char* key = "КЛЮЧ_ВАШЕЙ_ПАНЕЛИ";
int status;
// Название переменных на сайте iocontrol.ru
//const char* VarName_key_hi = "key_hi"; // Раскомментировать для проверки ключа полностью
const char* VarName_key_lo = "key";
const char* VarName_lock = "lock";
// определяем программный последовательный порт RFID-модуля
SoftwareSerial RfidReader(RX, TX);
// Создаём объект клиента класса EthernetClient
EthernetClient client;
// Создаём объект iocontrol, передавая в конструктор название панели и клиента
iocontrol mypanel(myPanelName, key, client);
// MAC адреса Ethernet шилда. Должен быть уникальным в сети
byte mac[] = {
0xDE, 0xED, 0xDE, 0xAD, 0xFA, 0xCA
};
// Создаём экземпляр класса матрицы
iarduino_I2C_Matrix_8x8 disp;
// Картинка для матрицы - доступ разрешён
uint8_t granted[] {
0b00000000,
0b00000011,
0b00000011,
0b11000110,
0b11000110,
0b01101100,
0b00111100,
0b00011000
};
uint8_t denied[] {
0b00000000,
0b11000011,
0b01100110,
0b00111100,
0b00011000,
0b00111100,
0b01100110,
0b11000011
};
byte buffer[KEY_SIZE]{0};
unsigned long timer;
// назначаем переменную для счетчика
int count = 0;
void setup()
{
// инициируем последовательный порт
Serial.begin(9600);
// инициируем передачу данных с модулем RFID
RfidReader.begin(9600);
Ethernet.init(10);
// Инициируем Ethernet Shield с использованием DHCP
Ethernet.begin(mac);
// Вызываем функцию первого запроса к сервису
status = mypanel.begin();
Serial.println((String)"Status mypanel.begin = " + status);
// Инициируем I2C матрицу 8x8
disp.begin();
disp.clrScr();
}
void loop()
{
// Обновляем переменные в памяти контроллера
status = mypanel.readUpdate();
// записываем значение переменной-переключателя "lock".
bool io_lock = mypanel.readBool(VarName_lock);
// Если переменные были обновлены...
if (status == OK) {
// выводим текст в последовательный порт,
Serial.println("------- Read OK -------");
// Если переключатель включён...
if (io_lock) {
// выводим изображение на матрицу,
disp.drawImage(granted);
// открываем замок,
open();
// очищаем экран матрицы,
disp.clrScr();
// устанавливаем переключатель в положение "выключено".
mypanel.write(VarName_lock, false);
while(mypanel.writeUpdate());
}
Serial.println((String)"io_lock = "+io_lock);
}
// если в последовательном порту есть данные, то
if (RfidReader.available()) {
// считаем байты
count++;
// записываем их в массив
buffer[count % KEY_SIZE] = RfidReader.read();
// если количество байтов кратно размеру ключа
if (!(count % KEY_SIZE)) {
// Оповещаем пользователя сигналом
buzz();
// Строка для преобразования полученного ключа
char str[KEY_SIZE + 1] = "";
// Вызываем функцию преобразования байтов в строку
array_to_hex_string(buffer, KEY_SIZE, str);
String s = str;
// Если необходимо проверять ключ полностью - раскомментируйте
// следующие две строки, и создайте переменную на сайте с названием
// "key_hi" для хранения старшей подстроки
//String key_hi = s.substring(0, s.length() / 2);
//mypanel.write(VarName_key_hi, key_hi);
// Записываем младшую подстроку в переменнную
String key_lo = s.substring(s.length() / 2, s.length());
mypanel.write(VarName_key_lo, key_lo);
// Отправляем переменные из контроллера в сервис
status = mypanel.writeUpdate();
// Если статус равен константе OK...
if (status == OK) {
// Если доступ не разрешён...
if (!io_lock)
// Выводим картинку на матрицу
disp.drawImage(denied);
timer = millis();
// Выводим текст в последовательный порт
Serial.println("------- Write OK -------");
}
}
}
if (millis() - timer > DURATION) {
disp.clrScr();
}
}
// Функция преобразования массива байт в строку
void array_to_hex_string(byte array[], unsigned int len, char buf[])
{
for (unsigned int i = 0; i < len; i++)
{
byte nib1 = (array[i] >> 4) & 0x0F;
byte nib2 = (array[i] >> 0) & 0x0F;
buf[i*2+0] = nib1 < 0xA ? '0' + nib1 : 'A' + nib1 - 0xA;
buf[i*2+1] = nib2 < 0xA ? '0' + nib2 : 'A' + nib2 - 0xA;
}
buf[len*2] = '\0';
}
// Функция открывания замка
void open()
{
pinMode(LOCK_PIN, OUTPUT);
digitalWrite(LOCK_PIN, HIGH);
pinMode(ZUM_PIN, OUTPUT);
digitalWrite(ZUM_PIN, HIGH);
delay(DURATION);
pinMode(ZUM_PIN, INPUT);
pinMode(LOCK_PIN, INPUT);
}
// Функция включения зуммера
void buzz()
{
pinMode(ZUM_PIN, OUTPUT);
digitalWrite(ZUM_PIN, HIGH);
delay(300);
pinMode(ZUM_PIN, INPUT);
}
Копирование ключа
После запуска скетча, поднесите ключ к считывателю. Его идентификатор появится в карточке переменной key в Вашей панели на сайте iocontrol (если ключ виден не полностью, зайдите в настройки карточки и измените её размер). Скопируйте этот идентификатор в следующий сценарий для Python
Сценарий Python
Для подключения библиотеки `pyiocontrol` необходимо сначала её установить. Сделать это можно в менеджере модулей в Thonny Python IDE (тогда библиотека установится локально для этого IDE), в виртуальной среде командой `pip3 install pyiocontrol` или в терминале Raspberry (тогда библиотека будет системной) командой:
sudo pip3 install pyiocontrol
Подробнее про установку библиотеки можно узнать по ссылке
#!/usr/bin/python3
import pyiocontrol
from time import sleep
p = pyiocontrol.Panel("НАЗВАНИЕ_ВАШЕЙ_ПАНЕЛИ", "КЛЮЧ_ПАНЕЛИ")
while True:
if p.key == "ИДЕНТИФИКАТОР_RFID_МЕТКИ":
p.lock = True
p.key = '0'
sleep(.5)

Обсуждение