Помогите с кодом

Stilus
Offline
Зарегистрирован: 07.11.2017

Есть код считывания - копирования ключей iButton от домофона. Сам код работает, но на экран 1602 всё выводится криво. Прошу помощи!

#include <OneWire.h>

#include <LiquidCrystal_I2C.h>
//задаем адрес LCD экрана 0x27, 16 символов, 2 строки
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int switchPin = 2; // Будем использовать аппаратное прерывание INT0, поэтому кнопка должна быть подключена к 2-му пину
const int dataPin = 10; // Data пин считывателя ключей
const int ledPin = 13; // Пин контрольного светодиода
volatile boolean writeMode = false; // Режим записи: 1 - включен; 0 - выключен (режим чтения)
boolean recoveryMode = false; // Режим восстановления нечитаемых ключей (с записанным по ошибке нулевым первым байтом)
byte oldID[8]; // Считанный ID ключа
byte newID[8]; // Записываемый ID ключа
const byte defaultID[8] = { 0x01, 0x54, 0x5E, 0x03, 0x0E, 0x00, 0x00, 0x84 }; // По умолчанию прошивается "Универсальный" ID: 01:54:5E:03:0E:00:00:84
byte crc; // Контрольная сумма CRC

OneWire ibutton (dataPin);


void setup() {
  Serial.begin(115200);
  loadDefaultID();
  pinMode(ledPin, OUTPUT);
  pinMode(switchPin, INPUT_PULLUP);
  // При включении устройства, удерживая кнопку нажатой, активируется режим восстановления
  if (digitalRead(switchPin) == LOW) recoveryMode = true;
  attachInterrupt(0, int0, LOW); // при нажитии кнопки срабатывает 0-е прерывание, обработчик прерывания (ISR) - функция int0()
  Serial.println("Device is ready. Send 'h' for help.");

  lcd.init(); // Инициализируем экран
  //включаем подсветку
  lcd.backlight();
  //Устанавливаем позицию начиная с которой выводится текст.
  lcd.setCursor(2, 0);
  //выводим строку 1
  lcd.print ("Copy Key-2017");
  lcd.setCursor (2, 1);
  //Выводим строку 2
  lcd.print ("Sergiev Posad11");
  delay(2000); // Пауза показа заставки
  lcd.clear(); // Очистка дисплея
  //аналогично выводим вторую строку



}


// Загрузка дефолтного "универсального" ID
void loadDefaultID() {
  for (byte x = 0; x < 8; x++) oldID[x] = defaultID[x];
}


// Переключение режима: Чтение/Запись
void changeMode () {
  // Перестраховка от записи некорректного ID
  if (!writeMode) {
    crc = ibutton.crc8(newID, 7); // Вычисление контрольной суммы записываемого ID
    if (newID[0] != 1 || newID[7] != crc) {
      Serial.println(F("ID is incorrect! Writing is not permitted."));
      writeModeOff();
      return;
    }
  }
  writeMode = !writeMode;
  digitalWrite(ledPin, writeMode);
  if (writeMode) {
    Serial.print(F("Waiting for the key to WRITE the new ID: "));
    for (byte x = 0; x < 8; x++) {
      Serial.print(newID[x], HEX);
      Serial.print(' ');
    }
    Serial.println(" ...");
  }
  else {
    writeModeOff();
  }
}


// Автоматическое отключение режима восстановления после записи и вывод приглашения считать новый ключ
void writeModeOff() {
  if (recoveryMode) {
    recoveryMode = false;
    Serial.println(F("Recovery mode disabled."));
  }
  Serial.println(F("Waiting for the key to READ the ID..."));
}


// Обработчик прерывания по нажатию кнопки: переключает режим: Чтение/Запись (отфильтровывая дребезг контактов)
void int0() {
  static unsigned long millis_prev;
  if ( millis() - millis_prev > 100 ) changeMode();
  millis_prev = millis();
}


// Вывод считанного ID в терминал
void printID() {
  for (byte x = 0; x < 8; x++) {
    Serial.print(oldID[x], HEX);
    Serial.print(" ");
    lcd.print(oldID[x], HEX);


  }
  crc = ibutton.crc8(oldID, 7); // Вычисление контрольной суммы считанного ID
  Serial.print(" CRC: ");
  Serial.print(crc, HEX);
  lcd.print(crc, HEX);
  if (oldID[0] !=  0x01) Serial.print(F(" Family code is not valid!"));
  if (crc != oldID[7]) Serial.print(F(" CRC is not valid!"));
  Serial.println();
  lcd.println();
}


void loop()
{

  // Обработка команд, посылаемых через терминал COM-порта
  if (Serial.available() > 0) {
    byte com; // Команда, отправляемая через терминал COM-порта
    com = Serial.read();
    switch ( com ) {
      case 'h': {
          Serial.println(F("Help:"));
          Serial.println(F("d - load default ID"));
          Serial.println(F("w - switch read/write mode"));
          Serial.println(F("m - enter ID manually"));
          Serial.println(F("r - enable recovery mode (send 'r' again to disable)"));
          Serial.println(F("h - show this help"));
          break;
        }
      case 'd': {
          if (writeMode) {
            writeMode = false;
            digitalWrite(ledPin, LOW);
          }
          loadDefaultID();
          Serial.println(F("Default ID is loaded."));

          printID();
          break;
        }
      case 'w': {
          changeMode();
          break;
        }
      case 'r': {
          writeMode = false;
          recoveryMode = !recoveryMode;
          Serial.println(recoveryMode ? F("Recovery mode enabled.") : F("Recovery mode disabled."));

          break;
        }
      case 'm': {
          byte inputID[8]; // Введённый вручную ID ключа
          char inputChar; // Код введённого символа
          char inputNum = 2; // Порядковый номер вводимого сивмола (от 0 до 15). Начинаем вводить со 2-го символа, т.к. 0-ой и 1-ый - фиксированные.
          char charEncode; // 16-ричное число (от 0 до F), в которое преобразуется каждый вводимый ASCII символ
          boolean even = 0; // Признак чётности порядкового номера вводимого символа
          Serial.println(F("Enter the new ID, or press 'Esc' to cancel."));
          inputID[0] = 1;
          Serial.print(F("The new ID is: 01 "));
          while (inputNum < 14) {
            if (Serial.available() > 0) {
              inputChar = Serial.read();
              if (inputChar == 27) {
                Serial.flush();
                Serial.println();
                Serial.print(F("Canceled..."));
                break;
              }
              else {
                if      ( inputChar >= 48 && inputChar <= 57  ) charEncode = inputChar - 48;
                else if ( inputChar >= 65 && inputChar <= 70  ) charEncode = inputChar - 55;
                else if ( inputChar >= 97 && inputChar <= 102 ) charEncode = inputChar - 87;
                else inputNum = -1;
                if ( inputNum != -1 ) {
                  Serial.write(inputChar);
                  if (!even) inputID[inputNum / 2] = charEncode << 4;
                  else {
                    inputID[inputNum / 2] = inputID[inputNum / 2] + charEncode;
                    Serial.print(' ');
                  }
                  even = !even;
                  inputNum++;
                }
              }
            }
          }
          if (inputNum == 14) {
            inputID[7] = ibutton.crc8(inputID, 7); // Автоматическое вычисление контрольной суммы введённого ID
            for (byte i = 0; i < 8; i++) oldID[i] = inputID[i];
          }
          Serial.println(oldID[7], HEX);
          printID();
          break;
        }
    }
  }

  for (byte x = 0; x < 8; x++) newID[x] = oldID[x];
  // Проверяем, приложен ли ключ
  if (!ibutton.search (oldID)) {
    ibutton.reset_search();
    delay(50);
    if (!recoveryMode) return;
  }

  // Режим чтения
  if (!writeMode) {
    digitalWrite(ledPin, HIGH);
    delay(50);
    printID();
    digitalWrite(ledPin, LOW);
  }

  // Режим записи
  if (writeMode) {
    delay(200);
    digitalWrite(ledPin, LOW);
    ibuttonCommand(0x33, 1, 1);
    Serial.print("Old ID: ");
    lcd.print("old ID:");
    for (byte x = 0; x < 8; x++) {
      Serial.print(ibutton.read(), HEX);
      lcd.setCursor (0, 1);
      lcd.print(ibutton.read(), HEX);
      Serial.print(' ');
    }
    ibuttonCommand(0xD1, 1, 1);
    // устанавливаем на линии логический 0
    digitalWrite(dataPin, LOW); pinMode(dataPin, OUTPUT); delayMicroseconds(60);
    pinMode(dataPin, INPUT); digitalWrite(dataPin, HIGH); delay(10);
    Serial.print("  New ID: ");
    for (byte x = 0; x < 8; x++) {
      Serial.print(newID[x], HEX);
      Serial.print(' ');
    }
    ibuttonCommand(0xD5, 1, 1);
    Serial.print("Writing... ");
    for (byte x = 0; x < 8; x++) {
      writeByte(newID[x]);
      Serial.print('*');
    }
    Serial.println(F(" OK!"));
    ibuttonCommand(0xD1, 0, 1);
    // устанавливаем на линии логическую 1
    digitalWrite(dataPin, LOW); pinMode(dataPin, OUTPUT); delayMicroseconds(10);
    pinMode(dataPin, INPUT); digitalWrite(dataPin, HIGH); delay(10);
    changeMode();
  }
}


// Отправка команды iButton
void ibuttonCommand(uint8_t command, boolean sk, boolean rs) {
  if (sk) ibutton.skip();
  if (rs) ibutton.reset();
  ibutton.write(command);
}


// Побайтовая запись нового ID
void writeByte(byte data) {
  for (int data_bit = 0; data_bit < 8; data_bit++) {
    digitalWrite(dataPin, LOW); pinMode(dataPin, OUTPUT);
    if (data & 1) delayMicroseconds(60);
    pinMode(dataPin, INPUT); digitalWrite(dataPin, HIGH);
    delay(10);
    data = data >> 1;


  }
}

 

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

Не плодите дубли сообщений. Если в прошлый раз было мало ответов - это не потому, что ваше сообщение не заметили. Причина в том, что вы неправильно подходите к проблеме и задаете неверный вопрос. 

Я вам уже писал - если у вас мало оыта, не стоит сразу писать огромные куски кода.  Начните с простого - с вывода на экран что-нибудь типа @Hello World@. Когда научитесь - попробуйте вывести код ключа. Потом добавите готовый код экрана в код работы с ibutton.

 

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

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

Искать решение проблемя надо начиная с простого.  Если данный код заработает то будем думать дальше.

Если нет, то меняйте дисплей, у меня даннй код работает отлично!

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("Hello, world!");
  lcd.setCursor(2,1);
  lcd.print("Ywrobot Arduino!");
}


void loop()
{
}

 

Stilus
Offline
Зарегистрирован: 07.11.2017

Дисплей работает, проверенно на Hello World! В сериал порт (монитор порта) всё выводится хорошо. Показывает считываемый ключ, записывыемый и тд. и все в разных строках. А на ЛСД всё в одну строку и как бы в нахлёст. следующие символы при заполнении строки ложатся на предыдущие! Вот такая беда.

Stilus
Offline
Зарегистрирован: 07.11.2017

Ещё один вопрос не по теме - Как удалить ошибочно созданную тему на форуме? СПС.

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

Stilus пишет:

на ЛСД всё в одну строку и как бы в нахлёст. следующие символы при заполнении строки ложатся на предыдущие! Вот такая беда.

ну блин, при выводе строки вы же должны задавать не только начальную позицию текста, но и строку. Вы задаете?

Посмотрите примеры к библиотеке - там это должно быть. Попробуйте вывести несколько Hello World! на разных строках.

Stilus
Offline
Зарегистрирован: 07.11.2017

когда пшу lcd.setCursor (0,1);  скетч перестаёт компилироватся

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

Stilus пишет:

когда пшу setCursor (0,1);  скетч перестаёт компилироватся

что значит "перестает компилироваться?" - виснет? ошибку выдает? - пишите текст ошибки.

И вообще - ну посмотрите же вы примеры!!! Вот выше Андрей запостил в сообщении №2 - у него в примере текст выводится в 2 строки.

 

Stilus
Offline
Зарегистрирован: 07.11.2017

Его пример рабочий, проверял. В моём коде сначала тоже в де строки вывод. 

lcd.init(); // Инициализируем экран
031   //включаем подсветку
032   lcd.backlight();
033   //Устанавливаем позицию начиная с которой выводится текст.
034   lcd.setCursor(2, 0);
035   //выводим строку 1
036   lcd.print ("Copy Key-2017");
037   lcd.setCursor (2, 1);
038   //Выводим строку 2
039   lcd.print ("Sergiev Posad11");
040   delay(2000); // Пауза показа заставки
041   lcd.clear(); // Очистка дисплея

А скетч выдаёт

C:\Documents and Settings\Admin\Мои документы\Arduino\Chitaet_i_zapisyvaet2\Chitaet_i_zapisyvaet2.ino: In function 'void printID()':
 
Chitaet_i_zapisyvaet2:107: error: 'setCursor' was not declared in this scope
 
exit status 1
'setCursor' was not declared in this scope
 
Stilus
Offline
Зарегистрирован: 07.11.2017

Ребят изначально код был без LCD, он полностью работает. Вот я и хотел к этому коду LCD прикурить, но ..... ?

#include <OneWire.h>

const int switchPin = 2; // Будем использовать аппаратное прерывание INT0, поэтому кнопка должна быть подключена к 2-му пину
const int dataPin = 10; // Data пин считывателя ключей
const int ledPin = 13; // Пин контрольного светодиода
volatile boolean writeMode = false; // Режим записи: 1 - включен; 0 - выключен (режим чтения)
boolean recoveryMode = false; // Режим восстановления нечитаемых ключей (с записанным по ошибке нулевым первым байтом)
byte oldID[8]; // Считанный ID ключа
byte newID[8]; // Записываемый ID ключа
const byte defaultID[8] = { 0x01, 0x27, 0x8F, 0x19, 0x05, 0x00, 0x00, 0x34 }; // По умолчанию прошивается "Универсальный" ID: 01:FF:FF:FF:FF:FF:FF:2F

byte crc; // Контрольная сумма CRC

OneWire ibutton (dataPin);


void setup() {
  Serial.begin(115200);
  loadDefaultID();
  pinMode(ledPin, OUTPUT);
  pinMode(switchPin, INPUT_PULLUP);
  // При включении устройства, удерживая кнопку нажатой, активируется режим восстановления
  if (digitalRead(switchPin) == LOW) recoveryMode = true;
  attachInterrupt(0, int0, LOW); // при нажитии кнопки срабатывает 0-е прерывание, обработчик прерывания (ISR) - функция int0()
  Serial.println("Device is ready. Send 'h' for help.");
}


// Загрузка дефолтного "универсального" ID 
void loadDefaultID() {
  for (byte x = 0; x < 8; x++) oldID[x] = defaultID[x];
}


// Переключение режима: Чтение/Запись
void changeMode () {
  // Перестраховка от записи некорректного ID
  if (!writeMode) {
    crc = ibutton.crc8(newID, 7); // Вычисление контрольной суммы записываемого ID
    if (newID[0] != 1 || newID[7] != crc) {
      Serial.println(F("ID is incorrect! Writing is not permitted."));
      writeModeOff();
      return;
    }
  }
  writeMode = !writeMode;
  digitalWrite(ledPin, writeMode);
  if (writeMode) {
    Serial.print(F("Waiting for the key to WRITE the new ID: "));
    for (byte x = 0; x < 8; x++) {
      Serial.print(newID[x], HEX);
      Serial.print(' ');
    }
    Serial.println(" ...");
  }
  else {
    writeModeOff();
  }
}


// Автоматическое отключение режима восстановления после записи и вывод приглашения считать новый ключ
void writeModeOff() {
  if (recoveryMode) {
    recoveryMode = false;
    Serial.println(F("Recovery mode disabled."));
  }
  Serial.println(F("Waiting for the key to READ the ID..."));
}


// Обработчик прерывания по нажатию кнопки: переключает режим: Чтение/Запись (отфильтровывая дребезг контактов)
void int0() {
  static unsigned long millis_prev;
  if ( millis() - millis_prev > 100 ) changeMode();
  millis_prev = millis();
}


// Вывод считанного ID в терминал
void printID() {
  for (byte x = 0; x < 8; x++) {
    Serial.print(oldID[x], HEX);
    Serial.print(" ");
  }
  crc = ibutton.crc8(oldID, 7); // Вычисление контрольной суммы считанного ID
  Serial.print(" CRC: ");
  Serial.print(crc, HEX);
  if (oldID[0] !=  0x01) Serial.print(F(" Family code is not valid!"));
  if (crc != oldID[7]) Serial.print(F(" CRC is not valid!"));
  Serial.println();
}


void loop() {
  // Обработка команд, посылаемых через терминал COM-порта
  if (Serial.available() > 0) {
    byte com; // Команда, отправляемая через терминал COM-порта
    com = Serial.read(); 
    switch ( com ) {
      case 'h': {
        Serial.println(F("Help:"));
        Serial.println(F("d - load default ID"));
        Serial.println(F("w - switch read/write mode"));
        Serial.println(F("m - enter ID manually"));
        Serial.println(F("r - enable recovery mode (send 'r' again to disable)"));
        Serial.println(F("h - show this help"));
        break;
      }
      case 'd': {
        if (writeMode) {
          writeMode = false;
          digitalWrite(ledPin, LOW);
        }
        loadDefaultID();
        Serial.println(F("Default ID is loaded."));
        printID();
        break;
      }
      case 'w': {
        changeMode();
        break;
      }
      case 'r': {
        writeMode = false;
        recoveryMode = !recoveryMode;
        Serial.println(recoveryMode ? F("Recovery mode enabled.") : F("Recovery mode disabled."));
        break;
      }
      case 'm': {
        byte inputID[8]; // Введённый вручную ID ключа
        char inputChar; // Код введённого символа
        char inputNum = 2; // Порядковый номер вводимого сивмола (от 0 до 15). Начинаем вводить со 2-го символа, т.к. 0-ой и 1-ый - фиксированные.
        char charEncode; // 16-ричное число (от 0 до F), в которое преобразуется каждый вводимый ASCII символ
        boolean even = 0; // Признак чётности порядкового номера вводимого символа
        Serial.println(F("Enter the new ID, or press 'Esc' to cancel."));
        inputID[0] = 1;
        Serial.print(F("The new ID is: 01 "));
        while (inputNum < 14) {
          if (Serial.available() > 0) {
            inputChar = Serial.read();
            if (inputChar == 27) {
              Serial.flush();
              Serial.println();
              Serial.print(F("Canceled..."));
              break;
            }
            else {
              if      ( inputChar >= 48 && inputChar <= 57  ) charEncode = inputChar - 48;
              else if ( inputChar >= 65 && inputChar <= 70  ) charEncode = inputChar - 55;
              else if ( inputChar >= 97 && inputChar <= 102 ) charEncode = inputChar - 87;
              else inputNum = -1;
              if ( inputNum != -1 ) {
                Serial.write(inputChar);
                if (!even) inputID[inputNum/2] = charEncode << 4;
                else {
                  inputID[inputNum/2] = inputID[inputNum/2] + charEncode;
                  Serial.print(' ');
                }
                even = !even;
                inputNum++;
              }
            }
          }
        }
        if (inputNum == 14) {
          inputID[7] = ibutton.crc8(inputID, 7); // Автоматическое вычисление контрольной суммы введённого ID
          for (byte i=0; i<8; i++) oldID[i] = inputID[i];
        }
        Serial.println(oldID[7], HEX);
        printID();
        break;
      }
    }
  }

  for (byte x = 0; x < 8; x++) newID[x] = oldID[x];
  // Проверяем, приложен ли ключ
  if (!ibutton.search (oldID)) {
    ibutton.reset_search();
    delay(50);
    if (!recoveryMode) return;
  }

    // Режим чтения
  if (!writeMode) {
    digitalWrite(ledPin, HIGH);
    delay(50);
    printID();
    digitalWrite(ledPin, LOW);
  }

  // Режим записи
  if (writeMode) {
    delay(200);
    digitalWrite(ledPin, LOW);
    ibuttonCommand(0x33, 1, 1);
    Serial.print("Old ID: ");
    for (byte x = 0; x < 8; x++) {
      Serial.print(ibutton.read(), HEX);
      Serial.print(' ');
    }
    ibuttonCommand(0xD1, 1, 1);
    // устанавливаем на линии логический 0
    digitalWrite(dataPin, LOW); pinMode(dataPin, OUTPUT); delayMicroseconds(60);
    pinMode(dataPin, INPUT); digitalWrite(dataPin, HIGH); delay(10);
    Serial.print("  New ID: ");
    for (byte x = 0; x < 8; x++) {
      Serial.print(newID[x], HEX);
      Serial.print(' ');
    }
    ibuttonCommand(0xD5, 1, 1);
    Serial.print("Writing... ");
    for (byte x = 0; x < 8; x++) {
      writeByte(newID[x]);
      Serial.print('*');
    }
    Serial.println(F(" OK!"));
    ibuttonCommand(0xD1, 0, 1);
    // устанавливаем на линии логическую 1
    digitalWrite(dataPin, LOW); pinMode(dataPin, OUTPUT); delayMicroseconds(10);
    pinMode(dataPin, INPUT); digitalWrite(dataPin, HIGH); delay(10);
    changeMode();
  }
}


// Отправка команды iButton
void ibuttonCommand(uint8_t command, boolean sk, boolean rs) {
  if (sk) ibutton.skip();
  if (rs) ibutton.reset();
  ibutton.write(command); 
}


// Побайтовая запись нового ID
void writeByte(byte data) {
  for (int data_bit = 0; data_bit < 8; data_bit++) {
    digitalWrite(dataPin, LOW); pinMode(dataPin, OUTPUT);
    if (data & 1) delayMicroseconds(60);
    pinMode(dataPin, INPUT); digitalWrite(dataPin, HIGH);
    delay(10);
    data = data >> 1;
  }
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

У меня не выдает:

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

Sketch uses 7,784 bytes (25%) of program storage space. Maximum is 30,720 bytes.
Global variables use 549 bytes (26%) of dynamic memory, leaving 1,499 bytes for local variables. Maximum is 2,048 bytes.

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

 

kalapanga
Онлайн
Зарегистрирован: 23.10.2016

Stilus пишет:

Дисплей работает, проверенно на Hello World! В сериал порт (монитор порта) всё выводится хорошо. Показывает считываемый ключ, записывыемый и тд. и все в разных строках. А на ЛСД всё в одну строку и как бы в нахлёст. следующие символы при заполнении строки ложатся на предыдущие! Вот такая беда.

В монитор порта каждый раз всё выводится на новую строку, а на дисплее их всего две. Чистить кроме Вас их никто не будет. Заставка-то из строк 36 и 39 небось нормально выводится? А дальше Вы всё печатаете поверх того, что есть. Уточните, что делает функция lcd.println() (Надо в Вашей библиотеке смотреть). Скорее всего на другую строку курсор переставляет, но вряд ли какой-нибудь "скроллинг" делает или строки очищает.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

То есть вот это, из вашего сетапа, у вас выводится друг на друга?

//Устанавливаем позицию начиная с которой выводится текст.
  lcd.setCursor(2, 0);
  //выводим строку 1
  lcd.print ("Copy Key-2017");
  lcd.setCursor (2, 1);
  //Выводим строку 2
  lcd.print ("Sergiev Posad11");
  delay(2000); // Пауза показа заставки

 

Stilus
Offline
Зарегистрирован: 07.11.2017

это нет, а вот все остальные данные да.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

А  lcd.clear(); // Очистка дисплея 

перед полной сменой экрана где надо делаете?

Stilus
Offline
Зарегистрирован: 07.11.2017
// Режим чтения
  if (!writeMode) {
    digitalWrite(ledPin, HIGH);
    delay(50);
    printID();
    digitalWrite(ledPin, LOW);
  }

  // Режим записи
  if (writeMode) {
    delay(200);
    digitalWrite(ledPin, LOW);
    ibuttonCommand(0x33, 1, 1);
    Serial.print("Old ID: ");
    lcd.clear(); // НАПРИМЕР
    lcd.print("old ID:");
    for (byte x = 0; x < 8; x++) {
      Serial.print(ibutton.read(), HEX);
      lcd.setCursor (0, 1);
      lcd.print(ibutton.read(), HEX);
      Serial.print(' ');
    }
    ibuttonCommand(0xD1, 1, 1);
    // устанавливаем на линии логический 0
    digitalWrite(dataPin, LOW); pinMode(dataPin, OUTPUT); delayMicroseconds(60);
    pinMode(dataPin, INPUT); digitalWrite(dataPin, HIGH); delay(10);
    Serial.print("  New ID: ");
    for (byte x = 0; x < 8; x++) {
      Serial.print(newID[x], HEX);
      Serial.print(' ');
    }
    ibuttonCommand(0xD5, 1, 1);
    Serial.print("Writing... ");
    for (byte x = 0; x < 8; x++) {
      writeByte(newID[x]);
      Serial.print('*');
    }
    Serial.println(F(" OK!"));
    ibuttonCommand(0xD1, 0, 1);
    // устанавливаем на линии логическую 1
    digitalWrite(dataPin, LOW); pinMode(dataPin, OUTPUT); delayMicroseconds(10);
    pinMode(dataPin, INPUT); digitalWrite(dataPin, HIGH); delay(10);
    changeMode();
  }
}