OneWire запись на болванку RW1990

b707
Offline
Зарегистрирован: 26.05.2017

satelit 2 пишет:

да там что то не понятное. блинк заливаетсяна ура и через usbasp и через ардуино. а как заливаю копир,то тинька зависает,даже на кнопку не реагирует. залил этот же скетч на ардуино, все работает, все копирует. кстати на ардуино про мини тоже не заливается. добился при заливке аттини не одной ошибки компиляции, а при заливки мини, ошибка что то там про sck

а вы частоту-то тиньке поднимаете? По умолчанию они прошиты под 1 МГц - на такой частоте ONeWire скорее всего виснет

satelit 2
Offline
Зарегистрирован: 04.12.2016

мне этот копир не нужен, я просто для себя решил китайцов обогнуть. уних копир с размером пульта ду, а тут с пробку. я в прошлом году хотел,или в маркер широкий или в зажигалку уместить. на про мини собрал. все работало только через программатор, а без не работает

satelit 2
Offline
Зарегистрирован: 04.12.2016

да на 1мгц. на другой делай коректировать надо

 

b707
Offline
Зарегистрирован: 26.05.2017

satelit 2 пишет:

да на 1мгц. на другой делай коректировать надо

 

достаточно правильно выставить частоту в двух местах - в ИДЕ и во фьюзах. Все остальное подкорректируется само (если конечно у вас код не на ассемблере :)

satelit 2
Offline
Зарегистрирован: 04.12.2016

я фьюзы не трогал. я четез ардуиноIDE заливаю

 

satelit 2
Offline
Зарегистрирован: 04.12.2016

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

b707
Offline
Зарегистрирован: 26.05.2017

satelit 2 пишет:

я четез ардуиноIDE заливаю

 

я тоже . И фьюзы тоже через Ардуино ИДЕ

 

b707
Offline
Зарегистрирован: 26.05.2017

satelit 2 пишет:

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

может и команду. Но перешить на 9.6МГц - это одна минута. я бы попробовал

satelit 2
Offline
Зарегистрирован: 04.12.2016

эх, я уже бредброд разобрал. но завтра соберу обратно. только уже решил вместо батереи устанивоить usbmicro от телефона. батарея сядет со временем, а тут и место не занимает и зарядник всегда рядом. до завтра

satelit 2
Offline
Зарегистрирован: 04.12.2016

9.6мгц толькона аттини13 всавиться,а на у меня только или1 или8. на 8 не прокатило, тинька также зависла,апри загрузке ошибва что то про BS2 . не смог скопировать. может это потому что я использую ide105

Neogar
Offline
Зарегистрирован: 05.12.2017

Для себя написал следующий код (редактировать лень):

/*****************************************************************************************/
/*                                       \\\|///                                         */
/*                                     \\  - -  //                                       */
/*                                      (  @ @  )                                        */
/*               /--------------------oOOo-(_)-oOOo--------------------\                 */
/*               |                                                     |                 */
/*               |  Простой копировщик ключей TouchMemory на Arduino   |                 */
/*               |                                                     |                 */
/*               |        [___]---------> GND (-5V)                    |                 */
/*               |          |    ___                                   |                 */
/*               |          }---|___|---> Vcc (+5V)                    |                 */
/*               |          |  4,7 KOm                                 |                 */
/*               |          }-----------> PIN 7 (Arduino UNO,          |                 */
/*               |                                       Nano,         |                 */
/*               |                            Oooo   Pro Mini, etc.)   |                 */
/*               \---------------------oooO---(   )--------------------/                 */
/*                                    (   )    ) /                                       */
/*                                     \ (    (_/                                        */
/*                                      \_)                                              */
/*                                                                                       */
/* Среда разработки: Arduino IDE v1.8.8                                                  */
/* Плата:            Arduino UNO (Китай)                                                 */
/*                                                                         © NEOGAR.2019 */
/*****************************************************************************************/


#include <avr/pgmspace.h>
#define number_of_messages    10
#define max_size_of_message   53
#define msg1                  ((const char *) &messages[0])   // "Ready!"
#define msg2                  ((const char *) &messages[1])   // "Help: R - reading ID, W - writing new ID, C - cancel"
#define msg3                  ((const char *) &messages[2])   // "Reading ID..."
#define msg4                  ((const char *) &messages[3])   // "Writing new ID..."
#define msg5                  ((const char *) &messages[4])   // "Cancel"
#define msg6                  ((const char *) &messages[5])   // "Key ID:"
#define msg7                  ((const char *) &messages[6])   // "New key ID:"
#define msg8                  ((const char *) &messages[7])   // " 0x"
#define msg9                  ((const char *) &messages[8])   // "Error reading! Try again"
#define msg10                 ((const char *) &messages[9])   // "CRC is not valid!"
const char messages [number_of_messages] [max_size_of_message] PROGMEM = {
  {"Ready!"},
  {"Help: R - reading ID, W - writing new ID, C - cancel"},
  {"Reading ID..."},
  {"Writing new ID..."},
  {"Cancel"},
  {"Key ID:"},
  {"New key ID:"},
  {" 0x"},
  {"Error reading! Try again"},
  {"CRC is not valid!"},
};


uint8_t addr[8];
volatile uint8_t state = 0x00;
/*****************************************************************************************/
/* Значения регистра state                                                               */
/*****************************************************************************************/
#define cmd_cancel            0x00   // Отмена команд
#define read_key              0x01   // Команда на считывание ID ключа. Ожидание ключа (отменяется вводом "C")
#define write_key             0x02   // Команда на запись ID ключа. Ожидание ключа (отменяется вводом "C")

uint8_t err = 0x00;
/*****************************************************************************************/
/* Значения регистра err                                                                 */
/*****************************************************************************************/
#define err_id                0x01   // Ошибка считывания ID ключа
#define err_crc               0x02   // Ошибка CRC ключа


/*****************************************************************************************/
/* Функция инициализации последовательного порта                                         */
/*****************************************************************************************/
void  USART_Init (void)
{
  UBRR0  = 0x67;                     // Serial.begin(9600);
  UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0);
}


/*****************************************************************************************/
/* Функция передачи данных через последовательный порт                                   */
/*****************************************************************************************/
void  USART_Transmit (uint8_t data)
{
  while (!(UCSR0A & (1 << UDRE0)));
  UDR0 = data;
}


/*****************************************************************************************/
/* Функция вывода строки через последовательный порт                                     */
/*****************************************************************************************/
void  USART_String (const char *str, uint8_t new_str)
{
  char out_char;

  if (!str) {
    return;
  }
  while ((out_char = pgm_read_byte(str++))) {
    USART_Transmit(out_char);
  }
  if (new_str) {
    USART_Transmit(0x0A);            // Переход на новую строку (\n, LF)
  }
}


/*****************************************************************************************/
/* Функция конвертирования шестнадцатеричных чисел в символы ASCII                       */
/*****************************************************************************************/
void  USART_HEX (uint8_t nibble_high)
{
  uint8_t array_simbol[2];
  uint8_t counter = 2;
  uint8_t nibble_low = nibble_high;

  array_simbol[0] = (((nibble_high &= 0x0F) <= 9) ? (nibble_high + 0x30) : (nibble_high + 0x41 - 10));
  array_simbol[1] = (((nibble_low >>= 4   ) <= 9) ? (nibble_low  + 0x30) : (nibble_low  + 0x41 - 10));
  while (counter--) {
    USART_Transmit(array_simbol[counter]);
  }
}


/*****************************************************************************************/
/* Функция приема команд через последовательный порт                                     */
/*****************************************************************************************/
ISR (USART_RX_vect)
{
  switch (UDR0) {
    case (0x52): {                   // "R"
        USART_String(msg3, 1);       // "Reading ID..."
        state = read_key;
      } break;
    case (0x57): {                   // "W"
        USART_String(msg4, 1);       // "Writing new ID..."
        state = write_key;
      } break;
    case (0x43): {                   // "C"
        if (state) {
          USART_String(msg5, 1);     // "Cancel"
          USART_Transmit(0x0A);      // Переход на новую строку (\n, LF)
          USART_String(msg2, 1);     // "Help: R - reading ID, W - writing new ID, C - cancel"
          state = cmd_cancel;
        }
      } break;
  }
}


/*****************************************************************************************/
/* Функция передачи импульса сброса по шине 1-Wire                                       */
/*****************************************************************************************/
bool  OneWire_Reset (void)
{
  uint8_t presence;

  PORTD &= ~(1 << 7);                // digitalWrite(7, LOW);
  DDRD  |= (1 << 7);                 // pinMode(7, OUTPUT);
  _delay_us(480);                    // delayMicroseconds(480);
  DDRD  &= ~(1 << 7);                // pinMode(7, INPUT);
  _delay_us(70);                     // delayMicroseconds(70);
  presence = (PIND & (1 << 7));      // digitalRead(7);
  _delay_us(410);                    // delayMicroseconds(410);
  return presence;
}


/*****************************************************************************************/
/* Функция записи данных по шине 1-Wire                                                  */
/*****************************************************************************************/
void  OneWire_Write (uint8_t wrt_byte)
{
  uint8_t i = 0;

  DDRD |= (1 << 7);                  // pinMode(7, OUTPUT);
  while (i < 8) {
    if (wrt_byte & 1) {              // Запись "1"
      PORTD &= ~(1 << 7);            // digitalWrite(7, LOW);
      _delay_us(10);                 // delayMicroseconds(10);
    }
    else {                           // Запись "0"
      PORTD &= ~(1 << 7);            // digitalWrite(7, LOW);
      _delay_us(60);                 // delayMicroseconds(60);
    }
    PORTD |=  (1 << 7);              // digitalWrite(7, HIGH);
    _delay_ms(5);                    // delay(5);
    wrt_byte >>= 1;
    i++;
  }
}


/*****************************************************************************************/
/* Функция приема данных по шине 1-Wire и их записи в массив addr                        */
/*****************************************************************************************/
void  OneWire_Read (void)
{
  uint8_t i;

  OneWire_Reset();
  OneWire_Write(0x33);
  for (i = 0; i < 8; i++) {
    uint8_t bitMask;
    uint8_t rd_bit;
    uint8_t rd_byte = 0;
    for (bitMask = 0x01; bitMask; bitMask <<= 1) {
      PORTD &= ~(1 << 7);            // digitalWrite(7, LOW);
      DDRD  |=  (1 << 7);            // pinMode(7, OUTPUT);
      _delay_us(6);                  // delayMicroseconds(6);
      DDRD  &= ~(1 << 7);            // pinMode(7, INPUT);
      _delay_us(9);                  // delayMicroseconds(9);
      rd_bit = (PIND & (1 << 7));    // digitalRead(7);
      _delay_us(55);                 // delayMicroseconds(55);
      if (rd_bit) {
        rd_byte |= bitMask;
      }
    }
    addr[i]  = rd_byte;
  }
}


/*****************************************************************************************/
/* Функция проверки считываемого ID ключа                                                */
/*****************************************************************************************/
bool  iButton_Check_ID (void)
{
  uint8_t i;
  uint8_t addr_temp[8];

  for (i = 0; i < 8; i++) {
    addr_temp[i] = addr[i];
  }
  OneWire_Read();
  for (i = 0; i < 8; i++) {
    if (addr_temp[i] != addr[i]) {
      USART_String(msg9, 1);         // "Error reading! Try again"
      err = err_id;
      return 0;                      // Ошибка считывания ID ключа
    } else {
      return 1;                      // Успешное считывание ID ключа
    }
  }
}


/*****************************************************************************************/
/* Функция проверки контрольной суммы ID ключа                                           */
/*****************************************************************************************/
bool  iButton_Checksum (uint8_t *addr)
{
  uint8_t addrsvn = addr[7];
  uint8_t len     = 7;
  uint8_t crc     = 0;
  uint8_t inbyte;
  uint8_t i;
  uint8_t mix;

  while (len--) {
    inbyte  = *addr++;
    for (i  = 8; i; i--) {
      mix   = (crc ^ inbyte) & 0x01;
      crc >>= 1;
      if (mix) crc ^= 0x8C;
      inbyte >>= 1;
    }
  }
  if (crc != addrsvn) {
    USART_String(msg10, 1);          // "CRC is not valid!"
    err  = err_crc;
    return 0;                        // Ошибка CRC ключа
  } else {
    return 1;                        // Правильный CRC ключа
  }
}


/*****************************************************************************************/
/* Функция считывания ID ключа                                                           */
/*****************************************************************************************/
void  iButton_Read (void)
{
  uint8_t i;

  if (OneWire_Reset()) {
    return;
  }
  OneWire_Read();
  if (!iButton_Check_ID() || !iButton_Checksum(addr)) {
    USART_Transmit(0x0A);            // Переход на новую строку (\n, LF)
    USART_String(msg2, 1);           // "Help: R - reading ID, W - writing new ID, C - cancel"
    state = cmd_cancel;
    return;
  }
  USART_String(msg6, 0);             // "Key ID:"
  for (i = 0; i < 8; i++) {
    USART_String(msg8, 0);           // " 0x"
    USART_HEX(addr[i]);
  }
  USART_Transmit(0x0A);              // Переход на новую строку (\n, LF)
  USART_Transmit(0x0A);              // Переход на новую строку (\n, LF)
  USART_String(msg2, 1);             // "Help: R - reading ID, W - writing new ID, C - cancel"
  err   = cmd_cancel;
  state = cmd_cancel;
}


/*****************************************************************************************/
/* Функция записи ID ключа                                                               */
/*****************************************************************************************/
void  iButton_Write (void)
{
  uint8_t i;

  if (err == err_id) {
    USART_String(msg9, 1);           // "Error reading! Try again"
    USART_String(msg5, 1);           // "Cancel"
    USART_Transmit(0x0A);            // Переход на новую строку (\n, LF)
    USART_String(msg2, 1);           // "Help: R - reading ID, W - writing new ID, C - cancel"
    state = cmd_cancel;
    return;
  }
  if (err == err_crc) {
    USART_String(msg10, 1);          // "CRC is not valid!"
    USART_String(msg5, 1);           // "Cancel"
    USART_Transmit(0x0A);            // Переход на новую строку (\n, LF)
    USART_String(msg2, 1);           // "Help: R - reading ID, W - writing new ID, C - cancel"
    state = cmd_cancel;
    return;
  }
  if (OneWire_Reset()) {
    return;
  }
  OneWire_Reset();
  OneWire_Write(0xD1);               // Начать запись RW-1990.1 (для RW1990.2 команда "0x1D")
  OneWire_Write(0x00);
  OneWire_Reset();
  OneWire_Write(0xD5);               // Команда на запись RW-1990.1
  for (i = 0; i < 8; i++) {          // Запись 8-байтного кода
    OneWire_Write(~addr[i]);         // Для RW1990.1 все биты инвертированы (для RW1990.2: OneWire_Write(addr[i]);)
  }
  OneWire_Reset();
  OneWire_Write(0xD1);               // Закончить запись RW-1990.1 (для RW1990.2 команда "0x1D")
  OneWire_Write(0x01);
  OneWire_Read();
  if (!iButton_Check_ID() || !iButton_Checksum(addr)) {
    USART_Transmit(0x0A);            // Переход на новую строку (\n, LF)
    USART_String(msg2, 1);           // "Help: R - reading ID, W - writing new ID, C - cancel"
    return;
  }
  USART_String(msg7, 0);             // "New key ID:"
  for (i = 0; i < 8; i++) {
    USART_String(msg8, 0);           // " 0x"
    USART_HEX(addr[i]);
  }
  USART_Transmit(0x0A);              // Переход на новую строку (\n, LF)
  USART_Transmit(0x0A);              // Переход на новую строку (\n, LF)
  USART_String(msg2, 1);             // "Help: R - reading ID, W - writing new ID, C - cancel"
  state = cmd_cancel;
}


void  setup (void)
{
  uint8_t i;

  USART_Init();
  USART_String(msg1, 1);             // "Ready!"
  USART_Transmit(0x0A);              // Переход на новую строку (\n, LF)
  USART_String(msg2, 1);             // "Help: R - reading ID, W - writing new ID, C - cancel"
  USART_String(msg6, 0);             // "Key ID:"
  for (i = 0; i < 8; i++) {
    USART_String(msg8, 0);           // " 0x"
    USART_HEX(addr[i]);
  }
  USART_Transmit(0x0A);              // Переход на новую строку (\n, LF)
  sei();
}


void  loop (void)
{
  switch (state) {
    case (read_key): {
        iButton_Read();
      } break;
    case (write_key): {
        iButton_Write();
      } break;
  }
  _delay_ms(30);
}

// Скетч использует 2054 байт (6%) памяти устройства. Всего доступно 32256 байт.
// Глобальные переменные используют 19 байт (0%) динамической памяти, оставляя 2029 байт для локальных переменных. Максимум: 2048 байт.

Скачать можно по ссылке https://yadi.sk/d/lnBduz6H0PYhZQ

Конструктивные замечания приветствую.

Neogar
Offline
Зарегистрирован: 05.12.2017

Оговорился: state и err - переменные.

b707
Offline
Зарегистрирован: 26.05.2017

Neogar пишет:

Для себя написал следующий код (редактировать лень):

Конструктивные замечания приветствую.

это называется "когда коту делать нечего..."

Функции USART_Init, String, Hex и тд - в классе Serial заменяются одной строчкой. Писать в Ардуино ИДЕ и работать с USART через регистры - тупой и бессмысленный снобизм :)

Не удивлюсь, если собственно запись на болванку еще и не работает :)

Neogar
Offline
Зарегистрирован: 05.12.2017

b707 пишет:

Функции USART_Init, String, Hex и тд - в классе Serial заменяются одной строчкой.

Конечно заменяются. Сравним?

void setup() {
  Serial.begin(9600);
  Serial.print('a');
}

void loop() {
  
}
// Скетч использует 1452 байт (4%) памяти устройства. Всего доступно 32256 байт.
// Глобальные переменные используют 184 байт (8%) динамической памяти, оставляя 1864 байт для локальных переменных. Максимум: 2048 байт.

И такой:

void setup() {
  UBRR0  = 0x67;   // Serial.begin(9600);
  UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0);
  while (!(UCSR0A & (1 << UDRE0)));
  UDR0 = 'b';      // Serial.print('b');
}

void loop() {
  
}
// Скетч использует 476 байт (1%) памяти устройства. Всего доступно 32256 байт.
// Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.

Это я к вопросу о регистрах.

b707 пишет:

Писать в Ардуино ИДЕ и работать с USART через регистры - тупой и бессмысленный снобизм :)

Только никому больше этого не говорите!

b707 пишет:

это называется "когда коту делать нечего..."

Это называется дать ответ на поставленный вопрос.

Спрашивайте, если в коде что-то непонятно.

И да, китайские болванки пишутся "на ура".

b707
Offline
Зарегистрирован: 26.05.2017

Neogar пишет:

b707 пишет:

Функции USART_Init, String, Hex и тд - в классе Serial заменяются одной строчкой.

Конечно заменяются. Сравним?

сравнили? - выиграли 1000 байт флеша,? - рады?

А теперь сравните вот что - первый код без малейших изменений будет работать на Уно, Меге, Дуе и СТМ32. А ваш?

Выигрывая в размере кода - вы потеряли в переносимости, простоте и наглядности. Если бы в этом был хоть какой-то смысл - например при нехватке места - вы были бы молодец. Но весь ваш код даже в формате Ардуино ИДЕ вряд ли займет хотя бы 20% свободного флеша Атмеги328. Так что остаюсь при своем мнении - это пустое и глупое выеживание на ровном месте.

А то что болванки пишутся - искренне рад. Это неожиданно. Обычно те, кто любит использовать низкоуровневые операторы без нужды - банально не умеют программировать высоуровневым кодом.

Neogar
Offline
Зарегистрирован: 05.12.2017
Я глубоко уважаю Ваше мнение. Если Вам претит низкоуровневое программирование, то, пожалуйста оставьте это при себе. Скетч был написан под платы на Atmega328. И написан на языке долеко от низкоуровнего - ассемблера.  Если Вы просмотрели скетч до конца, то последние строки для UNO:
Скетч использует 2054 байт (6%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 19 байт (0%) динамической памяти, оставляя 2029 байт для локальных переменных. Максимум: 2048 байт.
Причем это лишь часть программного кода моего проекта, где еще используются другие модули, EEPROM. Поэтому ставка на размер кода. А сам скетч легко переписывается для переносимости, простоты и наглядности и наша с Вами полемика уводит в сторону от темы этой ветки форума.
LevaP
Offline
Зарегистрирован: 11.05.2019

Народ, скиньте рабочий скетч для создания универсального ключа от всех домофонов если есть таковой?
Болванка rw1990

b707
Offline
Зарегистрирован: 26.05.2017

LevaP пишет:

Народ, скиньте рабочий скетч для создания универсального ключа от всех домофонов если есть таковой?

нет такого (универсального ключа)

satelit 2
Offline
Зарегистрирован: 04.12.2016

я обслуживаю домофоны. домофон открывает дверь, только тем ключем, которые записали в него. или копии этих ключей. универсальный ключ это миф.

кстати я заметил, что пустые ячейки памяти заполнены FF

timurtanum
Offline
Зарегистрирован: 15.11.2014
Доброго времени суток . нашел дубликатор домофонных ключей . на болванки RW1990 и т.д читает пишет данный девайс . на 125 mHz нашел только карточку с кодом mifare . 
если кому не сложно , подкскажите как добавить новые домофоны в эту прошивку ? кто разбирается как добавить новые протоколы для чтение разных карт от домофонов . заранее спасибо 



#include <OneWire.h>
#include "pitches.h"

#define CheckL 0           // для настройки катушки временно установите тут единицу
#define iButtonPin A3      // Линия data ibutton
#define R_Led 2            // RGB Led
#define G_Led 3
#define B_Led 4
#define VRpinGnd 5         // Земля подстроечного резистора для аналогового компаратора
#define ACpin 6            // Вход Ain0 аналогового компаратора для EM-Marie
#define BtnPin 8           // Кнопка переключения режима чтение/запись
#define BtnPinGnd 9        // Земля кнопки переключения режима 
#define speakerPin 10       // Спикер, он же buzzer, он же beeper
#define FreqGen 11         // генератор 125 кГц
#define speakerPinGnd 12   // земля Спикера
#define rfidBitRate 2       // Скорость обмена с rfid в kbps
#define rfidUsePWD 0        // ключ использует пароль для изменения
#define rfidPWD 123456      // пароль для ключа

OneWire ibutton (iButtonPin); 
byte addr[8];                             // временный буфер
byte keyID[8];                            // ID ключа для записи
byte rfidData[5];                         // значащие данные frid em-marine
bool readflag = false;                    // флаг сигнализирует, что данные с ключа успечно прочианы в ардуино
bool writeflag = false;                   // режим запись/чтение
bool preBtnPinSt = HIGH;
enum emRWType {rwUnknown, TM01, RW1990_1, RW1990_2, TM2004, T5557, EM4305};               // тип болванки
enum emkeyType {keyUnknown, keyDallas, keyTM2004, keyCyfral, keyMetacom, keyEM_Marie};    // тип оригинального ключа  
emkeyType keyType;

void setup() {
  pinMode(BtnPin, INPUT_PULLUP);                            // включаем чтение и подягиваем пин кнопки режима к +5В
  pinMode(BtnPinGnd, OUTPUT); digitalWrite(BtnPinGnd, LOW); // подключаем второй пин кнопки к земле
  pinMode(speakerPin, OUTPUT);
  pinMode(speakerPinGnd, OUTPUT); digitalWrite(speakerPinGnd, LOW); // подключаем второй пин спикера к земле
  pinMode(ACpin, INPUT);                                            // Вход аналогового компаратора для ключей RFID и аналоговых ключей Cyfral / Metacom
  pinMode(VRpinGnd, OUTPUT); digitalWrite(VRpinGnd, LOW);           // подключаем пин подстроечного резистора к земле
  pinMode(R_Led, OUTPUT); pinMode(G_Led, OUTPUT); pinMode(B_Led, OUTPUT);  //RGB-led
  clearLed();
  pinMode(FreqGen, OUTPUT);                               
  digitalWrite(B_Led, HIGH);                                //awaiting of origin key data
  Serial.begin(115200);
  Sd_StartOK();
}

void clearLed(){
  digitalWrite(R_Led, LOW);
  digitalWrite(G_Led, LOW);
  digitalWrite(B_Led, LOW);  
}

//*************** dallas **************
emRWType getRWtype(){    
   byte answer;
  // TM01 это неизвестный тип болванки, делается попытка записи TM-01 без финализации для dallas или c финализацией под cyfral или metacom
  // RW1990_1 - dallas-совместимые RW-1990, RW-1990.1, ТМ-08, ТМ-08v2 
  // RW1990_2 - dallas-совместимая RW-1990.2
  // TM2004 - dallas-совместимая TM2004 в доп. памятью 1кб
  // пробуем определить RW-1990.1
  ibutton.reset(); ibutton.write(0xD1); // проуем снять флаг записи для RW-1990.1
  ibutton.write_bit(1);                 // записываем значение флага записи = 1 - отключаем запись
  delay(10); pinMode(iButtonPin, INPUT);
  ibutton.reset(); ibutton.write(0xB5); // send 0xB5 - запрос на чтение флага записи
  answer = ibutton.read();
  //Serial.print("\n Answer RW-1990.1: "); Serial.println(answer, HEX);
  if (answer == 0xFE){
    Serial.println(" Type: dallas RW-1990.1 ");
    return RW1990_1;            // это RW-1990.1
  }
  // пробуем определить RW-1990.2
  ibutton.reset(); ibutton.write(0x1D);  // пробуем установить флаг записи для RW-1990.2 
  ibutton.write_bit(1);                  // записываем значение флага записи = 1 - включаем запись
  delay(10); pinMode(iButtonPin, INPUT);
  ibutton.reset(); ibutton.write(0x1E);  // send 0x1E - запрос на чтение флага записи
  answer = ibutton.read();
  if (answer == 0xFE){
    ibutton.reset(); ibutton.write(0x1D); // возвращаем оратно запрет записи для RW-1990.2
    ibutton.write_bit(0);                 // записываем значение флага записи = 0 - выключаем запись
    delay(10); pinMode(iButtonPin, INPUT);
    Serial.println(" Type: dallas RW-1990.2 ");
    return RW1990_2; // это RW-1990.2
  }
  // пробуем определить TM-2004
  ibutton.reset(); ibutton.write(0x33);                     // посылаем команду чтения ROM для перевода в расширенный 3-х байтовый режим
  for ( byte i=0; i<8; i++) ibutton.read();                 // читаем данные ключа
  ibutton.write(0xAA);                                      // пробуем прочитать регистр статуса для TM-2004    
  ibutton.write(0x00); ibutton.write(0x00);                 // передаем адрес для считывания
  answer = ibutton.read();                                  // читаем CRC комманды и адреса
  byte m1[3] = {0xAA, 0,0};                                 // вычисляем CRC комманды
  if (OneWire::crc8(m1, 3) == answer) {
    answer = ibutton.read();                                  // читаем регистр статуса
    //Serial.print(" status: "); Serial.println(answer, HEX);
    Serial.println(" Type: dallas TM2004");
    ibutton.reset();
    return TM2004; // это Type: TM2004
  }
  ibutton.reset();
  Serial.println(" Type: dallas unknown, trying TM-01! ");
  return TM01;                              // это неизвестный тип DS1990, нужно перебирать алгоритмы записи (TM-01)
}

bool write2iBtnTM2004(){                // функция записи на TM2004
  byte answer; bool result = true;
  ibutton.reset();
  ibutton.write(0x3C);                                      // команда записи ROM для TM-2004    
  ibutton.write(0x00); ibutton.write(0x00);                 // передаем адрес с которого начинается запись
  for (byte i = 0; i<8; i++){
    digitalWrite(R_Led, !digitalRead(R_Led));
    ibutton.write(keyID[i]);
    answer = ibutton.read();
    //if (OneWire::crc8(m1, 3) != answer){result = false; break;}     // crc не верный
    delayMicroseconds(600); ibutton.write_bit(1); delay(50);         // испульс записи
    pinMode(iButtonPin, INPUT);
    Serial.print('*');
    Sd_WriteStep();
    if (keyID[i] != ibutton.read()) { result = false; break;}    //читаем записанный байт и сравниваем, с тем что должно записаться
  } 
  if (!result){
    ibutton.reset();
    Serial.println(" The key copy faild");
    Sd_ErrorBeep();
    digitalWrite(R_Led, HIGH);
    return false;    
  }
  ibutton.reset();
  Serial.println(" The key has copied successesfully");
  Sd_ReadOK();
  delay(500);
  digitalWrite(R_Led, HIGH);
  return true;
}

bool write2iBtnRW1990_1_2_TM01(emRWType rwType){              // функция записи на RW1990.1, RW1990.2, TM-01C(F)
  byte rwCmd, rwFlag = 1;
  switch (rwType){
    case TM01: rwCmd = 0xC1; break;                   //TM-01C(F)
    case RW1990_1: rwCmd = 0xD1; rwFlag = 0; break;  // RW1990.1  флаг записи инвертирован
    case RW1990_2: rwCmd = 0x1D; break;              // RW1990.2
  }
  ibutton.reset(); ibutton.write(rwCmd);       // send 0xD1 - флаг записи
  ibutton.write_bit(rwFlag);                   // записываем значение флага записи = 1 - разрешить запись
  delay(10); pinMode(iButtonPin, INPUT);
  ibutton.reset(); ibutton.write(0xD5);        // команда на запись
  for (byte i = 0; i<8; i++){
    digitalWrite(R_Led, !digitalRead(R_Led));
    if (rwType == RW1990_1) BurnByte(~keyID[i]);      // запись происходит инверсно для RW1990.1
      else BurnByte(keyID[i]);
    Serial.print('*');
    Sd_WriteStep();
  } 
  ibutton.write(rwCmd);                     // send 0xD1 - флаг записи
  ibutton.write_bit(!rwFlag);               // записываем значение флага записи = 1 - отключаем запись
  delay(10); pinMode(iButtonPin, INPUT);
  digitalWrite(R_Led, LOW);       
  if (!dataIsBurningOK()){          // проверяем корректность записи
    Serial.println(" The key copy faild");
    Sd_ErrorBeep();
    digitalWrite(R_Led, HIGH);
    return false;
  }
  Serial.println(" The key has copied successesfully");
  if ((keyType == keyMetacom)||(keyType == keyCyfral)){      //переводим ключ из формата dallas
    ibutton.reset();
    if (keyType == keyCyfral) ibutton.write(0xCA);       // send 0xCA - флаг финализации Cyfral
      else ibutton.write(0xCB);                       // send 0xCA - флаг финализации metacom
    ibutton.write_bit(1);                             // записываем значение флага финализации = 1 - перевезти формат
    delay(10); pinMode(iButtonPin, INPUT);
  }
  Sd_ReadOK();
  delay(500);
  digitalWrite(R_Led, HIGH);
  return true;
}

void BurnByte(byte data){
  for(byte n_bit=0; n_bit<8; n_bit++){ 
    ibutton.write_bit(data & 1);  
    delay(5);                        // даем время на прошивку каждого бита до 10 мс
    data = data >> 1;                // переходим к следующему bit
  }
  pinMode(iButtonPin, INPUT);
}

bool dataIsBurningOK(){
  byte buff[8];
  if (!ibutton.reset()) return false;
  ibutton.write(0x33);
  ibutton.read_bytes(buff, 8);
  byte Check = 0;
  for (byte i = 0; i < 8; i++) 
    if (keyID[i] == buff[i]) Check++;      // сравниваем код для записи с тем, что уже записано в ключе.
  if (Check != 8) return false;             // если коды совпадают, ключ успешно скопирован
  return true;
}

bool write2iBtn(){
  int Check = 0;
  if (!ibutton.search(addr)) { 
    ibutton.reset_search(); 
    return false;
  }
  Serial.print("The new key code is: ");
  for (byte i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX); Serial.print(":");  
    if (keyID[i] == addr[i]) Check++;    // сравниваем код для записи с тем, что уже записано в ключе.
  }
  if (Check == 8) {                     // если коды совпадают, ничего писать не нужно
    digitalWrite(R_Led, LOW); 
    Serial.println(" it is the same key. Writing in not needed.");
    Sd_ErrorBeep();
    digitalWrite(R_Led, HIGH);
    delay(500);
    return false;
  }
  emRWType rwType = getRWtype(); // определяем тип RW-1990.1 или 1990.2 или TM-01
  Serial.print("\n Burning iButton ID: ");
  if (rwType == TM2004) return write2iBtnTM2004();  //шьем TM2004
    else return write2iBtnRW1990_1_2_TM01(rwType); //пробуем прошить другие форматы
}

bool searchIbutton(){
  if (!ibutton.search(addr)) { 
    ibutton.reset_search(); 
    return false;
  }  
  for (byte i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX); Serial.print(":");
    keyID[i] = addr[i];                               // копируем прочтенный код в ReadID
  }
  if (addr[0] == 0x01) {                         // это ключ формата dallas
    keyType = keyDallas;
    if (getRWtype() == TM2004) keyType = keyTM2004;
    if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      Sd_ErrorBeep();
      digitalWrite(B_Led, HIGH);
      return false;
    }
    return true;
  }
  if ((addr[0]>>4) == 0x0E) Serial.println(" Type: unknown family dallas. May be cyfral in dallas key.");
    else Serial.println(" Type: unknown family dallas");
  keyType = keyUnknown;
  return true;
}

//************ Cyfral ***********************
unsigned long pulseAComp(bool pulse, unsigned long timeOut = 20000){  // pulse HIGH or LOW
  bool AcompState;
  unsigned long tStart = micros();
  do {
    AcompState = (ACSR >> ACO)&1;  // читаем флаг компаратора
    if (AcompState == pulse) {
      tStart = micros();
      do {
        AcompState = (ACSR >> ACO)&1;  // читаем флаг компаратора
        if (AcompState != pulse) return (long)(micros() - tStart);  
      } while ((long)(micros() - tStart) < timeOut);
      return 0;                                                 //таймаут, импульс не вернуся оратно
    }             // end if
  } while ((long)(micros() - tStart) < timeOut);
  return 0;
}

void ACsetOn(){
  ACSR |= 1<<ACBG;                            // Подключаем ко входу Ain0 1.1V для Cyfral/Metacom
  ADCSRA &= ~(1<<ADEN);                       // выключаем ADC
  ADMUX = (ADMUX&0b11110000) | 0b0011;        // подключаем к AC Линию A3
  ADCSRB |= 1<<ACME;                          // включаем мультиплексор AC
}

bool read_cyfral(byte* buf, byte CyfralPin){
  unsigned long ti; byte j = 0;
  digitalWrite(CyfralPin, LOW); pinMode(CyfralPin, OUTPUT);  //отклчаем питание от ключа
  delay(100);
  pinMode(CyfralPin, INPUT);  // включаем пиание Cyfral
  ACsetOn(); 
  for (byte i = 0; i<36; i++){    // чиаем 36 bit
    ti = pulseAComp(HIGH);
    if ((ti == 0) || (ti > 200)) break;                      // not Cyfral
    //if ((ti > 20)&&(ti < 50)) bitClear(buf[i >> 3], 7-j);
    if ((ti > 90) && (ti < 200)) bitSet(buf[i >> 3], 7-j);
    j++; if (j>7) j=0; 
  }
  if (ti == 0) return false;
  if ((buf[0] >> 4) != 0b1110) return false;   /// not Cyfral
  byte test;
  for (byte i = 1; i<4; i++){
    test = buf[i] >> 4;
    if ((test != 1)&&(test != 2)&&(test != 4)&&(test != 8)) return false;
    test = buf[i] & 0x0F;
    if ((test != 1)&&(test != 2)&&(test != 4)&&(test != 8)) return false;
  }
  return true;
}

bool searchCyfral(){
  for (byte i = 0; i < 8; i++) addr[i] = 0;
  if (!read_cyfral(addr, iButtonPin)) return false; 
  keyType = keyCyfral;
  for (byte i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX); Serial.print(":");
    keyID[i] = addr[i];                               // копируем прочтенный код в ReadID
  }
  Serial.println(" Type: Cyfral ");
  return true;  
}

//**********EM-Marine***************************
bool vertEvenCheck(byte* buf){        // проверка четности столбцов с данными
  byte k;
  k = 1&buf[1]>>6 + 1&buf[1]>>1 + 1&buf[2]>>4 + 1&buf[3]>>7 + 1&buf[3]>>2 + 1&buf[4]>>5 + 1&buf[4] + 1&buf[5]>>3 + 1&buf[6]>>6 + 1&buf[6]>>1 + 1&buf[7]>>4;
  if (k&1) return false;
  k = 1&buf[1]>>5 + 1&buf[1] + 1&buf[2]>>3 + 1&buf[3]>>6 + 1&buf[3]>>1 + 1&buf[4]>>4 + 1&buf[5]>>7 + 1&buf[5]>>2 + 1&buf[6]>>5 + 1&buf[6] + 1&buf[7]>>3;
  if (k&1) return false;
  k = 1&buf[1]>>4 + 1&buf[2]>>7 + 1&buf[2]>>2 + 1&buf[3]>>5 + 1&buf[3] + 1&buf[4]>>3 + 1&buf[5]>>6 + 1&buf[5]>>1 + 1&buf[6]>>4 + 1&buf[7]>>7 + 1&buf[7]>>2;
  if (k&1) return false;
  k = 1&buf[1]>>3 + 1&buf[2]>>6 + 1&buf[2]>>1 + 1&buf[3]>>4 + 1&buf[4]>>7 + 1&buf[4]>>2 + 1&buf[5]>>5 + 1&buf[5] + 1&buf[6]>>3 + 1&buf[7]>>6 + 1&buf[7]>>1;
  if (k&1) return false;
  if (1&buf[7]) return false;
  //номер ключа, который написан на корпусе
  rfidData[0] = (0b01111000&buf[1])<<1 | (0b11&buf[1])<<2 | buf[2]>>6;
  rfidData[1] = (0b00011110&buf[2])<<3 | buf[3]>>4;
  rfidData[2] = buf[3]<<5 | (0b10000000&buf[4])>>3 | (0b00111100&buf[4])>>2;
  rfidData[3] = buf[4]<<7 | (0b11100000&buf[5])>>1 | 0b1111&buf[5];
  rfidData[4] = (0b01111000&buf[6])<<1 | (0b11&buf[6])<<2 | buf[7]>>6;
  return true;
}

byte ttAComp(unsigned long timeOut = 10000){  // pulse 0 or 1 or -1 if timeout
  byte AcompState, AcompInitState;
  unsigned long tStart = micros();
  AcompInitState = (ACSR >> ACO)&1;               // читаем флаг компаратора
  do {
    AcompState = (ACSR >> ACO)&1;                 // читаем флаг компаратора
    if (AcompState != AcompInitState) {
      delayMicroseconds(1000/(rfidBitRate*4));    // 1/4 Period on 2 kBps = 125 mks 
      AcompState = (ACSR >> ACO)&1;               // читаем флаг компаратора      
      delayMicroseconds(1000/(rfidBitRate*2));    // 1/2 Period on 2 kBps = 250 mks 
      return AcompState;  
    }
  } while ((long)(micros() - tStart) < timeOut);
  return 2;                                             //таймаут, компаратор не сменил состояние
}

bool readEM_Marie(byte* buf){
  unsigned long tStart = millis();
  byte ti; byte j = 0, k=0;
  for (int i = 0; i<64; i++){    // читаем 64 bit
    ti = ttAComp();
    if (ti == 2)  break;         //timeout
    if ( ( ti == 0 ) && ( i < 9)) {  // если не находим 9 стартовых единиц - начинаем сначала
      if ((long)(millis()-tStart) > 50) { ti=2; break;}  //timeout
      i = -1; j=0; continue;
    }
    if ((i > 8) && (i < 59)){     //начиная с 9-го бита проверяем контроль четности каждой строки
      if (ti) k++;                // считаем кол-во единиц
      if ( (i-9)%5 == 4 ){        // конец строки с данными из 5-и бит, 
        if (k & 1) {              //если нечетно - начинаем сначала
          i = -1; j = 0; k = 0; continue; 
        }
        k = 0;
      }
    }
    if (ti) bitSet(buf[i >> 3], 7-j);
      else bitClear(buf[i >> 3], 7-j);
    j++; if (j>7) j=0; 
  }
  if (ti == 2) return false;         //timeout
  return vertEvenCheck(buf);
}

void rfidACsetOn(){
  //включаем генератор 125кГц
  TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);  //Вкючаем режим Toggle on Compare Match на COM2A (pin 11) и счет таймера2 до OCR2A
  TCCR2B = _BV(WGM22) | _BV(CS20);                                // Задаем делитель для таймера2 = 1 (16 мГц)
  OCR2A = 63;                                                    // 63 тактов на период. Частота на COM2A (pin 11) 16000/64/2 = 125 кГц, Скважнось COM2A в этом режиме всегда 50% 
  OCR2B = 31;                                                     // Скважность COM2B 32/64 = 50%  Частота на COM2A (pin 3) 16000/64 = 250 кГц
  // включаем компаратор
  ADCSRB &= ~(1<<ACME);           // отключаем мультиплексор AC
  ACSR &= ~(1<<ACBG);             // отключаем от входа Ain0 1.1V
  digitalWrite(ACpin, LOW); pinMode(ACpin, OUTPUT);                                            // ускоряем переходные процессы в детекторе с 12мс до 2 мс
  delay(1);
  pinMode(ACpin, INPUT);
  delay(1);
}

bool searchEM_Marine( bool copyKey = true){
  byte gr = digitalRead(G_Led);
  bool rez = false;
  rfidACsetOn();            // включаем генератор 125кГц и компаратор
  delay(4);                //4 мс запускается ключ
  if (!readEM_Marie(addr)) goto l2;
  rez = true;
  keyType = keyEM_Marie;
  for (byte i = 0; i<8; i++){
    if (copyKey) keyID[i] = addr [i];
    Serial.print(addr[i], HEX); Serial.print(":");
  }
  Serial.print(" ( id ");
  Serial.print(rfidData[0]); Serial.print(" key ");
  unsigned long keyNum = (unsigned long)rfidData[1]<<24 | (unsigned long)rfidData[2]<<16 | (unsigned long)rfidData[3]<<8 | (unsigned long)rfidData[4];
  Serial.print(keyNum);
  Serial.println(") Type: EM-Marie ");
  l2:
  if (!CheckL)
    if (!copyKey) TCCR2A &=0b00111111;              //Оключить ШИМ COM2A (pin 11). Для настройки катушки в резонанс установите CheckL в 1
  digitalWrite(G_Led, gr);
  return rez;
}

void TxBitRfid(byte data){
  if (data & 1) delayMicroseconds(54*8); 
    else delayMicroseconds(24*8);
  rfidGap(19*8);                       //write gap
}

void TxByteRfid(byte data){
  for(byte n_bit=0; n_bit<8; n_bit++){
    TxBitRfid(data & 1);
    data = data >> 1;                   // переходим к следующему bit
  }
}

void rfidGap(unsigned int tm){
  TCCR2A &=0b00111111;                //Оключить ШИМ COM2A 
  delayMicroseconds(tm);
  TCCR2A |= _BV(COM2A0);              // Включить ШИМ COM2A (pin 11)      
}

bool T5557_blockRead(byte* buf){
  byte ti; byte j = 0, k=0;
  for (int i = 0; i<33; i++){    // читаем стартовый 0 и 32 значащих bit
    ti = ttAComp(2000);
    if (ti == 2)  break;         //timeout
    if ( ( ti == 1 ) && ( i == 0)) { ti=2; break; }                             // если не находим стартовый 0 - это ошибка
    if (i > 0){     //начиная с 1-го бита пишем в буфер
      if (ti) bitSet(buf[(i-1) >> 3], 7-j);
        else bitClear(buf[(i-1) >> 3], 7-j);
      j++; if (j>7) j=0;
    }
  }
  if (ti == 2) return false;         //timeout
  return true;
}

bool sendOpT5557(byte opCode, unsigned long password = 0, byte lockBit = 0, unsigned long data = 0, byte blokAddr = 1){
  TxBitRfid(opCode >> 1); TxBitRfid(opCode & 1); // передаем код операции 10
  if (opCode == 0b00) return true;
  // password
  TxBitRfid(lockBit & 1);               // lockbit 0
  if (data != 0){
    for (byte i = 0; i<32; i++) {
      TxBitRfid((data>>(31-i)) & 1);
    }
  }
  TxBitRfid(blokAddr>>2); TxBitRfid(blokAddr>>1); TxBitRfid(blokAddr & 1);      // адрес блока для записи
  delay(4);                       // ждем пока пишутся данные
  return true;
}

bool write2rfidT5557(byte* buf){
  bool result; unsigned long data32;
  digitalWrite(R_Led, LOW);
  delay(6);
  for (byte k = 0; k<2; k++){                                       // send key data
    data32 = (unsigned long)buf[0 + (k<<2)]<<24 | (unsigned long)buf[1 + (k<<2)]<<16 | (unsigned long)buf[2 + (k<<2)]<<8 | (unsigned long)buf[3 + (k<<2)];
    rfidGap(30 * 8);                                                 //start gap
    sendOpT5557(0b10, 0, 0, data32, k+1);                            //передаем 32 бита ключа в blok k
    Serial.print('*'); delay(6);
  }
  delay(6);
  rfidGap(30 * 8);          //start gap
  sendOpT5557(0b00);
  result = readEM_Marie(addr);
  TCCR2A &=0b00111111;              //Оключить ШИМ COM2A (pin 11)
  for (byte i = 0; i < 8; i++)
    if (addr[i] != keyID[i]) { result = false; break; }
  if (!result){
    Serial.println(" The key copy faild");
    Sd_ErrorBeep();
  } else {
    Serial.println(" The key has copied successesfully");
    Sd_ReadOK();
    delay(1000);
  }
  digitalWrite(R_Led, HIGH);
  return result;  
}

emRWType getRfidRWtype(){
  unsigned long data32, data33; byte buf[4] = {0, 0, 0, 0}; 
  rfidACsetOn();            // включаем генератор 125кГц и компаратор
  delay(4);                //4мс запускается ключ
  rfidGap(30 * 8);          //start gap
  sendOpT5557(0b11, 0, 0, 0, 1); //переходим в режим чтения Vendor ID 
  if (!T5557_blockRead(buf)) return rwUnknown; 
  data32 = (unsigned long)buf[0]<<24 | (unsigned long)buf[1]<<16 | (unsigned long)buf[2]<<8 | (unsigned long)buf[3];
  delay(4);
  rfidGap(20 * 8);          //gap  
  data33 = 0b00000000000101001000000001000000 | (rfidUsePWD << 4);   //конфиг регистр 0b00000000000101001000000001000000
  sendOpT5557(0b10, 0, 0, data33, 0);   //передаем конфиг регистр
  delay(4);
  rfidGap(30 * 8);          //start gap
  sendOpT5557(0b11, 0, 0, 0, 1); //переходим в режим чтения Vendor ID 
  if (!T5557_blockRead(buf)) return rwUnknown; 
  data33 = (unsigned long)buf[0]<<24 | (unsigned long)buf[1]<<16 | (unsigned long)buf[2]<<8 | (unsigned long)buf[3];
  sendOpT5557(0b00, 0, 0, 0, 0);  // send Reset
  delay(6);
  if (data32 != data33) return rwUnknown;    
  Serial.print(" The rfid RW-key is T5557. Vendor ID is ");
  Serial.println(data32, HEX);
  return T5557;
}

bool write2rfid(){
  bool Check = true;
  if (searchEM_Marine(false)) {
    for (byte i = 0; i < 8; i++)
      if (addr[i] != keyID[i]) { Check = false; break; }  // сравниваем код для записи с тем, что уже записано в ключе.
    if (Check) {                                          // если коды совпадают, ничего писать не нужно
      digitalWrite(R_Led, LOW); 
      Serial.println(" it is the same key. Writing in not needed.");
      Sd_ErrorBeep();
      digitalWrite(R_Led, HIGH);
      delay(500);
      return false;
    }
  }
  emRWType rwType = getRfidRWtype(); // определяем тип T5557 (T5577) или EM4305
  if (rwType != rwUnknown) Serial.print("\n Burning rfid ID: ");
  //keyID[0] = 0xFF; keyID[1] = 0xA9; keyID[2] =  0x8A; keyID[3] = 0xA4; keyID[4] = 0x87; keyID[5] = 0x78; keyID[6] = 0x98; keyID[7] = 0x6A; // если у вас есть код какого-то ключа, можно прописать его тут
  switch (rwType){
    case T5557: return write2rfidT5557(keyID); break;                    //пишем T5557
    //case EM4305: return write2rfidEM4305(keyID); break;                  //пишем EM4305
    case rwUnknown: break;
  }
  return false;
}

void loop() {
  bool BtnClick, BtnPinSt  = digitalRead(BtnPin);
  if ((BtnPinSt == LOW) &&(preBtnPinSt!= LOW)) BtnClick = true;
    else BtnClick = false;
  preBtnPinSt = BtnPinSt;
  if ((Serial.read() == 't') || BtnClick) {                         // переключаель режима чтение/запись
    if (readflag == true) {
      writeflag = !writeflag;
      clearLed(); 
      if (writeflag) digitalWrite(R_Led, HIGH);
        else digitalWrite(G_Led, HIGH);
      Serial.print("Writeflag = "); Serial.println(writeflag);  
    } else Sd_ErrorBeep();
  }
  if (!writeflag){
    if (searchCyfral() || searchEM_Marine() || searchIbutton()){            // запускаем поиск cyfral, затем поиск EM_Marine, затем поиск dallas
      digitalWrite(G_Led, LOW);
      Sd_ReadOK();
      readflag = true;
      clearLed(); digitalWrite(G_Led, HIGH);
    } else {
      delay(100);   //ничего не нашлось - начинаем сначала
      return;
    } 
  }
  if (writeflag && readflag){
    if (keyType == keyEM_Marie) write2rfid();
      else write2iBtn();
  }
  delay(200);
}

//***************** звуки****************
void Sd_ReadOK() {  // звук ОК
  for (int i=400; i<6000; i=i*1.5) { tone(speakerPin, i); delay(20); }
  noTone(speakerPin);
}

void Sd_WriteStep(){  // звук "очередной шаг"
  for (int i=2500; i<6000; i=i*1.5) { tone(speakerPin, i); delay(10); }
  noTone(speakerPin);
}

void Sd_ErrorBeep() {  // звук "ERROR"
  for (int j=0; j <3; j++){
    for (int i=1000; i<2000; i=i*1.1) { tone(speakerPin, i); delay(10); }
    delay(50);
    for (int i=1000; i>500; i=i*1.9) { tone(speakerPin, i); delay(10); }
    delay(50);
  }
  noTone(speakerPin);
}

void Sd_StartOK(){   // звук "Успешное включение"
  tone(speakerPin, NOTE_A7); delay(100);
  tone(speakerPin, NOTE_G7); delay(100);
  tone(speakerPin, NOTE_E7); delay(100); 
  tone(speakerPin, NOTE_C7); delay(100);  
  tone(speakerPin, NOTE_D7); delay(100); 
  tone(speakerPin, NOTE_B7); delay(100); 
  tone(speakerPin, NOTE_F7); delay(100); 
  tone(speakerPin, NOTE_C7); delay(100);
  noTone(speakerPin); 
}
/*************************************************
 * Public Constants
 *************************************************/

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978

 

b707
Offline
Зарегистрирован: 26.05.2017

timurtanum - чтобы добавить в этот код "поддержку других домофонов", как вы выразились - надо иметь подробное описание протокола считывания и записи ключей этого формата. А фирмы, делающие домофоны, как-то не очень хотят делится этой информацией.

Поэтому энутзиасты собирают информацию по кусочкам и пытаются написать программы. Например в комментариях в вашем скетче упоминаются ключи форматов RW-1990.1, RW-1990.2, TM-2004, TM-01, T5557, Цифрал а также RFID формата EM-Marine

Только "обещать - не значит женится", не думаю. что этот код умеет работать со всеми этими ключами.

timurtanum
Offline
Зарегистрирован: 15.11.2014

Доброго времени суток . у вас есть возможность протестировать rfid метки которые уже записаны в программу ? мне просто интересно знать эта программа работает с rfid ьетками или нет .