Нам понадобится:
Arduino uno: http://ali.ski/BHUqd
Контактные провода: http://ali.pub/1m0h4y
Ключи перезаписываемые iButton: http://ali.pub/1oytk5
iButton гнездо: http://ali.pub/1oytt3
Кнопки: http://ali.pub/1oyu1n
Прежде чем приступить к материалу, я Вас попрошу, если нравится то, что я делаю и хотите следить за моей деятельностью, то рекомендую подписаться на мой телеграмм канал: https://t.me/ypavla
Там я публикую новости о вышедших видео, статьях и разные устройства для умного дома и не только показываю.
Спасибо за внимание, теперь продолжим.
В данной статье мы рассмотрим работу с iButton ключами. Они часто используются для открытии двери в многоквартирных домах, домофонах.
iButton хранит 64 бита информации.
Питается от 2.8V до 6.0V.
К центру подключается линия данных, к боку GND.
Подтягивающий резистор используется на 2.2Ком
Ардуино работает с ключом по протоколу OneWire.
Схема подключения ключа к Ардуино:
Сам скетч для считывания данных с ключа выглядит следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include <OneWire.h> /* * test 1-Wire whith DS1990A */ OneWire ds( 10 ); // на digital pin 10 void setup ( void ) { Serial.begin ( 9600 ); } void loop ( void ) { byte i; byte present = 0 ; byte data[ 12 ]; byte addr[ 8 ]; if ( ! ds.search(addr)) { Serial.print ( "No more addresses.\n" ); ds.reset_search(); return ; } Serial.print ( "R=" ); for ( i = 0 ; i < 8 ; i + + ) { Serial.print (addr[i], HEX); Serial.print ( " " ); } if ( OneWire::crc8( addr, 7 ) ! = addr[ 7 ]) { Serial.print ( "CRC is not valid!\n" ); return ; } if ( addr[ 0 ] ! = 0x01 ) { Serial.print ( "Device is not a DS1990A family device.\n" ); return ; } Serial.println (); ds.reset(); delay ( 1000 ); } |
Ссылка на Скетч: https://yadi.sk/d/SArPyPGb3LRVvs
После заливки скетча, в мониторе порта мы сможем увидеть адрес устройства.
Подробнее смотрим в видео ниже в статье.
Теперь давайте рассмотрим работу дубликатора ключей:
Схема подключения к Ардуино:
Для управления дублированием ключей используются кнопки
Обозначение кнопок будет осуществляться с права на лево:
Кнопки:
Кнопка подключенная к 2 пину – чтение ID ключа в буфер
Кнопка подключенная к 3 пину – программирование ключа
Кнопка подключенная к 4 пину – сохранение считанного ID в энергонезависимую память
Кнопка подключенная к 5 пину – загрузка сохранённого ID в буфер
Кнопка подключенная к 6 пину – загрузка константы в буфер(константа указывается вначале скетча)
А здесь собственно сам Скетч:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | #include <OneWire.h> #include <EEPROM.h> #define pin 10 // I button connected on PIN 10. OneWire ibutton (pin); byte IDconst[ 8 ] = { 0x01 , 0x24 , 0x2A , 0xAB , 0x00 , 0x00 , 0x00 , 0x2F }; byte arr[ 8 ]; byte ID[ 8 ]; char com = 0 ; int sw1 = 0 ; int sw2 = 0 ; int sw3 = 0 ; int sw4 = 0 ; int sw5 = 0 ; void setup (){ Serial.begin ( 9600 ); pinMode ( 2 , INPUT ); // назначить выводу порт ввода digitalWrite ( 2 , HIGH ); pinMode ( 3 , INPUT ); // назначить выводу порт ввода digitalWrite ( 3 , HIGH ); pinMode ( 4 , INPUT ); // назначить выводу порт ввода digitalWrite ( 4 , HIGH ); pinMode ( 5 , INPUT ); // назначить выводу порт ввода digitalWrite ( 5 , HIGH ); pinMode ( 6 , INPUT ); // назначить выводу порт ввода digitalWrite ( 6 , HIGH ); } void loop (){ if ( ! ibutton.search (arr)){ //read attached ibutton and asign value to buffer ibutton.reset_search(); delay ( 200 ); //com=0; //Serial.print(" .."); return ; } com = Serial.read (); if ( com = = 'h' ){ delay ( 200 ); Serial.print ( "Help \n" ); Serial.print ( "r - reading ID of IButton \n" ); Serial.print ( "w - writing ID to IButton \n" ); Serial.print ( "s - save reading ID to EEPROM \n" ); Serial.print ( "l - loading ID from EEPROM \n" ); Serial.print ( "e - erasing EEPROM \n" ); Serial.print ( "c - load constant ID to bufer \n" ); Serial.print ( "p - print variables\n" ); com = 0 ; } if ( com = = 'c' | | digitalRead ( 6 ) = = LOW & & sw5 = = 0 ){ delay ( 200 ); /*ibutton.search (arr);//read attached ibutton and asign value to buffer ibutton.reset_search();*/ for ( byte x = 0 ; x< 8 ; x + + ){ ID[x] = IDconst[x];} Serial.print ( "Constant ID: " ); for ( byte x = 0 ; x< 8 ; x + + ){ Serial.print (ID[x],HEX); //print the buffer content in LSB. For MSB: for (int x = 8; x>0; x--) Serial.print ( " " ); } Serial.print ( "\n" ); com = 0 ; sw5 = 1 ; } if ( digitalRead ( 6 ) = = HIGH & & sw5 = = 1 ) { delay ( 200 ); sw5 = 0 ; } if ( com = = 'r' | | digitalRead ( 2 ) = = LOW & & sw1 = = 0 ){ delay ( 200 ); /*ibutton.search (arr);//read attached ibutton and asign value to buffer ibutton.reset_search();*/ for ( byte x = 0 ; x< 8 ; x + + ){ ID[x] = arr[x];} Serial.print ( "ID: " ); //Serial.print(millis()/1000); //Serial.print("Read ID "); for ( byte x = 0 ; x< 8 ; x + + ){ Serial.print (ID[x],HEX); //print the buffer content in LSB. For MSB: for (int x = 8; x>0; x--) Serial.print ( " " ); } //compute crc// byte crc; crc = ibutton.crc8(ID, 7 ); Serial.print ( "CRC: " ); Serial.println (crc,HEX); //newID[8] = ID[8]; com = 0 ; sw1 = 1 ; } if ( digitalRead ( 2 ) = = HIGH & & sw1 = = 1 ) { delay ( 200 ); sw1 = 0 ; } if ( com = = 's' | | digitalRead ( 4 ) = = LOW & & sw3 = = 0 ){ delay ( 200 ); Serial.print ( "Saved ID: " ); for ( byte x = 0 ; x< 8 ; x + + ){ EEPROM.write(x, ID[x]); Serial.print (ID[x],HEX); //print the buffer content in LSB. For MSB: for (int x = 8; x>0; x--) Serial.print ( " " ); } com = 0 ; sw3 = 1 ; Serial.print ( "\n" ); } if ( digitalRead ( 4 ) = = HIGH & & sw3 = = 1 ) { delay ( 200 ); sw3 = 0 ; } if ( com = = 'p' ){ Serial.print ( "Print ID: " ); for ( byte x = 0 ; x< 8 ; x + + ){ Serial.print (ID[x],HEX); //print the buffer content in LSB. For MSB: for (int x = 8; x>0; x--) Serial.print ( " " ); } Serial.print ( "\n" ); Serial.print ( "Print ARR: " ); for ( byte x = 0 ; x< 8 ; x + + ){ Serial.print (ID[x],HEX); //print the buffer content in LSB. For MSB: for (int x = 8; x>0; x--) Serial.print ( " " ); } Serial.print ( "\n" ); Serial.print ( "Print IDconst: " ); for ( byte x = 0 ; x< 8 ; x + + ){ Serial.print (IDconst[x],HEX); //print the buffer content in LSB. For MSB: for (int x = 8; x>0; x--) Serial.print ( " " ); } Serial.print ( "\n" ); com = 0 ; } if ( com = = 'l' | | digitalRead ( 5 ) = = LOW & & sw4 = = 0 ){ delay ( 200 ); Serial.print ( "Loaded ID: " ); for ( byte x = 0 ; x< 8 ; x + + ){ ID[x] = EEPROM.read(x); Serial.print (ID[x],HEX); //print the buffer content in LSB. For MSB: for (int x = 8; x>0; x--) Serial.print ( " " ); } Serial.print ( "\n" ); com = 0 ; sw4 = 1 ; } if ( digitalRead ( 5 ) = = HIGH & & sw4 = = 1 ) { delay ( 200 ); sw4 = 0 ; } if ( com = = 'e' ){ Serial.print ( "Erase saved ID" ); for ( byte x = 0 ; x< 8 ; x + + ){ EEPROM.write(x, 0xFF ); } Serial.print ( "\n" ); com = 0 ; } if ( com = = 'w' | | digitalRead ( 3 ) = = LOW & & sw2 = = 0 ){ delay ( 200 ); ibutton.skip(); ibutton.reset(); ibutton.write( 0x33 ); Serial.print ( "ID before write:" ); for ( byte x = 0 ; x< 8 ; x + + ){ Serial.print ( ' ' ); Serial.print (ibutton.read(), HEX); } ibutton.skip(); ibutton.reset(); ibutton.write( 0xD1 ); digitalWrite ( 10 , LOW ); pinMode ( 10 , OUTPUT ); delayMicroseconds ( 60 ); pinMode ( 10 , INPUT ); digitalWrite ( 10 , HIGH ); delay ( 10 ); Serial.print ( '\n' ); Serial.print ( "Writing iButton ID: " ); for ( byte x = 0 ; x< 8 ; x + + ){ Serial.print (ID[x],HEX); Serial.print ( ' ' ); } Serial.print ( '\n' ); // Hardcode here your desired ID // // 01 D5 9F DC 02 00 00 96 ibutton.skip(); ibutton.reset(); ibutton.write( 0xD5 ); for ( byte x = 0 ; x< 8 ; x + + ){ writeByte(ID[x]); Serial.print ( "**" ); } Serial.print ( '\n' ); ibutton.reset(); ibutton.write( 0xD1 ); digitalWrite ( 10 , LOW ); pinMode ( 10 , OUTPUT ); delayMicroseconds ( 10 ); pinMode ( 10 , INPUT ); digitalWrite ( 10 , HIGH ); delay ( 10 ); com = 0 ; sw2 = 1 ; } if ( digitalRead ( 3 ) = = HIGH & & sw2 = = 1 ) { delay ( 200 ); sw2 = 0 ; } } int writeByte( byte data){ int data_bit; for (data_bit = 0 ; data_bit< 8 ; data_bit + + ){ if (data & 1 ){ digitalWrite (pin, LOW ); pinMode (pin, OUTPUT ); delayMicroseconds ( 60 ); pinMode (pin, INPUT ); digitalWrite (pin, HIGH ); delay ( 10 ); } else { digitalWrite (pin, LOW ); pinMode (pin, OUTPUT ); pinMode (pin, INPUT ); digitalWrite (pin, HIGH ); delay ( 10 ); } data = data >> 1 ; } return 0 ; } |
Ссылка на скетч: https://yadi.sk/d/WiIVW0-K3LRX86
Демонстрация работы данной программы можно увидеть в видео приведенном в конце статьи.
Видео: