Мне понравилась идея Flipper Zero в хранении и эмуляции электронных ключей. Это довольно удобно, можно избавится от половины моей связки со всеми ключами, плюс те ключи, которые я обычно даже не ношу, будут под рукой, в том числе универсальные. Но не понравились его габариты. К тому же, весь остальной функционал хоть мне и интересен, для этой задачи излишен, а за него тоже надо платить. В этот момент появилась идея и, что самое главное, желание самостоятельно реализовать такую штуку.
Я работаю в центре поддержки одаренных школьников, поэтому сначала дал эту тему одному своему самому продвинутому ученику в качестве проекта. Но потом сам погрузился в этот проект :D
Конечная идея была в эмуляции ключей стандартов TouchMemory, Em-Marine и Mifare classic в одном устройстве. Хочется, чтобы это устройство было максимально компактным, в идеале вообще помещалось на связку ключей.
![Текущие прототипы устройства Текущие прототипы устройства](https://habrastorage.org/r/w1560/getpro/habr/upload_files/752/d97/f08/752d97f08fcf598253d30b5cd9259496.jpg)
Давайте для начала расскажу, что это за стандарты такие.
Распространенные стандарты ключей
Em-Marine и Mifare classic – это бесконтактные ключи, которые работают по беспроводным протоколам на частоте 125кГц для Em-Marine и 13.56 для mifare classic.
Em-Marine – это старые, довольно глупые ключи, которые хранят только свой id, и в основном используются на турникетах и домофонах (если их ещё не заменили на Mifare classic).
Mifare classic работает на частотах nfc, и, соответственно, его без проблем можно прочитать современным телефоном, скопировать (к сожалению с ограничениями), и даже иногда эмулировать (далеко не на всех устройствах, часто только с root правами и т.д.).
Не буду сильно вдаваться в этот стандарт, до работы с ним мы ещё не добрались.
TouchMemory – класс электронных устройств, имеющих однопроводный протокол обмена информацией (1-Wire, но не всегда) и помещённых в стандартный металлический корпус (обычно имеющий вид таблетки).
Это те самые ключи-таблетки, которые вы прислоняете к домофону, чтобы зайти.
Про ключи TouchMemory
В основном стандарт представлен в виде ключей dallas и русских-народных Cyfral и Metacom.
Соответственно, с этих ключей мы и решили начать, т.к. они показались нам самыми простыми. Проектировать это устройство решили на всеми любимой arduino, и кодить естественно в её среде.
Для начала решили разобраться с dallas, все-таки это самые распространённые ключи. И обычно поддерживаются любым домофоном, даже cyfral и metacom. Эти ключи работают на протоколе 1-wire, сам ключ является умным, умеет принимать и обрабатывать несколько стандартных команд, и хранит только свой уникальный ID из 8 байт.
![Протокол 1-wire Протокол 1-wire](https://habrastorage.org/r/w1560/getpro/habr/upload_files/e2e/9fd/398/e2e9fd398a7cf4f6a50099096ed5fed1.jpeg)
Протокол 1-wire работает по модели Master-Slave. В этой топологии устройство Master всегда инициирует общение, а Slave следует его указаниям. При контакте ключа (Slave) с домофоном (Master), ключ получает питание, чип внутри ключа включается, происходит инициализация ключа, после чего домофон запрашивает ID ключа.
Домофон считывает из iButton 8 байт (64 бита) информации, чтобы решить, открывать дверь или нет. Первый байт это family code. У ds1990 это всегда 01, по нему можно понять, что это за ключ (например, у cyfral и metacom мы сюда будем писать уже их коды 10 и 20, в статьях про них объясню, почему так). Далее 6 байт самого ключа и последний байт – контрольная сумма. Иногда код ключа записывают в перевернутом виде, как на схеме:
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/9d9/7aa/9b6/9d97aa9b66b9b02248ecc67982b424dd.jpg)
Подключаем Arduino
Для работы с этим протоколом для ардуины есть шикарная библиотека OneWire, которая позволяет работать ардуино как Master устройство, и на ней написаны прошивки практически всех дубликаторов ключей на ардуино. Проблема в том, что эта библиотека не умеет работать как slave устройство, и, соответственно, написать эмуляцию на ней не получится.
Но для начала было бы неплохо хотя бы прочитать какой-нибудь ключ...
Чтобы обеспечить ключ питанием, достаточно притянуть центральный контакт на 5в через резистор и боковой на gnd. Обычно советуют использовать 2.2кОм, но, как показала практика, можно использовать любой от 500ом до 5кОм, и даже напряжения достаточно 3.3в
Чтобы общаться с ключом по этому протоколу, нужно ещё соединить центральный контакт с каким-нибудь цифровым портом. Далее открываем пример и загружаем.
![Этой схемы уже достаточно, чтобы читать и эмулировать ключи протокола OneWire Этой схемы уже достаточно, чтобы читать и эмулировать ключи протокола OneWire](https://habrastorage.org/r/w1560/getpro/habr/upload_files/588/f75/46b/588f7546b37ce318b1fd3132a3aeceed.jpeg)
Само чтение происходит всего в одну строчку кода:
#include <OneWire.h>
#define iButtonPort 2
byte addr[8];
OneWire ibutton(iButtonPort);
void setup() {
Serial.begin(115200);
}
void loop() {
readKey();
}
void readKey() {
if (ibutton.search(addr)) { // Если устройство подключено - считываем
for (int i = 7; i > -1; i--) { // Запускаем цикл печати данных из массива
Serial.print(addr[i], HEX); // Печатаем нужный байт в шестнадцатиричном виде
Serial.print(" ");
}
Serial.println(); // В конце цикла переводим строку
ibutton.reset_search(); // Сбрасываем устройство
}
}
Давайте вернемся к эмуляции
Поиски библиотеки для эмуляции были долгими, первой нашлась статья на RoboCraft: Arduino/CraftDuino и эмулятор iButton с недописанным кодом, и следом библиотека OneWireSlave, которая до сих пор не может эмулировать ds1990 :(
Было желание на все плюнуть и написать свою библиотеку, но моя лень и упорство вывели меня на библиотеку OneWireHub, которая основана как раз на OneWireSlave :D. Вот она заработала отлично.
![К этому моменту была собрана первая тестовая железка К этому моменту была собрана первая тестовая железка](https://habrastorage.org/r/w1560/getpro/habr/upload_files/09b/5bf/644/09b5bf644b11810ffadf6f184111efb5.png)
![Первое удачное испытание Первое удачное испытание](https://habrastorage.org/r/w1560/getpro/habr/upload_files/65c/89f/0f5/65c89f0f5b5413ca01d000f770f555c3.png)
В этой библиотеке есть пример эмуляции, но для кучи устройств в одном скетче. Я, пожалуй, приведу в пример скетч только с эмуляцией ключа.
#include "OneWireHub.h"
#include "DS2401.h" // Serial Number
#define iButtonPort 2
auto hub = OneWireHub(iButtonPort);
byte Key[8] = { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F }; //универсальный ключ
auto ds1990A = DS2401(Key[0], Key[1], Key[2], Key[3], Key[4], Key[5], Key[6]); //crc считается автоматически
void setup() {
hub.attach(ds1990A); // всегда онлайн
}
void loop() {
hub.poll(); // необходимо периодически вызывать следующую функцию
}
Как видите, ничего сложного. Но на этом этапе уже появились проблемы с нехваткой ресурсов ардуины. Оказывается, у atmega328p всего 2кб оперативной (если точнее SRAM) памяти, а буфер для работы с oled 128х64, который мы решили использовать, занимает смело половину.
В принципе, можно было бы оптимизировать прошивку, повозиться с дисплеем, но для работы с Mifare Classic (хотя до него еще и далеко) памяти уже бы точно не хватило, да и хотелось писать код попроще. Поэтому было решено перейти на более производительный контроллер.
Переходим на ESP8266
И тут выбор встал между stm32f103 (или чем-то подобным) и esp8266. По сути, stm больше подходит к этому проекту, в ней и портов побольше, и полезные аппаратные фишки есть, но stm32 все еще плохо совместима с arduino кодом, поэтому выбор пока остановился на esp8266.
В esp8266 уже 82 кБ SRAM памяти и до 160Мгц частота ядра, что даже больше, чем у stm32f103. Поэтому можно ни в чем себе не отказывать, хоть картины рисовать :D
![И вот готов третий тестовый образец на отладочной плате NodeMCU (esp8266) И вот готов третий тестовый образец на отладочной плате NodeMCU (esp8266)](https://habrastorage.org/r/w1560/getpro/habr/upload_files/76e/5fe/76d/76e5fe76dc995addea2c83233f1bb244.jpg)
Эта железка уже умела читать, писать и эмулировать ключи dallas, а также хранить их в памяти. Также я, естественно, забил в быстрый доступ десять универсальных и часто используемых ключей :)
Но получилось не очень компактно :(
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/1bf/776/a91/1bf776a9149bf6ae94425bc46b27242b.jpg)
Следующий вариант был собран на wemosMini v4, это уже более компактная плата на базе esp8266. Существенно меньше девайс не стал, т.к. экран все равно остался довольно большим.
Зато появился аккумулятор с платой зарядки и стильный фиолетовый корпус!
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/62b/f7d/ea6/62bf7dea6d5d1dd2197680a805affe06.jpg)
Следующим этапом был переход на более маленький oled 1106_128x64. Для него не надо выводить отдельные контакты, т.к. он подключается в стандартный i2c разъем на wemosMini v4 по проводу. И вот с ним удалось добиться хоть какой-то компактности.
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/cb8/c60/fcc/cb8c60fcc3f2060565adc11719abe1f0.jpg)
Бонусом оказалось, что GPIO2 на vemosMini, как и на nodeMCU, уже подтянуты через резистор к 3.3v. Поэтому схема устройства ещё сильнее упростилась. Правда, не на всех платах хватает этой подтяжки, иногда надо добавить резистор 1кОм на 3.3v.
![Схема устройства на vemosMini, сверху кнопки управления. Экран подключен по проводу Схема устройства на vemosMini, сверху кнопки управления. Экран подключен по проводу](https://habrastorage.org/r/w1560/getpro/habr/upload_files/c91/7dd/57e/c917dd57e29c5d79987102ba1d4f7d79.jpg)
Спустя некоторое время появился и корпус. Кривой, конечно, но пока и такой пойдет.
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/9be/695/d54/9be695d545ad66288a2b8de09e3c5593.jpg)
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/f74/d7e/811/f74d7e8110d1338b233159710fa7b6db.jpg)
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/d0c/a09/e0f/d0ca09e0f4759e5e5aee40d150cf80d6.png)
Да, забыл упомянуть про контактную площадку. Мы перебрали кучу вариантов и остановились на форме, которая позволяет удобно читать ключ и имеет надежный и удобный контакт с домофоном. В будущем она, скорее всего, будет изменена, но на данный момент это наиболее удобный вариант.
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/04e/633/2b1/04e6332b1d4932d3dea21b90430509fa.jpg)
Для достижения максимальной компактности, естественно, надо собирать эту штуку на печатной плате, но схема устройства пока всё время меняется, и печатка перерисовывается. Думаю, после победы над контактными ключами попробуем собрать небольшую партию устройств на печатных платах.
![Модель устройства на печатной плате Модель устройства на печатной плате](https://habrastorage.org/r/w1560/getpro/habr/upload_files/8f6/6ad/495/8f66ad49575b332084712f96e8b62859.jpg)
Что уже получилось
Следующим этапом были ключи Cyfral и Metacom.
Спойлер! С метакомом все получилось, можно читать, перекодировать и писать на болванки ds1990, писать на специализированные болванки и даже эмулировать оригинальный ключ! С Cyfral все похуже, можно читать и писать на спец. болванки, но эмулированный ключ домофон так и не воспринимает. Также получилось прочитать, записать и эмулировать EM-Marine. Но про все это в следующих статьях.