SHARE
TWEET

Untitled

a guest Jan 20th, 2020 101 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.   Скетч к проекту "Копировальщик ключей для домофона RFID с OLED дисплеем и хранением 8 ключей в память EEPROM"
  3.   Аппаратная часть построена на Arduino Nano
  4.   Исходники на GitHub: https://github.com/AlexMalov/EasyKeyDublicatorRFID_OLED/
  5.   Автор: МЕХАТРОН DIY, AlexMalov, 2019
  6.   v 3.1
  7. */
  8.  
  9. // Настройки
  10. #include <OneWire.h>
  11. //#include <OneWireSlave.h>
  12. #include "pitches.h"
  13. #include <EEPROM.h>
  14. #include <OLED_I2C.h>
  15. OLED myOLED(SDA, SCL); //создаем экземпляр класса OLED с именем myOLED
  16. extern uint8_t SmallFont[];
  17. extern uint8_t BigNumbers[];
  18. #include "TimerOne.h"
  19. #include "DualFunctionButton.h"     //https://github.com/BerranRemzi/dual-function-button
  20.  
  21. //settings
  22. #define rfidUsePWD 0        // ключ использует пароль для изменения
  23. #define rfidPWD 123456      // пароль для ключа
  24. #define rfidBitRate 2       // Скорость обмена с rfid в kbps
  25.  
  26. //pins
  27. #define iButtonPin A3      // Линия data ibutton
  28. #define iBtnEmulPin A1     // Линия эмулятора ibutton
  29. #define Luse_Led 13        // Светодиод лузы
  30. #define R_Led 2            // RGB Led
  31. #define G_Led 3
  32. #define B_Led 4
  33. #define ACpin 6            // Вход Ain0 аналогового компаратора 0.1В для EM-Marie
  34. #define speakerPin 12       // Спикер, он же buzzer, он же beeper
  35. #define FreqGen 11         // генератор 125 кГц
  36. #define BtnOKPin 10        // Кнопка переключения режима чтение/запись
  37. #define BtnUpPin 8         // Кнопка вверх
  38. #define BtnDownPin 9       // Кнопка вниз
  39. DualFunctionButton BtnOK(BtnOKPin, 2000, INPUT_PULLUP);
  40. DualFunctionButton BtnErase(BtnOKPin, 5000, INPUT_PULLUP);
  41. DualFunctionButton BtnUp(BtnUpPin, 2000, INPUT_PULLUP);
  42. DualFunctionButton BtnDown(BtnDownPin, 2000, INPUT_PULLUP);
  43. char data[16];
  44. int data_count =0;
  45.  
  46. OneWire ibutton (iButtonPin);
  47. //OneWireSlave iBtnEmul(iBtnEmulPin);       //Эмулятор iButton для BlueMode
  48. byte maxKeyCount;                         // максимальное кол-во ключей, которое влазит в EEPROM, но не > 20
  49. byte EEPROM_key_count;                    // количество ключей 0..maxKeyCount, хранящихся в EEPROM
  50. byte EEPROM_key_index = 0;                // 1..EEPROM_key_count номер последнего записанного в EEPROM ключа  
  51. byte addr[8];                             // временный буфер
  52. byte keyID[8];                            // ID ключа для записи
  53. byte rfidData[5];                         // значащие данные frid em-marine
  54. byte halfT;                               // полупериод для метаком
  55. enum emRWType {rwUnknown, TM01, RW1990_1, RW1990_2, TM2004, T5557, EM4305};               // тип болванки
  56. enum emkeyType {keyUnknown, keyDallas, keyTM2004, keyCyfral, keyMetacom, keyEM_Marine};    // тип оригинального ключа  
  57. emkeyType keyType;
  58. enum emMode {md_empty, md_read, md_write, md_blueMode};               // режим раоты копировальщика
  59. emMode copierMode = md_empty;
  60.  
  61. void OLED_printKey(byte buf[8], byte msgType = 0){
  62.   String st;
  63.   switch (msgType){
  64.     case 0: st = "The key " + String(EEPROM_key_index) + " of " + String(EEPROM_key_count) + " in ROM"; break;      
  65.     case 1: st = "Hold the Btn to save";  break;
  66.     case 3: st = "The key " + String(indxKeyInROM(buf)) + " exists in ROM";  break;  
  67.   }
  68.   myOLED.clrScr();
  69.   myOLED.print(st, 0, 0);  
  70.   st = "";
  71.   for (byte i = 0; i < 8; i++) st += String(buf[i], HEX) +":";
  72.   myOLED.print(st, 0, 12);
  73.   st = "Type ";
  74.   switch (keyType){
  75.     case keyDallas: st += "Dallas wire"; break;      
  76.     case keyCyfral: st += "Cyfral wire";  break;  
  77.     case keyMetacom: st += "Metakom wire"; break;            
  78.     case keyEM_Marine: st += "EM_Marine rfid"; break;
  79.     case keyUnknown: st += "Unknown"; break;
  80.   }
  81.   myOLED.print(st, 0, 24);
  82.   myOLED.update();
  83. }
  84.  
  85. void OLED_printError(String st, bool err = true){
  86.   myOLED.clrScr();
  87.   if (err) myOLED.print("Error!", 0, 0);
  88.     else myOLED.print("OK", 0, 0);
  89.   myOLED.print(st, 0, 12);  
  90.   myOLED.update();
  91. }
  92.  
  93. void setup() {
  94.   pinMode(Luse_Led, OUTPUT); digitalWrite(Luse_Led, HIGH); //поменять на LOW
  95.   myOLED.begin(SSD1306_128X32); //инициализируем дисплей
  96.   pinMode(BtnOKPin, INPUT_PULLUP);                            // включаем чтение и подягиваем пин кнопки режима к +5В
  97.   pinMode(BtnUpPin, INPUT_PULLUP);
  98.   pinMode(BtnDownPin, INPUT_PULLUP);
  99.   pinMode(speakerPin, OUTPUT);
  100.   pinMode(ACpin, INPUT);                                    // Вход аналогового компаратора 3В для Cyfral
  101.   pinMode(R_Led, OUTPUT); pinMode(G_Led, OUTPUT); pinMode(B_Led, OUTPUT);  //RGB-led
  102.   clearLed();
  103.   pinMode(FreqGen, OUTPUT);                        
  104.   Serial.begin(115200);
  105.   myOLED.clrScr();                                          //Очищаем буфер дисплея.
  106.   myOLED.setFont(SmallFont);                                //Перед выводом текста необходимо выбрать шрифт
  107.   myOLED.print("Hello, read a key...", LEFT, 0);
  108.   char st[16] = {98, 121, 32, 77, 69, 88, 65, 84, 80, 79, 72, 32, 68, 73, 89, 0};
  109.   myOLED.print(st, LEFT, 24);
  110.   myOLED.update();
  111.   Sd_StartOK();
  112.   EEPROM_key_count = EEPROM[0];
  113.   maxKeyCount = EEPROM.length() / 8 - 1; if (maxKeyCount > 20) maxKeyCount = 20;
  114.   if (EEPROM_key_count > maxKeyCount) EEPROM_key_count = 0;
  115.   if (EEPROM_key_count != 0 ) {
  116.     EEPROM_key_index = EEPROM[1];
  117.     Serial.print("Read key code from EEPROM: ");
  118.     EEPROM_get_key(EEPROM_key_index, keyID);
  119.     for (byte i = 0; i < 8; i++) {
  120.       keyID[i] = keyID[i];
  121.       Serial.print(keyID[i], HEX); Serial.print(":");  
  122.     }
  123.     Serial.println();
  124.     delay(3000);
  125.     OLED_printKey(keyID);
  126.     copierMode = md_read;
  127.     digitalWrite(G_Led, HIGH);
  128.   } else {
  129.     myOLED.print("ROM has no keys yet.", 0, 12);
  130.     myOLED.update();  
  131.   }
  132. //  Timer1.initialize(1000);            // установка таймера на каждые 1000 микросекунд (= 1 мс)
  133. //  Timer1.attachInterrupt(timerIsr);   // запуск таймера
  134.   digitalWrite(Luse_Led, !digitalRead(Luse_Led));
  135. }
  136.  
  137. void clearLed(){
  138.   digitalWrite(R_Led, LOW);
  139.   digitalWrite(G_Led, LOW);
  140.   digitalWrite(B_Led, LOW);  
  141. }
  142.  
  143. byte indxKeyInROM(byte buf[]){ //возвращает индекс или ноль если нет в ROM
  144.   byte buf1[8]; bool eq = true;
  145.   for (byte j = 1; j<=EEPROM_key_count; j++){  // ищем ключ в eeprom.
  146.     EEPROM.get(j*sizeof(buf1), buf1);
  147.     for (byte i = 0; i < 8; i++)
  148.       if (buf1[i] != buf[i]) { eq = false; break;}
  149.     if (eq) return j;
  150.     eq = true;
  151.   }
  152.   return 0;
  153. }
  154.  
  155. bool EPPROM_AddKey(byte buf[]){
  156.   byte buf1[8]; byte indx;
  157.   indx = indxKeyInROM(buf);                 // ищем ключ в eeprom. Если находим, то не делаем запись, а индекс переводим в него
  158.   if ( indx != 0) {
  159.     EEPROM_key_index = indx;
  160.     EEPROM.update(1, EEPROM_key_index);
  161.     return false;
  162.   }
  163.   if (EEPROM_key_count <= maxKeyCount) EEPROM_key_count++;
  164.   if (EEPROM_key_count < maxKeyCount) EEPROM_key_index = EEPROM_key_count;
  165.     else EEPROM_key_index++;
  166.   if (EEPROM_key_index > EEPROM_key_count) EEPROM_key_index = 1;
  167.   Serial.println("Adding to EEPROM");
  168.   for (byte i = 0; i < 8; i++) {
  169.     buf1[i] = buf[i];
  170.     Serial.print(buf[i], HEX); Serial.print(":");  
  171.   }
  172.   Serial.println();
  173.   EEPROM.put(EEPROM_key_index*sizeof(buf1), buf1);
  174.   EEPROM.update(0, EEPROM_key_count);
  175.   EEPROM.update(1, EEPROM_key_index);
  176.   return true;
  177. }
  178.  
  179. void EEPROM_get_key(byte EEPROM_key_index1, byte buf[8]){
  180.   byte buf1[8];
  181.   int address = EEPROM_key_index1*sizeof(buf1);
  182.   if (address > EEPROM.length()) return;
  183.   EEPROM.get(address, buf1);
  184.   for (byte i = 0; i < 8; i++) buf[i] = buf1[i];
  185.   keyType = getKeyType(buf1);
  186. }
  187.  
  188. emkeyType getKeyType(byte* buf){
  189.   if (buf[0] == 0x01) return keyDallas;                       // это ключ формата dallas
  190.   if ((buf[0] >> 4) == 0b0001) return keyCyfral;
  191.   if ((buf[0] >> 4) == 0b0010) return keyMetacom;
  192.   if ((buf[0] == 0xFF) && vertEvenCheck(buf)) return keyEM_Marine;
  193.   return keyUnknown;
  194. }
  195.  
  196. //*************** dallas **************
  197. emRWType getRWtype(){    
  198.    byte answer;
  199.   // TM01 это неизвестный тип болванки, делается попытка записи TM-01 без финализации для dallas или c финализацией под cyfral или metacom
  200.   // RW1990_1 - dallas-совместимые RW-1990, RW-1990.1, ТМ-08, ТМ-08v2
  201.   // RW1990_2 - dallas-совместимая RW-1990.2
  202.   // TM2004 - dallas-совместимая TM2004 в доп. памятью 1кб
  203.   // пробуем определить RW-1990.1
  204.   ibutton.reset(); ibutton.write(0xD1); // проуем снять флаг записи для RW-1990.1
  205.   ibutton.write_bit(1);                 // записываем значение флага записи = 1 - отключаем запись
  206.   delay(10); pinMode(iButtonPin, INPUT);
  207.   ibutton.reset(); ibutton.write(0xB5); // send 0xB5 - запрос на чтение флага записи
  208.   answer = ibutton.read();
  209.   //Serial.print("\n Answer RW-1990.1: "); Serial.println(answer, HEX);
  210.   if (answer == 0xFE){
  211.     Serial.println(" Type: dallas RW-1990.1 ");
  212.     return RW1990_1;            // это RW-1990.1
  213.   }
  214.   // пробуем определить RW-1990.2
  215.   ibutton.reset(); ibutton.write(0x1D);  // пробуем установить флаг записи для RW-1990.2
  216.   ibutton.write_bit(1);                  // записываем значение флага записи = 1 - включаем запись
  217.   delay(10); pinMode(iButtonPin, INPUT);
  218.   ibutton.reset(); ibutton.write(0x1E);  // send 0x1E - запрос на чтение флага записи
  219.   answer = ibutton.read();
  220.   if (answer == 0xFE){
  221.     ibutton.reset(); ibutton.write(0x1D); // возвращаем оратно запрет записи для RW-1990.2
  222.     ibutton.write_bit(0);                 // записываем значение флага записи = 0 - выключаем запись
  223.     delay(10); pinMode(iButtonPin, INPUT);
  224.     Serial.println(" Type: dallas RW-1990.2 ");
  225.     return RW1990_2; // это RW-1990.2
  226.   }
  227.   // пробуем определить TM-2004
  228.   ibutton.reset(); ibutton.write(0x33);                     // посылаем команду чтения ROM для перевода в расширенный 3-х байтовый режим
  229.   for ( byte i=0; i<8; i++) ibutton.read();                 // читаем данные ключа
  230.   ibutton.write(0xAA);                                      // пробуем прочитать регистр статуса для TM-2004    
  231.   ibutton.write(0x00); ibutton.write(0x00);                 // передаем адрес для считывания
  232.   answer = ibutton.read();                                  // читаем CRC комманды и адреса
  233.   byte m1[3] = {0xAA, 0,0};                                 // вычисляем CRC комманды
  234.   if (OneWire::crc8(m1, 3) == answer) {
  235.     answer = ibutton.read();                                  // читаем регистр статуса
  236.     //Serial.print(" status: "); Serial.println(answer, HEX);
  237.     Serial.println(" Type: dallas TM2004");
  238.     ibutton.reset();
  239.     return TM2004; // это Type: TM2004
  240.   }
  241.   ibutton.reset();
  242.   Serial.println(" Type: dallas unknown, trying TM-01! ");
  243.   return TM01;                              // это неизвестный тип DS1990, нужно перебирать алгоритмы записи (TM-01)
  244. }
  245.  
  246. bool write2iBtnTM2004(){                // функция записи на TM2004
  247.   byte answer; bool result = true;
  248.   ibutton.reset();
  249.   ibutton.write(0x3C);                                      // команда записи ROM для TM-2004    
  250.   ibutton.write(0x00); ibutton.write(0x00);                 // передаем адрес с которого начинается запись
  251.   for (byte i = 0; i<8; i++){
  252.     digitalWrite(R_Led, !digitalRead(R_Led));
  253.     ibutton.write(keyID[i]);
  254.     answer = ibutton.read();
  255.     //if (OneWire::crc8(m1, 3) != answer){result = false; break;}     // crc не верный
  256.     delayMicroseconds(600); ibutton.write_bit(1); delay(50);         // испульс записи
  257.     pinMode(iButtonPin, INPUT);
  258.     Serial.print('*');
  259.     Sd_WriteStep();
  260.     if (keyID[i] != ibutton.read()) { result = false; break;}    //читаем записанный байт и сравниваем, с тем что должно записаться
  261.   }
  262.   if (!result){
  263.     ibutton.reset();
  264.     Serial.println(" The key copy faild");
  265.     OLED_printError("The key copy faild");
  266.     Sd_ErrorBeep();
  267.     digitalWrite(R_Led, HIGH);
  268.     return false;    
  269.   }
  270.   ibutton.reset();
  271.   Serial.println(" The key has copied successesfully");
  272.   OLED_printError("The key has copied", false);
  273.   Sd_ReadOK();
  274.   delay(2000);
  275.   digitalWrite(R_Led, HIGH);
  276.   return true;
  277. }
  278.  
  279. bool write2iBtnRW1990_1_2_TM01(emRWType rwType){              // функция записи на RW1990.1, RW1990.2, TM-01C(F)
  280.   byte rwCmd, bitCnt = 64, rwFlag = 1;
  281.   switch (rwType){
  282.     case TM01: rwCmd = 0xC1; if ((keyType == keyMetacom)||(keyType == keyCyfral)) bitCnt = 36; break;                   //TM-01C(F)
  283.     case RW1990_1: rwCmd = 0xD1; rwFlag = 0; break;  // RW1990.1  флаг записи инвертирован
  284.     case RW1990_2: rwCmd = 0x1D; break;              // RW1990.2
  285.   }
  286.   ibutton.reset(); ibutton.write(rwCmd);       // send 0xD1 - флаг записи
  287.   ibutton.write_bit(rwFlag);                   // записываем значение флага записи = 1 - разрешить запись
  288.   delay(5); pinMode(iButtonPin, INPUT);
  289.   ibutton.reset();
  290.   if (rwType == TM01) ibutton.write(0xC5);
  291.     else ibutton.write(0xD5);        // команда на запись
  292.   if (bitCnt == 36) BurnByteMC(keyID);
  293.   else for (byte i = 0; i< (bitCnt >> 3); i++){
  294.     digitalWrite(R_Led, !digitalRead(R_Led));
  295.     if (rwType == RW1990_1) BurnByte(~keyID[i]);      // запись происходит инверсно для RW1990.1
  296.       else BurnByte(keyID[i]);
  297.     Serial.print('*');
  298.     Sd_WriteStep();
  299.   }
  300.   if (bitCnt == 64) {
  301.       ibutton.write(rwCmd);                     // send 0xD1 - флаг записи
  302.       ibutton.write_bit(!rwFlag);               // записываем значение флага записи = 1 - отключаем запись
  303.       delay(5); pinMode(iButtonPin, INPUT);
  304.     }
  305.   digitalWrite(R_Led, LOW);      
  306.   if (!dataIsBurningOK(bitCnt)){                  // проверяем корректность записи
  307.     Serial.println(" The key copy faild");
  308.     OLED_printError("The key copy faild");
  309.     Sd_ErrorBeep();
  310.     digitalWrite(R_Led, HIGH);
  311.     return false;
  312.   }
  313.   Serial.println(" The key has copied successesfully");
  314.   if ((keyType == keyMetacom)||(keyType == keyCyfral)){      //переводим ключ из формата dallas
  315.     ibutton.reset();
  316.     if (keyType == keyCyfral) ibutton.write(0xCA);       // send 0xCA - флаг финализации Cyfral
  317.       else ibutton.write(0xCB);                       // send 0xCB - флаг финализации metacom
  318.     ibutton.write_bit(1);                             // записываем значение флага финализации = 1 - перевезти формат
  319.     delay(10); pinMode(iButtonPin, INPUT);
  320.   }
  321.   OLED_printError("The key has copied", false);
  322.   Sd_ReadOK();
  323.   delay(2000);
  324.   digitalWrite(R_Led, HIGH);
  325.   return true;
  326. }
  327.  
  328. void BurnByte(byte data){
  329.   for(byte n_bit = 0; n_bit < 8; n_bit++){
  330.     ibutton.write_bit(data & 1);  
  331.     delay(5);                        // даем время на прошивку каждого бита до 10 мс
  332.     data = data >> 1;                // переходим к следующему bit
  333.   }
  334.   pinMode(iButtonPin, INPUT);
  335. }
  336.  
  337. void BurnByteMC(byte buf[8]){
  338.   byte j = 0;
  339.   for(byte n_bit = 0; n_bit < 36; n_bit++){
  340.     ibutton.write_bit(((~buf[n_bit>>3]) >> (7-j) ) & 1);  
  341.     delay(5);                        // даем время на прошивку каждого бита 5 мс
  342.     j++;
  343.     if (j > 7) j = 0;
  344.   }
  345.   pinMode(iButtonPin, INPUT);
  346. }
  347.  
  348. void convetr2MC(byte buff[8]){
  349.   byte data;
  350.   for (byte i = 0; i < 5; i++){
  351.     data = ~buff[i];
  352.     buff[i] = 0;
  353.     for (byte j = 0; j < 8; j++)
  354.       if ( (data>>j)&1) bitSet(buff[i], 7-j);
  355.   }
  356.   buff[4] &= 0xf0;  buff[5] = 0; buff[6] = 0; buff[7] = 0;
  357. }
  358.  
  359. bool dataIsBurningOK(byte bitCnt){
  360.   byte buff[8];
  361.   if (!ibutton.reset()) return false;
  362.   ibutton.write(0x33);
  363.   ibutton.read_bytes(buff, 8);
  364.   if (bitCnt == 36) convetr2MC(buff);
  365.   byte Check = 0;
  366.   for (byte i = 0; i < 8; i++){
  367.     if (keyID[i] == buff[i]) Check++;       // сравниваем код для записи с тем, что уже записано в ключе.
  368.     Serial.print(buff[i], HEX); Serial.print(":");
  369.   }
  370.   if (Check != 8) return false;             // если коды совпадают, ключ успешно скопирован
  371.   return true;
  372. }
  373.  
  374. bool write2iBtn(){
  375.   int Check = 0;
  376.   if (!ibutton.search(addr)) {
  377.     ibutton.reset_search();
  378.     return false;
  379.   }
  380.   Serial.print("The new key code is: ");
  381.   for (byte i = 0; i < 8; i++) {
  382.     Serial.print(addr[i], HEX); Serial.print(":");  
  383.     if (keyID[i] == addr[i]) Check++;         // сравниваем код для записи с тем, что уже записано в ключе.
  384.   }
  385.   if (Check == 8) {                           // если коды совпадают, ничего писать не нужно
  386.     digitalWrite(R_Led, LOW);
  387.     Serial.println(" it is the same key. Writing in not needed.");
  388.     OLED_printError("It is the same key");
  389.     Sd_ErrorBeep();
  390.     digitalWrite(R_Led, HIGH);
  391.     delay(1000);
  392.     return false;
  393.   }
  394.   emRWType rwType = getRWtype();                    // определяем тип RW-1990.1 или 1990.2 или TM-01
  395.   Serial.print("\n Burning iButton ID: ");
  396.   //keyID[0] = 0xFF; keyID[1] = 0xA9; keyID[2] =  0x8A; keyID[3] = 0xA4; keyID[4] = 0x87; keyID[5] = 0x78; keyID[6] = 0x98; keyID[7] = 0x6A; // если у вас есть код какого-то iButton ключа, можно прописать его тут
  397.  
  398.   if (rwType == TM2004) return write2iBtnTM2004();  //шьем TM2004
  399.     else return write2iBtnRW1990_1_2_TM01(rwType);  //пробуем прошить другие форматы
  400. }
  401.  
  402. bool searchIbutton(){
  403.   if (!ibutton.search(addr)) {
  404.     ibutton.reset_search();
  405.     return false;
  406.   }  
  407.   for (byte i = 0; i < 8; i++) {
  408.     Serial.print(addr[i], HEX); Serial.print(":");
  409.     keyID[i] = addr[i];                               // копируем прочтенный код в ReadID
  410.   }
  411.   if (addr[0] == 0x01) {                              // это ключ формата dallas
  412.     keyType = keyDallas;
  413.     if (getRWtype() == TM2004) keyType = keyTM2004;
  414.     if (OneWire::crc8(addr, 7) != addr[7]) {
  415.       Serial.println("CRC is not valid!");
  416.       OLED_printError("CRC is not valid!");
  417.       Sd_ErrorBeep();
  418.       digitalWrite(B_Led, HIGH);
  419.       return false;
  420.     }
  421.     return true;
  422.   }
  423.   if(addr[0]>>4 == 1) Serial.println(" Type: May be cyfral in dallas key");
  424.   //if(addr[0]>>4 == 2) Serial.println(" Type: May be metacom in dallas key");
  425.   if(addr[0]>>4 >= 3) Serial.println(" Type: unknown family dallas");
  426.   keyType = keyUnknown;
  427.   return true;
  428. }
  429.  
  430. //************ Cyfral ***********************
  431. unsigned long pulseACompA(bool pulse, byte Average = 80, unsigned long timeOut = 1500){  // pulse HIGH or LOW
  432.   bool AcompState;
  433.   unsigned long tEnd = micros() + timeOut;
  434.   do {
  435.     ADCSRA |= (1<<ADSC);
  436.     while(ADCSRA & (1 << ADSC)); // Wait until the ADSC bit has been cleared
  437.     if (ADCH > 200) return 0;
  438.     if (ADCH > Average) AcompState = HIGH;  // читаем флаг компаратора
  439.       else AcompState = LOW;
  440.     if (AcompState == pulse) {
  441.       tEnd = micros() + timeOut;
  442.       do {
  443.           ADCSRA |= (1<<ADSC);
  444.           while(ADCSRA & (1 << ADSC)); // Wait until the ADSC bit has been cleared
  445.         if (ADCH > Average) AcompState = HIGH;  // читаем флаг компаратора
  446.           else AcompState = LOW;
  447.         if (AcompState != pulse) return (unsigned long)(micros() + timeOut - tEnd);  
  448.       } while (micros() < tEnd);
  449.       return 0;                                                 //таймаут, импульс не вернуся оратно
  450.     }             // end if
  451.   } while (micros() < tEnd);
  452.   return 0;
  453. }
  454.  
  455. void ADCsetOn(){
  456.   ADMUX = (ADMUX&0b11110000) | 0b0011 | (1<<ADLAR);// (1 << REFS0);          // подключаем к AC Линию A3 ,  левое выравние, измерение до Vcc
  457.   ADCSRB = (ADCSRB & 0b11111000) | (1<<ACME);                // источник перезапуска ADC FreeRun, включаем мультиплексор AC
  458.   ADCSRA = (ADCSRA & 0b11111000) |0b011 | (1<<ADEN) | (1<<ADSC);// | (1<<ADATE);      // 0b011 делитель скорости ADC, // включаем ADC и запускаем ADC и autotriger ADC
  459. }
  460.  
  461. void ACsetOn(){
  462.   ACSR |= 1<<ACBG;                            // Подключаем ко входу Ain0 1.1V для Cyfral/Metacom
  463.   ADCSRA &= ~(1<<ADEN);                       // выключаем ADC
  464.   ADMUX = (ADMUX&0b11110000) | 0b0011;        // подключаем к AC Линию A3
  465.   ADCSRB |= 1<<ACME;                          // включаем мультиплексор AC
  466. }
  467.  
  468. bool read_cyfral(byte* buf, byte CyfralPin){
  469.   unsigned long ti; byte i=0, j = 0, k = 0;
  470.   analogRead(iButtonPin);
  471.   ADCsetOn();
  472.   byte aver = calcAverage();
  473.   unsigned long tEnd = millis() + 30;
  474.   do{
  475.     ti = pulseACompA(HIGH, aver);
  476.     if ((ti == 0) || (ti > 250)) {i = 0; j=0; k = 0; continue;}
  477.     if ((i < 3) && (ti < halfT)) {i = 0; j = 0; k = 0; continue;}      //контроль стартовой последовательности 0b0001
  478.     if ((i == 3) && (ti > halfT)) {i = 0; j = 0; k = 0; continue;}      
  479.     if (ti < halfT) bitSet(buf[i >> 3], 7-j);
  480.       else if (i > 3) k++;
  481.     if ((i > 3) && ((i-3)%4 == 0) ){        //начиная с 4-го бита проверяем количество нулей каждой строки из 4-и бит
  482.       if (k > 1) {i = 0; j = 0; k = 0; continue;}              //если еддиниц больше одной - начинаем сначала
  483.       k = 0;
  484.     }
  485.     j++; if (j>7) j=0;
  486.     i++;
  487.   } while ((millis() < tEnd) && (i < 36));
  488.   if (i < 36) return false;
  489.   return true;
  490. }
  491.  
  492. bool searchCyfral(){
  493.   byte buf[8];
  494.   for (byte i = 0; i < 8; i++) {addr[i] =0; buf[i] = 0;}
  495.   if (!read_cyfral(addr, iButtonPin)) return false;
  496.   if (!read_cyfral(buf, iButtonPin)) return false;
  497.   for (byte i = 0; i < 8; i++)
  498.     if (addr[i] != buf[i]) return false;  
  499.   keyType = keyCyfral;
  500.   for (byte i = 0; i < 8; i++) {
  501.     Serial.print(addr[i], HEX); Serial.print(":");
  502.     keyID[i] = addr[i];                                         // копируем прочтенный код в ReadID
  503.   }
  504.   Serial.println(" Type: Cyfral ");
  505.   return true;  
  506. }
  507.  
  508. byte calcAverage(){
  509.   unsigned int sum = 127; byte preADCH = 0, j = 0;
  510.   for (byte i = 0; i<255; i++) {
  511.     ADCSRA |= (1<<ADSC);
  512.     delayMicroseconds(10);
  513.     while(ADCSRA & (1 << ADSC)); // Wait until the ADSC bit has been cleared
  514.     sum += ADCH;
  515.   }
  516.   sum = sum >> 8;
  517.   unsigned long tSt = micros();
  518.   for (byte i = 0; i<255; i++) {
  519.     delayMicroseconds(4);
  520.     ADCSRA |= (1<<ADSC);
  521.     while(ADCSRA & (1 << ADSC)); // Wait until the ADSC bit has been cleared
  522.     if (((ADCH > sum)&&(preADCH < sum)) | ((ADCH < sum)&&(preADCH > sum))) j++;
  523.     preADCH = ADCH;
  524.   }
  525.   halfT = byte((micros() - tSt) / j);
  526.   return (byte)sum;
  527. }
  528.  
  529. bool read_metacom(byte* buf, byte MetacomPin){
  530.   unsigned long ti; byte i = 0, j = 0, k = 0;
  531.   analogRead(iButtonPin);
  532.   ADCsetOn();
  533.   byte aver = calcAverage();
  534.   unsigned long tEnd = millis() + 30;
  535.   do{
  536.     ti = pulseACompA(LOW, aver);
  537.     if ((ti == 0) || (ti > 500)) {i = 0; j=0; k = 0; continue;}
  538.     if ((i == 0) && (ti+30 < (halfT<<1))) {i = 0; j = 0;  k = 0; continue;}      //вычисляем период;
  539.     if ((i == 2) && (ti > halfT)) {i = 0; j = 0;  k = 0; continue;}      //вычисляем период;
  540.     if (((i == 1) || (i == 3)) && (ti < halfT)) {i = 0; j = 0;  k = 0; continue;}      //вычисляем период;
  541.     if (ti < halfT) {  
  542.       bitSet(buf[i >> 3], 7-j);
  543.       if (i > 3) k++;                             // считаем кол-во единиц
  544.     }
  545.     if ((i > 3) && ((i-3)%8 == 0) ){        //начиная с 4-го бита проверяем контроль четности каждой строки из 8-и бит
  546.       if (k & 1) {i = 0; j = 0;  k = 0; continue;}              //если нечетно - начинаем сначала
  547.       k = 0;
  548.     }  
  549.     j++; if (j>7) j=0;
  550.     i++;
  551.   }  while ((millis() < tEnd) && (i < 36));
  552.   if (i < 36) return false;
  553.   return true;
  554. }
  555.  
  556. bool searchMetacom(){
  557.   byte buf[8];
  558.   for (byte i = 0; i < 8; i++) {addr[i] =0; buf[i] = 0;}
  559.   if (!read_metacom(addr, iButtonPin)) return false;
  560.   if (!read_metacom(buf, iButtonPin)) return false;
  561.   for (byte i = 0; i < 8; i++)
  562.     if (addr[i] != buf[i]) return false;
  563.   keyType = keyMetacom;
  564.   for (byte i = 0; i < 8; i++) {
  565.     Serial.print(addr[i], HEX); Serial.print(":");
  566.     keyID[i] = addr[i];                               // копируем прочтенный код в ReadID
  567.   }
  568.   Serial.println(" Type: Metacom ");
  569.   return true;  
  570. }
  571.  
  572. void readAnalog(){
  573.   byte buf[255][2];
  574.   analogRead(iButtonPin);
  575.   digitalWrite(iButtonPin, LOW); pinMode(iButtonPin, OUTPUT);  //отклчаем питание от ключа
  576.   delay(1000);
  577.   ADCsetOn();
  578.   pinMode(iButtonPin, INPUT);                                   // включаем пиание Metacom
  579.   unsigned long ti = micros();
  580.   for (byte i = 0; i < 255; i++){
  581.     ADCSRA |= (1<<ADSC);
  582.     while(ADCSRA & (1 << ADSC)); // Wait until the ADSC bit has been cleared
  583.     buf[i][0] = ADCH;
  584.     buf[i][1] = (byte) ((micros() - ti)>>1);
  585.   }
  586.   for (byte i = 0; i < 255; i++){
  587.     Serial.print(buf[i][0]); Serial.print(" "); Serial.println(buf[i][1]);
  588.   }
  589. }
  590.  
  591. void resetMetacomCyfral(bool rsMc = true){
  592.  
  593. }
  594.  
  595. //**********EM-Marine***************************
  596. bool vertEvenCheck(byte* buf){        // проверка четности столбцов с данными
  597.   byte k;
  598.   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;
  599.   if (k&1) return false;
  600.   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;
  601.   if (k&1) return false;
  602.   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;
  603.   if (k&1) return false;
  604.   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;
  605.   if (k&1) return false;
  606.   if (1&buf[7]) return false;
  607.   //номер ключа, который написан на корпусе
  608.   rfidData[0] = (0b01111000&buf[1])<<1 | (0b11&buf[1])<<2 | buf[2]>>6;
  609.   rfidData[1] = (0b00011110&buf[2])<<3 | buf[3]>>4;
  610.   rfidData[2] = buf[3]<<5 | (0b10000000&buf[4])>>3 | (0b00111100&buf[4])>>2;
  611.   rfidData[3] = buf[4]<<7 | (0b11100000&buf[5])>>1 | 0b1111&buf[5];
  612.   rfidData[4] = (0b01111000&buf[6])<<1 | (0b11&buf[6])<<2 | buf[7]>>6;
  613.   return true;
  614. }
  615.  
  616. byte ttAComp(unsigned long timeOut = 7000){  // pulse 0 or 1 or -1 if timeout
  617.   byte AcompState, AcompInitState;
  618.   unsigned long tEnd = micros() + timeOut;
  619.   AcompInitState = (ACSR >> ACO)&1;               // читаем флаг компаратора
  620.   do {
  621.     AcompState = (ACSR >> ACO)&1;                 // читаем флаг компаратора
  622.     if (AcompState != AcompInitState) {
  623.       delayMicroseconds(1000/(rfidBitRate*4));    // 1/4 Period on 2 kBps = 125 mks
  624.       AcompState = (ACSR >> ACO)&1;               // читаем флаг компаратора      
  625.       delayMicroseconds(1000/(rfidBitRate*2));    // 1/2 Period on 2 kBps = 250 mks
  626.       return AcompState;  
  627.     }
  628.   } while (micros() < tEnd);
  629.   return 2;                                             //таймаут, компаратор не сменил состояние
  630. }
  631.  
  632. bool readEM_Marie(byte* buf){
  633.   unsigned long tEnd = millis() + 50;
  634.   byte ti; byte j = 0, k=0;
  635.   for (int i = 0; i<64; i++){    // читаем 64 bit
  636.     ti = ttAComp();
  637.     if (ti == 2)  break;         //timeout
  638.     if ( ( ti == 0 ) && ( i < 9)) {  // если не находим 9 стартовых единиц - начинаем сначала
  639.       if (millis() > tEnd) { ti=2; break;}  //timeout
  640.       i = -1; j=0; continue;
  641.     }
  642.     if ((i > 8) && (i < 59)){     //начиная с 9-го бита проверяем контроль четности каждой строки
  643.       if (ti) k++;                // считаем кол-во единиц
  644.       if ( (i-9)%5 == 4 ){        // конец строки с данными из 5-и бит,
  645.         if (k & 1) {              //если нечетно - начинаем сначала
  646.           i = -1; j = 0; k = 0; continue;
  647.         }
  648.         k = 0;
  649.       }
  650.     }
  651.     if (ti) bitSet(buf[i >> 3], 7-j);
  652.       else bitClear(buf[i >> 3], 7-j);
  653.     j++; if (j>7) j=0;
  654.   }
  655.   if (ti == 2) return false;         //timeout
  656.   return vertEvenCheck(buf);
  657. }
  658.  
  659. void rfidACsetOn(){
  660.   //включаем генератор 125кГц
  661.   pinMode(FreqGen, OUTPUT);
  662.   TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);  //Вкючаем режим Toggle on Compare Match на COM2A (pin 11) и счет таймера2 до OCR2A
  663.   TCCR2B = _BV(WGM22) | _BV(CS20);                                // Задаем делитель для таймера2 = 1 (16 мГц)
  664.   OCR2A = 63;                                                    // 63 тактов на период. Частота на COM2A (pin 11) 16000/64/2 = 125 кГц, Скважнось COM2A в этом режиме всегда 50%
  665.   OCR2B = 31;                                                     // Скважность COM2B 32/64 = 50%  Частота на COM2A (pin 3) 16000/64 = 250 кГц
  666.   // включаем компаратор
  667.   ADCSRB &= ~(1<<ACME);           // отключаем мультиплексор AC
  668.   ACSR &= ~(1<<ACBG);             // отключаем от входа Ain0 1.1V
  669. }
  670.  
  671. bool searchEM_Marine( bool copyKey = true){
  672.   byte gr = digitalRead(G_Led);
  673.   bool rez = false;
  674.   rfidACsetOn();            // включаем генератор 125кГц и компаратор
  675.   delay(6);                //13 мс длятся переходные прцессы детектора
  676.   if (!readEM_Marie(addr)) {
  677.     if (!copyKey) TCCR2A &=0b00111111;              //Оключить ШИМ COM2A (pin 11)
  678.     digitalWrite(G_Led, gr);
  679.     return rez;
  680.   }
  681.   rez = true;
  682.   keyType = keyEM_Marine;
  683.   for (byte i = 0; i<8; i++){
  684.     if (copyKey) keyID[i] = addr [i];
  685.     Serial.print(addr[i], HEX); Serial.print(":");
  686.   }
  687.   Serial.print(" ( id ");
  688.   Serial.print(rfidData[0]); Serial.print(" key ");
  689.   unsigned long keyNum = (unsigned long)rfidData[1]<<24 | (unsigned long)rfidData[2]<<16 | (unsigned long)rfidData[3]<<8 | (unsigned long)rfidData[4];
  690.   Serial.print(keyNum);
  691.   Serial.println(") Type: EM-Marie ");
  692.   //////выводим HEX значение ключа
  693.   for(byte b=0; b<5; b++)
  694.    {
  695.       if (rfidData[b]<10) {Serial.print(0);}
  696.       Serial.print(rfidData[b], HEX); Serial.print(":");
  697.    }
  698.   Serial.println("");
  699.   ////////////////////
  700.   if (!copyKey) TCCR2A &=0b00111111;              //Оключить ШИМ COM2A (pin 11)
  701.   digitalWrite(G_Led, gr);
  702.   return rez;
  703. }
  704.  
  705. void TxBitRfid(byte data){
  706.   if (data & 1) delayMicroseconds(54*8);
  707.     else delayMicroseconds(24*8);
  708.   rfidGap(19*8);                       //write gap
  709. }
  710.  
  711. void TxByteRfid(byte data){
  712.   for(byte n_bit=0; n_bit<8; n_bit++){
  713.     TxBitRfid(data & 1);
  714.     data = data >> 1;                   // переходим к следующему bit
  715.   }
  716. }
  717.  
  718. void rfidGap(unsigned int tm){
  719.   TCCR2A &=0b00111111;                //Оключить ШИМ COM2A
  720.   delayMicroseconds(tm);
  721.   TCCR2A |= _BV(COM2A0);              // Включить ШИМ COM2A (pin 11)      
  722. }
  723.  
  724. bool T5557_blockRead(byte* buf){
  725.   byte ti; byte j = 0, k=0;
  726.   for (int i = 0; i<33; i++){                           // читаем стартовый 0 и 32 значащих bit
  727.     ti = ttAComp(2000);
  728.     if (ti == 2)  break;                                //timeout
  729.     if ( ( ti == 1 ) && ( i == 0)) { ti=2; break; }     // если не находим стартовый 0 - это ошибка
  730.     if (i > 0){                                         //начиная с 1-го бита пишем в буфер
  731.       if (ti) bitSet(buf[(i-1) >> 3], 7-j);
  732.         else bitClear(buf[(i-1) >> 3], 7-j);
  733.       j++; if (j>7) j=0;
  734.     }
  735.   }
  736.   if (ti == 2) return false;                           //timeout
  737.   return true;
  738. }
  739.  
  740. bool sendOpT5557(byte opCode, unsigned long password = 0, byte lockBit = 0, unsigned long data = 0, byte blokAddr = 1){
  741.   TxBitRfid(opCode >> 1); TxBitRfid(opCode & 1); // передаем код операции 10
  742.   if (opCode == 0b00) return true;
  743.   // password
  744.   TxBitRfid(lockBit & 1);               // lockbit 0
  745.   if (data != 0){
  746.     for (byte i = 0; i<32; i++) {
  747.       TxBitRfid((data>>(31-i)) & 1);
  748.     }
  749.   }
  750.   TxBitRfid(blokAddr>>2); TxBitRfid(blokAddr>>1); TxBitRfid(blokAddr & 1);      // адрес блока для записи
  751.   delay(4);                                                                     // ждем пока пишутся данные
  752.   return true;
  753. }
  754.  
  755. bool write2rfidT5557(byte* buf){
  756.   bool result; unsigned long data32;
  757.   delay(6);
  758.   Serial.print('1');
  759.   for (byte k = 0; k<2; k++){                                       // send key data
  760.     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)];
  761.     rfidGap(30 * 8);                                                 //start gap
  762.     sendOpT5557(0b10, 0, 0, data32, k+1);                            //передаем 32 бита ключа в blok k
  763.     Serial.print(data32, BIN);
  764.     Serial.print('*'); delay(6);
  765.   }
  766.   Serial.print('2');
  767.   delay(6);
  768.   rfidGap(30 * 8);                  //start gap
  769.   sendOpT5557(0b00);
  770.   delay(4);
  771.   Serial.print('3');
  772.   result = readEM_Marie(addr);
  773.   TCCR2A &=0b00111111;              //Оключить ШИМ COM2A (pin 11)
  774.   for (byte i = 0; i < 8; i++)
  775.     if (addr[i] != keyID[i]) { result = false; break;
  776.     Serial.print('4');}
  777.    Serial.print('5');
  778.   if (!result){
  779.     Serial.println(" The key copy faild");
  780.     OLED_printError("The key copy faild");
  781.     Sd_ErrorBeep();
  782.   } else {
  783.     Serial.println(" The key has copied successesfully");
  784.     OLED_printError("The key has copied", false);
  785.     Sd_ReadOK();
  786.     delay(2000);
  787.   }
  788.   Serial.print('6');
  789.   digitalWrite(R_Led, HIGH);
  790.   return result;  
  791. }
  792.  
  793. emRWType getRfidRWtype(){
  794.   unsigned long data32, data33; byte buf[4] = {0, 0, 0, 0};
  795.   rfidACsetOn();                // включаем генератор 125кГц и компаратор
  796.   delay(13);                    //13 мс длятся переходные процессы детектора
  797.   rfidGap(30 * 8);              //start gap
  798.   sendOpT5557(0b11, 0, 0, 0, 1); //переходим в режим чтения Vendor ID
  799.   if (!T5557_blockRead(buf)) return rwUnknown;
  800.   data32 = (unsigned long)buf[0]<<24 | (unsigned long)buf[1]<<16 | (unsigned long)buf[2]<<8 | (unsigned long)buf[3];
  801.   delay(4);
  802.   rfidGap(20 * 8);          //gap  
  803.   data33 = 0b00000000000101001000000001000000 | (rfidUsePWD << 4);   //конфиг регистр 0b00000000000101001000000001000000
  804.   sendOpT5557(0b10, 0, 0, data33, 0);   //передаем конфиг регистр
  805.   delay(4);
  806.   rfidGap(30 * 8);          //start gap
  807.   sendOpT5557(0b11, 0, 0, 0, 1); //переходим в режим чтения Vendor ID
  808.   if (!T5557_blockRead(buf)) return rwUnknown;
  809.   data33 = (unsigned long)buf[0]<<24 | (unsigned long)buf[1]<<16 | (unsigned long)buf[2]<<8 | (unsigned long)buf[3];
  810.   sendOpT5557(0b00, 0, 0, 0, 0);  // send Reset
  811.   delay(6);
  812.   if (data32 != data33) return rwUnknown;    
  813.   Serial.print(" The rfid RW-key is T5557. Vendor ID is ");
  814.   Serial.println(data32, HEX);
  815.   return T5557;
  816. }
  817.  
  818. bool write2rfid(){
  819.   bool Check = true;
  820.   if (searchEM_Marine(false)) {
  821.     for (byte i = 0; i < 8; i++)
  822.       if (addr[i] != keyID[i]) { Check = false; break; }  // сравниваем код для записи с тем, что уже записано в ключе.
  823.     if (Check) {                                          // если коды совпадают, ничего писать не нужно
  824.       digitalWrite(R_Led, LOW);
  825.       Serial.println(" it is the same key. Writing in not needed.");
  826.       OLED_printError("It is the same key");
  827.       Sd_ErrorBeep();
  828.       digitalWrite(R_Led, HIGH);
  829.       delay(1000);
  830.       return false;
  831.     }
  832.   }
  833.   emRWType rwType = getRfidRWtype(); // определяем тип T5557 (T5577) или EM4305
  834.   if (rwType != rwUnknown) Serial.print("\n Burning rfid ID: ");
  835.   switch (rwType){
  836.     case T5557: return write2rfidT5557(keyID); break;                    //пишем T5557
  837.     //case EM4305: return write2rfidEM4305(keyID); break;                  //пишем EM4305
  838.     case rwUnknown: break;
  839.   }
  840.   return false;
  841. }
  842.  
  843.  
  844. void SendEM_Marine(byte* buf){
  845.   byte bt; unsigned long tStart;
  846.   TCCR2A &=0b00111111; // отключаем шим
  847.   digitalWrite(FreqGen, LOW);
  848.   //FF:A9:8A:A4:87:78:98:6A
  849.   delay(10);
  850.   for (byte k = 0; k<10; k++){
  851.     for (byte i = 0; i<8; i++){
  852.       for (byte j = 0; j<8; j++){
  853.         bt = 1 & (buf[i]>>(7-j));
  854.         if (!bt) {
  855.           pinMode(FreqGen, OUTPUT);
  856.           tStart = micros();
  857.           do {
  858.             digitalWrite(FreqGen, !digitalRead(FreqGen));  
  859.           } while ((long)(micros() - tStart) < 250);
  860.           pinMode(FreqGen, INPUT);
  861.           delayMicroseconds(250);
  862.         } else {
  863.           pinMode(FreqGen, INPUT);
  864.           delayMicroseconds(250);
  865.           pinMode(FreqGen, OUTPUT);
  866.           tStart = micros();
  867.           do {
  868.             digitalWrite(FreqGen, !digitalRead(FreqGen));  
  869.           } while ((long)(micros() - tStart) < 250);
  870.  
  871.         }
  872.       }
  873.     }
  874.    // delay(1);
  875.   }  
  876. }
  877.  
  878. void SendDallas(byte* buf){
  879. /*  iBtnEmul.init(buf);
  880.   //iBtnEmul.waitForRequest(false);
  881.   unsigned long tStart = millis();
  882.   do {
  883.     if (!iBtnEmul.waitReset(10) ) continue;
  884.     if (!iBtnEmul.presence() ) continue;
  885.     if (iBtnEmul.recvAndProcessCmd() ) break;
  886.   } while (millis() < 200 + tStart);  */
  887. }
  888.  
  889. void BM_SendKey(byte* buf){
  890.   switch (keyType){
  891.     case keyEM_Marine: SendEM_Marine(buf); break;
  892.     default: SendDallas(buf); break;
  893.   }
  894. }
  895.  
  896. unsigned long stTimer = millis();
  897. void loop() {
  898.   char echo = Serial.read();
  899.   if (echo == 'e' || BtnErase.longPress()){
  900.     myOLED.print("EEPROM cleared success!", 0, 0);
  901.     Serial.println("EEPROM cleared");
  902.     EEPROM.update(0, 0); EEPROM.update(1, 0);
  903.     EEPROM_key_count = 0; EEPROM_key_index = 0;
  904.     Sd_Erase();
  905.     myOLED.update();
  906.   }
  907.  
  908.   if (echo == 'r') readAnalog();
  909.   if (echo == 'm') resetMetacomCyfral(true);
  910.   if (echo == 'c') resetMetacomCyfral(false);
  911.   if ((echo == 't') || BtnOK.shortPress()) {  // переключатель режима чтение/запись
  912.     switch (copierMode){
  913.       case md_empty: Sd_ErrorBeep(); break;
  914.       case md_read: copierMode = md_write; clearLed(); digitalWrite(R_Led, HIGH);  break;
  915.       case md_write: copierMode = md_blueMode; clearLed(); digitalWrite(B_Led, HIGH);
  916.         digitalWrite(Luse_Led, !digitalRead(Luse_Led)); break;
  917.       case md_blueMode: copierMode = md_read; clearLed(); digitalWrite(G_Led, HIGH);
  918.         digitalWrite(Luse_Led, !digitalRead(Luse_Led)); break;
  919.     }
  920.     OLED_printKey(keyID);
  921.     Serial.print("Mode: "); Serial.println(copierMode);
  922.     Sd_WriteStep();
  923.   }
  924.  
  925.  if (BtnUp.shortPress() && (EEPROM_key_count > 0)){       //при нажатии кнопки листаем ключи из eeprom
  926.     EEPROM_key_index--;
  927.     if (EEPROM_key_index < 1) EEPROM_key_index = EEPROM_key_count;
  928.     EEPROM_get_key(EEPROM_key_index, keyID);
  929.     OLED_printKey(keyID);
  930.     Sd_WriteStep();
  931.   }
  932.  if (BtnDown.shortPress() && (EEPROM_key_count > 0)){
  933.     EEPROM_key_index++;
  934.     if (EEPROM_key_index > EEPROM_key_count) EEPROM_key_index = 1;
  935.     EEPROM_get_key(EEPROM_key_index, keyID);
  936.     OLED_printKey(keyID);
  937.     Sd_WriteStep();            
  938.   }
  939.  
  940.  if ((copierMode != md_empty) && BtnOK.longPress()){     // Если зажать кнопкку - ключ сохранися в EEPROM
  941.     if (EPPROM_AddKey(keyID)) {
  942.       OLED_printError("The key saved", false);
  943.       Sd_ReadOK();
  944.       delay(1000);
  945.     }
  946.       else Sd_ErrorBeep();
  947.     OLED_printKey(keyID);
  948.   }
  949.  
  950.   if (millis() - stTimer < 100) return; //задержка в 100 мс
  951.   stTimer = millis();
  952.   switch (copierMode){
  953.       case md_empty: case md_read:
  954.         if (searchCyfral() || searchMetacom() || searchEM_Marine() || searchIbutton() ){     // запускаем поиск cyfral, затем поиск EM_Marine, затем поиск dallas
  955.           //keyID[0] = 0xFF; keyID[1] = 0xA9; keyID[2] =  0x8A; keyID[3] = 0xA4; keyID[4] = 0x87; keyID[5] = 0x78; keyID[6] = 0x98; keyID[7] = 0x6A; // если у вас есть код какого-то RFID ключа, можно прописать его тут
  956.           Sd_ReadOK();
  957.           copierMode = md_read;
  958.           digitalWrite(G_Led, HIGH);
  959.           if (indxKeyInROM(keyID) == 0) OLED_printKey(keyID, 1);
  960.             else OLED_printKey(keyID, 3);
  961.           }
  962.         break;
  963.       case md_write:
  964.         if (keyType == keyEM_Marine) write2rfid();
  965.           else write2iBtn();
  966.         break;
  967.       case md_blueMode:
  968.         BM_SendKey(keyID);
  969.         break;
  970.     } //end switch
  971. }
  972.  
  973. //***************** звуки****************
  974. void Sd_ReadOK() {  // звук ОК
  975.   for (int i=400; i<6000; i=i*1.5) { tone(speakerPin, i); delay(20); }
  976.   noTone(speakerPin);
  977. }
  978.  
  979. void Sd_WriteStep(){  // звук "очередной шаг"
  980.   for (int i=2500; i<6000; i=i*1.5) { tone(speakerPin, i); delay(10); }
  981.   noTone(speakerPin);
  982. }
  983.  
  984. void Sd_ErrorBeep() {  // звук "ERROR"
  985.   for (int j=0; j <3; j++){
  986.     for (int i=1000; i<2000; i=i*1.1) { tone(speakerPin, i); delay(10); }
  987.     delay(50);
  988.     for (int i=1000; i>500; i=i*1.9) { tone(speakerPin, i); delay(10); }
  989.     delay(50);
  990.   }
  991.   noTone(speakerPin);
  992. }
  993.  
  994. void Sd_StartOK(){   // звук "Успешное включение"
  995.   tone(speakerPin, NOTE_A7); delay(100);
  996.   tone(speakerPin, NOTE_G7); delay(100);
  997.   tone(speakerPin, NOTE_E7); delay(100);
  998.   tone(speakerPin, NOTE_C7); delay(100);  
  999.   tone(speakerPin, NOTE_D7); delay(100);
  1000.   tone(speakerPin, NOTE_B7); delay(100);
  1001.   tone(speakerPin, NOTE_F7); delay(100);
  1002.   tone(speakerPin, NOTE_C7); delay(100);
  1003.   noTone(speakerPin);
  1004. }
  1005. /*
  1006. void Sd_StartOK(){   // звук "Успешное включение"
  1007.   tone(speakerPin, NOTE_DS6); delay(66);
  1008.   tone(speakerPin, NOTE_E6); delay(66);
  1009.   tone(speakerPin, NOTE_F6); delay(66);
  1010.   delay(66);
  1011.   tone(speakerPin, NOTE_F6); delay(66);  
  1012.   tone(speakerPin, NOTE_FS6); delay(66);
  1013.   tone(speakerPin, NOTE_G6); delay(66);
  1014.   delay(66);
  1015.   tone(speakerPin, NOTE_G6); delay(66);
  1016.   tone(speakerPin, NOTE_GS6); delay(66);
  1017.   tone(speakerPin, NOTE_A6); delay(66);
  1018.   delay(66);
  1019.   tone(speakerPin, NOTE_B6); delay(66);
  1020.   noTone(speakerPin);
  1021. }*/
  1022.  
  1023.  void Sd_Erase(){   // звук "Успешное включение"
  1024.   tone(speakerPin, NOTE_E5); delay(80);
  1025.   tone(speakerPin, NOTE_D5); delay(80);
  1026.   tone(speakerPin, NOTE_FS4); delay(40);
  1027.   tone(speakerPin, NOTE_GS4); delay(40);
  1028.   tone(speakerPin, NOTE_CS5); delay(80);
  1029.   tone(speakerPin, NOTE_B4); delay(80);
  1030.   tone(speakerPin, NOTE_D4); delay(40);
  1031.   tone(speakerPin, NOTE_E4); delay(40);
  1032.   tone(speakerPin, NOTE_B4); delay(80);
  1033.   tone(speakerPin, NOTE_A4); delay(80);
  1034.   tone(speakerPin, NOTE_CS4); delay(40);
  1035.   tone(speakerPin, NOTE_E4); delay(40);
  1036.   tone(speakerPin, NOTE_A4); delay(20);
  1037.   noTone(speakerPin);
  1038. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top