Рейтинг@Mail.ru
Ключ типа iButton
Ключ типа iButton

Как сделать копию ключа для домофона в домашних условиях

С помощью Ардуино можно сделать дома копию ключа для домофона за 15 минут, если, к примеру, мастерская закрыта, а ключ нужен срочно.

Инструкция по чтению и записи ключа iButton (1-wire) с помощью Arduino

Вам понадобится

  • Ардуино;
  • компьютер;
  • ключ для домофона типа iButton или 1-wire;
  • ключ-болванка для создания "клона" оригинального ключа;
  • 1 резистор сопротивлением 2,2 кОм;
  • соединительные провода.

1Схема подключения ключа к Arduinoпо однопроводному интерфейсу

Каждый ключ для домофона имеет свой номер – именно этот номер и служит идентификатором ключа. Именно по номеру ключа домофон решает – свой или чужой. Поэтому алгоритм копирования такой: сначала нужно узнать номер разрешённого ключа, а затем присвоить этот номер другому ключу – клону. Для домофона нет разницы, был приложен оригинальный ключ или его копия. Сверив номер со своей базой данных разрешённых номеров, он откроет дверь.

Ключи для домофона, которые мы будем подключать к Arduino (их иногда называют iButton или Touch Memory), считываются и записываются по однопроводному интерфейсу 1-wire. Поэтому схема подключения очень проста. Нам нужны лишь пара проводов и подтягивающий резистор номиналом 2,2 кОм. Схема показана на рисунке.

Схема подключения ключа iButton к Arduino по интерфейсу 1-wire
Схема подключения ключа iButton к Arduino по интерфейсу 1-wire

2Библиотеки для работы с интерфейсом 1-Wire

Для работы с интерфейсом 1-wire существуют готовые библиотеки для Ардуино. Можно воспользоваться, например, этой. Скачиваем архив и распаковываем в папку /libraries/, расположенную в каталоге Arduino IDE. Теперь мы можем очень просто работать с данным протоколом.

Загрузим в Ардуино стандартным способом такой скетч.

#include <OneWire.h>
OneWire iButton(10); // создаём объект 1-wire на 10 выводе

void setup (void) {
  Serial.begin(9600);
}

void loop(void) {
  delay(1000); // задержка 1 сек 
  byte addr[8]; // массив для хранения данных ключа
  
  if ( !iButton.search(addr) ) { // если ключ не приложен
      Serial.println("No key connected..."); // сообщаем об этом
      return; // и прерываем программу
  }
  
  Serial.print("Key : ");
  for(int i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX); // выводим побайтно данные ключа
    Serial.print(" ");
  }
  Serial.println();
  iButton.reset(); // сброс ключа
}

3Считывание номера ключа iButton с помощью Arduino

Данный скетч показывает номер ключа для домофона, который подключён к схеме. Это то, что нам и нужно сейчас: мы должны узнать номер ключа, копию которого хотим сделать. Подключим Ардуино к компьютеру. Запустим монитор последовательного порта: Инструменты Монитор последовательного порта (или сочетание клавиш Ctrl + Shift + M).

Теперь подключим ключ к схеме. Монитор порта покажет номер ключа. Запомним этот номер.

Запоминаем номер ключа iButton, выводимый в монитор последовательного порта
Запоминаем номер ключа iButton, выводимый в монитор последовательного порта

4Запись нового номера ключа iButton с помощью Arduino

Теперь перепишем скетч таким образом, чтобы он мог записывать данные в память ключа.

#include <OneWire.h>  // подключаем библиотеку
const int pin = 10;   // объявляем номер пина
OneWire iButton(pin); // объявляем объект OneWire на 10-ом пине

// номер ключа, который мы хотим записать в iButton:
byte key_to_write[] = { 0x01, 0xF6, 0x75, 0xD7, 0x0F, 0x00 0x00, 0x9A };

void setup(void) { 
  Serial.begin(9600); 
  pinMode(pin, OUTPUT);  
}

void loop(void) {
  delay(1000); // задержка на 1 сек  
  iButton.reset(); // сброс устройства 1-wire
  delay(50); 
  iButton.write(0x33); // отправляем команду "чтение"

  byte data[8]; // массив для хранения данных ключа
  iButton.read_bytes(data, 8); // считываем данные приложенного ключа, 8х8=64 бита
  
  if ( OneWire::crc8(data, 7) != data[7] ) { // проверяем контрольную сумму приложенного ключа
      Serial.println("CRC error!"); // если CRC не верна, сообщаем об этом
      return; // и прерываем программу
  }

  if (data[0] & data[1] & data[2] & data[3] & data[4] & data[5] & data[6] & data[7] == 0xFF) {
    return; // если ключ не приложен к считывателю, прерываем программу и ждём, пока будет приложен
  }

  Serial.print("Start programming..."); // начало процесса записи данных в ключ
  
  for (int i = 0; i < 8; i++) {
    iButton.reset(); // сброс ключа и формирование 4-х байт для записи в ключ
    data[0] = 0x3C; // отправляем команду "запись"
    data[1] = i; // указываем байт для записи
    data[2] = 0;
    data[3] = key_to_write[i]; 
    iButton.write_bytes(data, 4); // записываем i-ый байт в ключ
  
    uint8_t b = iButton.read(); // считываем байт из ключа
    
    if (OneWire::crc8(data, 4) != b) { // при ошибке контрольной суммы
        Serial.println("Error while programming!"); // сообщаем об этом
        return; // и отменяем запись ключа
    }
    send_programming_impulse(); // если всё хорошо, посылаем импульс для записи i-го байта в ключ
  }
  Serial.println("Success!"); // сообщение об успешной записи данных в ключ  
}

// Инициализация записи данных в ключ-таблетку iButton:
void send_programming_impulse() { 
  digitalWrite(pin, HIGH); 
  delay(60);
  digitalWrite(pin, LOW); 
  delay(5);
  digitalWrite(pin, HIGH); 
  delay(50); 
}

Не забудьте задать номер своего оригинального ключа в массиве key_to_write, который мы узнали чуть ранее.

Загрузим этот скетч в Arduino. Откроем монитор последовательного порта (Ctrl + Shift + M). Подключим к схеме ключ, который будет клоном оригинального ключа. О результате программирования монитор последовательного порта выведет соответствующее сообщение.

Обратите внимание

Ключи для домофона бываю разных типов и семейств. Данный код подойдёт не для всех ключей, а только для RW1990 или RW1990.2. Программирование ключей других типов может привести к выходу ключей из строя! При определённом желании, можно переписать программу для ключа другого типа. Для этого нужно найти описание на Ваш ключ (datasheet) и поправить код скетча в соответствии с описанием.

Ошибки при компиляции скетча

1) Если при компиляции скетча возникнет ошибка WConstants.h: No such file or directory #include "WConstants.h", то следует в файле OneWire.cpp заменить первый блок после комментариев на следующий:

#include <OneWire.h>
#include <Arduino.h>
extern "C" {
  #include <avr/io.h>
  #include <pins_arduino.h>
}

2) Если при компиляции появляется ошибка class OneWire has no member named read_bytes или подобная, то найдите другую библиотеку OneWire, в интернете их много.

Последнее изменениеВторник, 05 Январь 2016 16:21
(3 голосов)
Прочитано 17228 раз

Поделиться

Похожие материалы (по тегу)

Оставить комментарий

Убедитесь, что вы вводите (*) необходимую информацию, где нужно
HTML-коды запрещены