Прошивка ключей от домофона Dallas RW1990

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Доброе всем утро.

Вот решил "усовершенствовать" скетч для прошивки ключей от домофона. Сделал вывод на TFT и избавил от необходимости прописывать вручную новый код с последующей перезаливкой.

Вот  "исходник", а вот мои доработки:

//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬       Dallas   RW1990 Key Rewriter                ▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

// Объявляем библиотеки
#include <Adafruit_GFX.h>
#include <Adafruit_TFTLCD.h>
#include <TouchScreen.h>
#include <OneWire.h>
#define pin 10

// Устанавливаем пины для тачскрина. Что куда - не знаю. Содрал))
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin

// Устанавливаем диапазон считывания в омах наверно. Точно не скажу
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940

// Устанавливаем цвета для элементов меню
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define REDD    0xF422
#define GREEN   0x07E0
#define LGREEN  0x17E1
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define PINK    0xF273
#define LGREY   0x836A
#define LLGREY  0xEED2
#define SPEC1   0x28E2
#define SPEC2   0x23F3
#define SPEC3   0x5273
#define SPEC4   0x0551 // Windows 98 default color
#define SPEC5   0x2A20


// Устанавливаем диапазон усилия нажатия на тачскрин
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohmode_flag across the X plate
#define MINPRESSURE 1
#define MAXPRESSURE 1200

// Инициализируем дисплей
Adafruit_TFTLCD tft(A3, A2, A1, A0, A4);

// Инициализируем тачскрин
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

boolean mode_flag, id_flag = false;

OneWire ibutton (pin);                  // I button connected on PIN 10.
byte addr[8], hex_data[8], crc;         //array to store the Ibutton ID.

//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬    S E T U P     ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

void setup(void) {
  // запускаем экран:
  tft.begin(0x9341);


  // переворачиваем на 90град. и заливаем черным цветом
  tft.setRotation((tft.getRotation() - 1));
  tft.fillScreen(BLACK);

  // устанавливаем размер текста, цвет, перемещаем курсор вниз экрана
  // и пишем  X: и Y: , куда будем помещать координаты нажатого тача
  tft.setTextSize(2);
  tft.setTextColor(WHITE, BLACK);
  tft.setCursor(0, 5);
  tft.print("Insert Key to read ID");
  tft.drawRoundRect(12, 160, 290, 60, 30, GREEN);
  tft.setTextColor(GREEN, BLACK);
  tft.setCursor(100, 185);
  tft.print("READ mode");
}

//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬      L O O P     ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

void loop()
{

//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬  Init Touch Screen  ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

  // в целях отладки я рисую зеленый квадратик в правом нижнем углу экрана
  // который при считывании координат нажатия - мигает красным
  //  tft.fillRect(tft.width() - 20, tft.height() - 20, tft.width(), tft.height(), GREEN);

  // Объявляем класс для считывания координат
  TSPoint p = ts.getPoint();

  // Тут непонятно что делается, я просто скопировал, но - работает
  //pinMode(XP, OUTPUT);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  //pinMode(YM, OUTPUT);

// Переделываем омы в пиксели,
// хотя в данном случае это непринципиально.
// Содрано с примера рисования, а там координаты
// нажатия нужны именно в пикселях, что бы под
// стиком сразу оставался след
  p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
  p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);

// Если элемент класса "р.z" укладывается в диапазон нажатия,
// будем считать что на тачскрин-таки нажали.
// Проверяем координаты нажатой точки

//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬  If Touch Was Pressed Call mode()  ▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
     delay (10);
    mode(p.x, p.y);
  }
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬  If Key ID Was Read   ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
  if (!ibutton.search (addr)) { //read attached ibutton and asign value to buffer
    ibutton.reset_search();
    delay(200);
      return;
  }

  for (byte a = 0; a < 8; a++) {
    hex_data[a] = addr[a], HEX; //print the buffer content in LSB. For mode_flagB: for (int x = 8; x>0; x--)
  }
  
  crc = ibutton.crc8(addr, 7);
        
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬  Display Key ID HEX   ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
  //-----------------------------------
  tft.setTextColor(LGREY, BLACK);
  tft.setCursor(0, 5);
  tft.print("ID was recieved:           ");
  tft.drawRect(0,27,tft.width(),35,LGREY);
  //-----------------------------------
  
  tft.setCursor(270, 5);
  tft.setTextColor(SPEC4, BLACK);
  tft.print("crc");
  tft.setTextColor(LGREY, BLACK);
  tft.setCursor(1, 36);
  //tft.setTextSize(2);
  if (!mode_flag){
    for (int b = 0; b < 8; b++) {
        tft.print(" ");
        tft.print(hex_data[b], HEX);
        }
    tft.print("   ");
    tft.setTextColor(SPEC4, BLACK);
    tft.print(crc, HEX);
    tft.setTextColor(WHITE, BLACK);
    tft.setCursor(2,70);
    tft.print("        ");
    tft.setCursor(2,70);
    tft.print("hex_data");
    id_flag=true;
  }
  else{
    for (int b = 0; b < 8; b++) {
        tft.print(" ");
        tft.print(addr[b], HEX);
        }
    tft.print("   ");
    tft.setTextColor(SPEC4, BLACK);
    tft.print(crc, HEX);
    tft.setTextColor(WHITE, BLACK);
    tft.setCursor(2,70);
    tft.print("        ");
    tft.setCursor(2,70);
    tft.print("addr");
    id_flag=true;
  }
    
    switch (mode_flag)
          {
          case true:
    tft.setTextColor(RED, BLACK);
    tft.setCursor(1, 100);
    ibutton.skip();ibutton.reset();ibutton.write(0xD1);
    digitalWrite(10, LOW); pinMode(10, OUTPUT); delayMicroseconds(60);
    pinMode(10, INPUT); digitalWrite(10, HIGH); delay(10);
    ibutton.skip();ibutton.reset();ibutton.write(0xD5);
    tft.print("Write: ");
    byte newID[8] = {0x01, 0x77, 0x36, 0xC6, 0x00, 0x00, 0x00, 0x08};
    for (byte a = 0; a<8; a++){
      writeByte(newID[a]);
      tft.print('*');
    }
    ibutton.reset();ibutton.write(0xD1);
    digitalWrite(10, LOW); pinMode(10, OUTPUT); delayMicroseconds(10);
    pinMode(10, INPUT); digitalWrite(10, HIGH); delay(10);
      tft.print(" Done!");
      tft.setCursor(1, 100);           
      delay(1000);
      tft.print("                     ");
      mode_flag = false;
           tft.fillRoundRect(12, 160, 290, 60, 30, BLACK);
           tft.drawRoundRect(12, 160, 290, 60, 30, GREEN);
           tft.setTextColor(GREEN, BLACK);
           tft.setCursor(100, 185);
           tft.print("READ mode");
          }//End of switch mode_flag

} //End of Void loop()




//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬    Mode Flag Check    ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
void mode(int x, int y) {

  if (y > 38 && y < 190 && x > 200 && x < 290) {
                                  // if mode button was pressed
switch (id_flag)                  // if data ID was recieved
     {
      case false:
           tft.fillRoundRect(12, 160, 290, 60, 30, RED);
           tft.setTextColor(WHITE, RED);
           tft.setCursor(40, 185);
           tft.print("Nothing 2 WRITE !!!");
           delay(1000);
           tft.fillRoundRect(12, 160, 290, 60, 30, BLACK);
           tft.drawRoundRect(12, 160, 290, 60, 30, GREEN);
           tft.setTextColor(GREEN, BLACK);
           tft.setCursor(100, 185);
           tft.print("READ mode");
           break;
      case true:
     
switch (mode_flag)
    {
    case false:                   // switch mode WRITE         
      tft.fillRoundRect(12, 160, 290, 60, 30, SPEC2);
      tft.drawRoundRect(12, 160, 290, 60, 30, RED);
      tft.setTextColor(YELLOW, SPEC2);
      tft.setCursor(100, 185);
      tft.print("WRITE mode");
      mode_flag=true;
      break;
    

    
    case true:                  // switch mode READ                                                              
      tft.fillRoundRect(12, 160, 290, 60, 30, BLACK);
      tft.drawRoundRect(12, 160, 290, 60, 30, GREEN);
      tft.setTextColor(GREEN, BLACK);
      tft.setCursor(100, 185);
      tft.print("READ mode");
      mode_flag=false;
      break;
    
  }   //switch (mode_flag)
  }   //switch (id_flag)
  }   //if
}     //void mode

//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬    Write Data Byte    ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

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;
}

 

Используется дисплей 2.4" TFT с тачем. 10-й пин задействован под контакт. Вот схема:

У меня не получается запись: как оказалось надо именно RW1990, потому что он перезаписываемый, а у меня обычные, одноразовые.

Принцип работы:

1. Считать код

2. Перевести программу в режим записи

3. Записать считанный ранее код на новую болванку

Может у кого есть под рукой такая болванка и желание поэксперементировать - отпишитесь пожалуста о результатах!

----------------------------------------------

В скетче присутсвуют неиспользуемые переменные (цвет) и лишний, на мой взгляд, массив (byte hex_data[8]), но я на всякий случай его оставил для более уверенного хранения считанных байтов.

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Ну и как всегда - первый пост очень напрасно не редактируется.

Пытаясь переписать одноразовый ключ, я сделал как в исходнике: вручную прописал какие-то данные.

На самом деле 204 строку надо закомментировать, а в 206-й, вместо: "writeByte(newID[a]);" написать: "writeByte(hex_data[a]);" Тогда, наверно, будут записываться считанные с предидущего ключа значения.

sir90
Offline
Зарегистрирован: 02.01.2016

код плохо работает на запись .- на экране вместо данных высвечиваеться просто словом hex_data

 

ключ записывает не из прочитанного а из каких то кусков