Нужна помощь со скетчем Дубликатор дом.ключей

Нашёл на одном форуме данный скетч. Но проблема в том что отображается всё на английском ( Помогите сделать отображение на русском. И ещё там база ключей не вся активирована не смог сам активировать (

Спойлер

/*
Скетч для копирования ключей DS1990 на базе Arduino NANO. Специально для https://4pda.ru/forum/index.php?showtopic=953401
Схема версии 3 очень простая, привела меня в восторг. Но лично мне не хватало в программной реализации пары мелочей.
Свою доработанную версию я назвал 3.1, т.к. она является просто небольшой доработкой версии 3. Скетч версии 3.1
отличается от версии 3 только наличием монитора порта, добавлением более понятного вывода номера ключа на экран и
удалёнными “лишними” блоками кода. А именно, я прибил вычисление CRC для вывода на экран (всё равно нигде его отдельно
не выводим), закомментированную часть кода, которая была написана автором явно не для экрана 1602. Кроме того, я добавил
комментарии, мне так приятнее смотреть на код. Ещё я заменил в схеме резистор 1 кОм на 2.2 кОм, так у меня лучше пишет ключи.
Английскую версию скетча я не делал по той простой причине, что этот скетч прекрасно работает с экранчиками 1602, в которых
отсутствуют кириллические символы. Всё благодаря прекрасной библиотеке LCD_1602_RUS_ALL.

Подключение LCD дисплея по IIC:

GND-GND
+5V-VCC
A4-SDA
A5-SCL

Если во время компиляции ругается на то, что невозможно найти arduino.h, то в файле
/Arduino/libraries/liquidcrystalrus_i2c/LiquidCrystalRus_I2C.cpp
Нужно заменить строку:
#include <arduino.h>
на
#include <Arduino.h>
*/
#define _LCD_TYPE 1
#include <OneWire.h> // Библиотека
#include <LCD_1602_RUS_ALL.h> // Библиотека
LCD_1602_RUS <LiquidCrystal_I2C> lcd(0x27, 16, 2); // Адрес Lcd дисплея 16х2
#define pin 10 // D10: пин данных (центральный) для подлючения лузы iButton (зелёный провод у лузы DS9092)
OneWire ibutton (pin);
byte OldID[8];
byte addr[8];
byte ReadID[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
byte bOut;
byte iSelN = 0xFF;
int iSize = 22;
int iDef = 30;

//массив универсальных ключей из темы
byte UniKey[22][8] =
{
{0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x00}, // - Univer 1F
{0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F, 0xFF, 0x00}, // - Univer 2F
{0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x9B}, // - UK-1 Metakom 2003
{0x01, 0xBE, 0x40, 0x11, 0x5A, 0x36, 0x00, 0xE1}, // - UK-2 Vizit – код универсального ключа, для Vizit
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D}, // - UK-3 Cyfral
{0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F}, // - Стандартный универсальный ключ
{0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}, // - Обычный
{0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x19, 0xFF}, // - Отлично работает на старых домофонах
{0x01, 0x53, 0xD4, 0xFE, 0x00, 0x00, 0x7E, 0x88}, // - Cyfral, Metakom
{0x01, 0x53, 0xD4, 0xFE, 0x00, 0x00, 0x7E, 0x00}, // - Cyfral,Metakom
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14}, // - Открываает 98% Metakom и некоторые Cyfral
{0x01, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00}, // - домофоны Cyfral + фильтр и защита
{0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00}, // - Metakom
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xA0}, // - Metakom 95%
{0x01, 0x00, 0xBE, 0x11, 0xAA, 0x00, 0x00, 0xFB}, // - домофоны KeyMan
{0x01, 0xBE, 0x40, 0x11, 0x0A, 0x00, 0x00, 0x1D}, // - проверен работает Vizit иногда KeyMan
{0x01, 0x53, 0xD4, 0xFE, 0x00, 0x00, 0x00, 0x6F}, // - домофоны Vizit - до 99%
{0x01, 0xBE, 0x40, 0x11, 0x5A, 0x36, 0x00, 0x00}, // - Vizit 99%
{0x01, 0x76, 0xB8, 0x2E, 0x0F, 0x00, 0x00, 0x5C}, // - домофоны Форвард
{0x01, 0xA9, 0xE4, 0x3C, 0x09, 0x00, 0x00, 0x00}, // - домофоны Eltis - до 90%
{0x01, 0xBE, 0x40, 0x11, 0x5A, 0x56, 0x00, 0xBB}, // - проверен работает
{0x01, 0xBE, 0x40, 0x11, 0x00, 0x00, 0x00, 0x77}, // - проверен работает
//{0x01, 0x2C, 0x7A, 0x0F, 0xA0, 0x00, 0x00, 0x4A}, // - ???
//{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // - домофоны Cyfral 70%
//{0x01, 0x6F, 0x2E, 0x88, 0x8A, 0x00, 0x00, 0x4D}, // - Открывать что-то должен
//{0x01, 0x71, 0xA8, 0x75, 0x0F, 0x00, 0x00, 0xE9}, // - Vizit 55%
//{0x11, 0xBE, 0x40, 0x11, 0x5B, 0x00, 0x00, 0xCD}, // - Vizit 50%
//{0x0F, 0xBE, 0x40, 0x11, 0x5A, 0x36, 0x00, 0x9E}, // - Vizit 50%
};
//идентификаторы унив ключей для отображения
String NameKey[22] = {“Uni_1F”, “Uni_2F”, “UK1 Met”, “UK2 Viz”, “UK3 Cyf”, “Std”, “Std2”, “Std_Old”, “CyfMet1”, “CyfMet2”, “CyfMet3”,“Cyf_Flt”, “Met_1”, “Met_2”, “KeyMan”, “KeyMViz”, “Vizit1”, “Vizit2”, “Forward”, “Eltis”, “Wrk_1”, “Wrk_2”};

#define TIME_STEP 10 //шаг измерения времени нажатия кнопки
#define TIME_WAIT 1000 //шаг измерения времени нажатия кнопки
#define BUTTON_LONG_PRESS_TIME 7000 //время длинного нажатия кнопки
#define BUTTON_MIDDLE_PRESS_TIME 3000 //время длинного нажатия кнопки
#define BUTTON_LSHORT_PRESS_TIME 500 //время короткого нажатия кнопки
#define BUTTON_SHORT_PRESS_TIME 100 //время короткого нажатия кнопки

//физическое состояние кнопки
enum ButtonResult {
buttonNotPress, //код если кнопка не нажата
buttonShortPress, //код короткого нажатия
buttonLShortPress, //код короткого нажатия
buttonMiddlePress, //код среднего нажатия
buttonLongPress //код длинного нажатия
};

const int buttonPin = 2; // Назначаем пин D2 на кнопку
const int ledPin = 13; // Пин светодиода (Плюс) D13. Если используется светодиод в лузе DS9092, то белый провод. Дублирует светодиод на Ардуинке.
int buttonState = 0; // Переменная, в которой хранится состояние кнопки
bool bWriteFlag = false; // Не пишем содержимое массива readID в таблетку, когда флаг равен 0
bool bReadFlag = true; // Вытаскиваем из таблетки номер в массив readID, если этот флаг равен 0
bool bFlagErr = false;
bool bCopy = false;
int iButtonPress;

void setup() { // Функция инициализации, выполняется однократно при запуске Ардуинки
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
lcd.init(); // Инициализируем дисплей 16x2
lcd.backlight(); // Включаем подсветку дисплея 16х2
lcd.setCursor(1,0); // Устанавливаем курсор в 4 символ 1 строки
LCD_Start();
Serial.begin(9600); // Инициализируем монитор порта на скорости 9600
Serial.println(); // новая строка в порт для красоты
Serial.println(F(“Инициализация успешно завершена”)); // Отправляем тестовую строку в монитор порта
Serial.println(F(“Читаем униерсальный ключ”));
if (iDef>= 0 && iDef < iSize - 1){
fMoveArray (ReadID, UniKey[iDef]);
NameKey[iDef] += “*”;
iSelN = iDef;
}
PrnByte(ReadID,0);
Serial.println();
delay(500);
}

//---------------------------
//сброс ардуино
void(* resetFunc) (void) = 0;

void loop() {
//обработка нажатия кнопки
switch(get_button()){
case buttonLShortPress:{
if (!bCopy){break;}
}
case buttonMiddlePress:{
Serial.println(F(“Button middle pressed”));
Serial.println ();
Serial.println (F("Нажата кнопка, готов к записи "));

  if (!fCompareArray(ReadID, ReadID, true)){
    bReadFlag = false;                                   // Ставим флаг, чтобы не читать из таблетки в массив ReadID перед записью
    bWriteFlag = true;                                  // Ставим флаг, чтобы писать в таблетку содержимое масива readID
  }
  else{
    Serial.println(F("К записи подан пустой код "));
    PrnByte(ReadID,0);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("   Blank code"));
    lcd.setCursor(0,1);
    lcd.print(F("Nothing to write"));
    delay(1500);
    LCD_Start();
  }
  break;
}
case buttonShortPress:{
  Serial.println(F("Button short pressed"));
  SelectUni ();
  break;
}
case buttonLongPress:{
  Serial.println(F("Button long pressed"));
  lcd.clear();                                      // Очищаем экран и начинаем отображение информации о номере ключа
  lcd.setCursor(0,0);
  lcd.print(F("Restart!!!")); 
  delay(1000);
  resetFunc();
  break;
}
case buttonNotPress:break;

}

if (!bWriteFlag && (Serial.read() != ‘w’)) { // Если НЕ установлен флаг на запись в таблетку
if (!ibutton.search (addr)) { // Проверка: а может таблетка не обнаружена?
ibutton.reset_search();
delay(50);
return; // если нет таблетки, то выходим из loop
}

if (bReadFlag){// Пишем считанный ключ в массив ReadID, если не стоит флаг запрета раньше был прочитан дугой
  if (!fCompareArray(ReadID, addr, false)){
    digitalWrite(ledPin, HIGH);                       // Ну а если нашли таблетку, то зажигаем светодиод на время считывания ключа
    delay(100);
    bCopy = true;
    lcd.clear();                                      // Очищаем экран и начинаем отображение информации о номере ключа
    lcd.setCursor(0,0);
    lcd.print(F("Read: ")); 
    Serial.print(F("Считан: "));
    fMoveArray (ReadID, (addr));
    PrnByte(ReadID,2);
    digitalWrite(ledPin, LOW);                        // Гасим светодиод
  }
  else{Serial.println(F("Повторное чтение"));}
}
else{Serial.print(".");} 

}
else{ //Запись в таблетку
lcd.clear(); // очищаем LCD и предлагаем приложить болванку
lcd.setCursor(0,0);
lcd.print(F(“Attach blank key”));
lcd.setCursor(4,1);
if (!bCopy){
lcd.print(NameKey[iSelN]);
}
else{
lcd.print(F(“Copy → New”));
}
Serial.println(); // отчитываемся в монитор порта о том, какой номер будем записывать в ключ
Serial.println(F("Будем писать ID: "));
PrnByte(ReadID,0);
delay(500);
digitalWrite(ledPin, HIGH); // Зажигаем светодиод, показывая готовность к записи
bFlagErr = true;
while (bFlagErr){
bReadFlag = true;
while (bReadFlag){
if(!ibutton.search (addr)) { // Проверка: а может таблетка не обнаружена?
switch(get_button()){
case buttonLongPress:{;}
case buttonMiddlePress:{;}
case buttonLShortPress:{
delay(50);
bReadFlag = true;
bWriteFlag = false;
Serial.print(F(“выход по кнопке”));
digitalWrite(ledPin, LOW);
LCD_Start();
return;
}
}
}
else{bReadFlag = false;}
}

  ibutton.skip(); ibutton.reset(); ibutton.write(0x33);
  
  Serial.println();                               // Новая строка в порт
  Serial.print(F(" ID ключа до записи: "));          // пишем в порт что на ключе было до записи
  for (byte x = 0; x < 8; x++) {
    OldID[x] = ibutton.read();
  }
  PrnByte(OldID,0);

  lcd.clear();                                    // Очищаем экран перед записью ключа
  lcd.setCursor(0,0);
  lcd.print(F("Key writing"));                          // Начало записи, интригуем пользователя и не даём оторвать таблетку
      
  // send reset
  ibutton.skip();
  ibutton.reset();
  // send 0xD1
  ibutton.write(0xD1);
  // send logical 0
  digitalWrite(pin, LOW); pinMode(pin, OUTPUT); delayMicroseconds(60);
  pinMode(pin, INPUT); digitalWrite(pin, HIGH); delay(10);
  byte newID[8] = { (ReadID[0]), (ReadID[1]), (ReadID[2]), (ReadID[3]), (ReadID[4]), (ReadID[5]), (ReadID[6]), (ReadID[7]) };
  ibutton.skip();
  ibutton.reset();
  ibutton.write(0xD5);
  Serial.println();
  Serial.print(F(" Запись ключа"));                // Отчитываемся в порт о начале записи ключа
  if (bCopy){Serial.print(F(" (копия):"));}
  else{Serial.print(F(" (универсальный):"));}
  for (byte x = 0; x < 8; x++) {
    writeByte(newID[x]);                          // В цикле вызываем функцию побайтовой записи ключа
    lcd.setCursor(x,1);
    lcd.print(".");
  }
  PrnByte(newID,0);
  Serial.println();
  Serial.println(F("Запись завершена"));       // Пишем в порт о завершении процесса записи
  Serial.println(F("Проверяем записанное"));       // Пишем в порт о завершении процесса записи

//проверяем запись
ibutton.skip();
ibutton.reset();
// ibutton.search (addr);
ibutton.write(0x33);
bFlagErr = false;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(F(“Checking”));
for (byte x = 0; x < 8; x++) {
lcd.setCursor(x,1);
lcd.print(“.”);
addr = ibutton.read();
delay(100);
}
bFlagErr = !fCompareArray (newID, addr, false);
Serial.print(F(“К записи в ключ “));
PrnByte(newID,0);
Serial.println();
Serial.print(F(” прочитано после записи “));
PrnByte(addr,0);
if (bFlagErr){
Serial.println(F(“Ошибка! Записанный ключ не прошел последующую верификацию. Возможно он только для чтения”));
}
ibutton.reset();
digitalWrite(ledPin, LOW); // Гасим светодиод
// lcd.setCursor(4,1);
lcd.clear();
lcd.setCursor(1,0);
if (bFlagErr){
lcd.print(F(“Write ERROR!”));
lcd.setCursor(0,1);
lcd.print(F(“Key is ReadOnly”));
delay(4000);
lcd.clear();
lcd.setCursor(1,0);
lcd.print(F(“Try write again”));
lcd.setCursor(0,1);
lcd.print(F(“or press button”));
}
else{
lcd.setCursor(4,0);
lcd.print(F(” Write OK”)); // дописываем фразу для пользователя, намекая, что таблетку можно забирать
lcd.setCursor(0,1);
lcd.print(F(" Key is ready"));
}
}
delay(4000);
LCD_Start();
bWriteFlag = false;
bReadFlag = true;
bCopy = false;
iSelN = 0xFF;
for (byte x = 0; x < 8; x++) ReadID = 0xFF;
}
}

//--------------------------------------------------
// собственно, функция записи байта в таблетку
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;
}

//--------------------------------------------------
// Начальное сообщение на дисплее
void LCD_Start(){
lcd.clear();
lcd.setCursor(1,0); // Устанавливаем курсор в 4 символ 1 строки
lcd.print(F("Ready to copy ")); // Первая строка при включении
lcd.setCursor(1,1); // Устанавливаем курсор в 7 символ 2 строки
lcd.print(F(“Attach the key”)); // Вторая строка при включении
}

//--------------------------------------------------
// вывод 8 байт с лидирующим 0
void PrnByte(byte hByte[8], int i){
bool bStart = true;
for (byte x = 0; x < 8; x++) {
if (bStart && (i == 1 || i == 2)){lcd.setCursor(8,0);}

if (hByte [x] <= 0x0F){
  if (i == 0 || i == 2){Serial.print("0");}
  if (i == 1 || i == 2){lcd.print("0");}  
}
if (i == 0 || i == 2){
  Serial.print(hByte[x], HEX);
  if (x < 7){Serial.print(':');}
  else{Serial.println();}
}
if (i == 1 || i == 2){
  lcd.print(hByte[x], HEX);
  if (x==3){lcd.setCursor (0,1);}
  if (x < 7){lcd.print(":");}
  bStart = false;
}

}
}

//--------------------------------------------------
//обработка кнопки
enum ButtonResult get_button(void){
//для измерения времени нажатия
uint16_t buttonPressTime = 0;

//--------------------------------------------------
//проверка нажатия кнопки
while(digitalRead(buttonPin) == LOW){
//шаг по шкале времени
delay(TIME_STEP);
//считаем время
buttonPressTime += TIME_STEP;
//это нужно, чтоб счетчик не переполнился, если кто-то уснет на кнопке
if(buttonPressTime > BUTTON_LONG_PRESS_TIME)
buttonPressTime = BUTTON_LONG_PRESS_TIME;
}

//проверяем длинное нажатие кнопки
if(buttonPressTime >= BUTTON_LONG_PRESS_TIME)
return buttonLongPress;

//проверяем среднее нажатие кнопки
if(buttonPressTime >= BUTTON_MIDDLE_PRESS_TIME)
return buttonMiddlePress;

//проверяем короткое нажатие кнопки
if(buttonPressTime >= BUTTON_LSHORT_PRESS_TIME)
return buttonLShortPress;

//проверяем короткое нажатие кнопки
if(buttonPressTime >= BUTTON_SHORT_PRESS_TIME)
return buttonShortPress;

//сообщаем, что кнопку не нажимали
return buttonNotPress;
}

//--------------------------------------------------
// копирование массива ключа
void fMoveArray (byte To[8], byte From[8]){
for (byte x = 0; x < 8; x ++) To = From;
}
//--------------------------------------------------
// копирование массива ключа
bool fCompareArray (byte Arr1[8], byte Arr2[8], bool bBlank){
bool bOk = true;
byte BlankByte = 0xFF;

for (byte x = 0; x < 8; x ++){
if (!bBlank){BlankByte = Arr2;}
if (Arr1 != BlankByte && bOk){
bOk = false;
}
}

return bOk;
}

//--------------------------------------------------
//выбор универсального клча из базы
void SelectUni (){
bool bLoop = true, bSel = false;
uint16_t WaitTime = 0;
byte i = 5, iSel = 0;
byte selID[8];

lcd.clear();
lcd.setCursor(0,0);
lcd.print(F(“Select univ key”));
Serial.println (F(“Выбираем унив. ключ из базы”));
while (bLoop){
switch(get_button()){
case buttonShortPress:{
fMoveArray (selID, UniKey[iSel]);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(NameKey[iSel]);
Serial.print(NameKey[iSel]);
Serial.print(" ");
PrnByte(selID,2);
iSelN = iSel;
if (iSel == iSize){iSel = 0;}else{iSel += 1;}
bSel = true;
break;
}

  case buttonLShortPress:{;}
  case buttonMiddlePress:{
    if (!bSel){break;}
    fMoveArray (ReadID, selID);
    bReadFlag = false;                                   // Ставим флаг, чтобы не читать из таблетки в массив ReadID перед записью
    bWriteFlag = true;                                  // Ставим флаг, чтобы писать в таблетку содержимое масива readID
    bCopy = false;
    return;
  }
  case buttonLongPress:{
    LCD_Start();
    return;
  }

  case buttonNotPress:{
    if (!bSel){
      delay(TIME_STEP);
      WaitTime += TIME_STEP;
      if ((WaitTime%1000) == 0){
        lcd.setCursor(9,1);
        lcd.print(i, DEC);
        i -= 1;
      }
    }  
    break;
  }
}
if (WaitTime > 5000){
  LCD_Start();
  return;
}  

}
}

Запрос перенесён в коммерческий раздел, т.к. по стилистике - это явно заказ работы.

Подправить пару строк в коде, ты прикалываешься?

DS1990… ты прикалываешься? Они ещё где то применяются?

Не знаю, может пару, а может и одну - это пусть у исполнителя голова болит.

Мы с Вами на ты? Давно?

В Москве 90% домофонов на RS1990

Сделаю, пишите на почту barmaley2m@yandex.ru

Английского не знаешь?
Или ты планировал эту программу кому-то впарить как свою - а с английскими сообщениями никто не поверит, что ты это сам написал?

Большая часть “базы ключей” - полный бред. Все эти “коды-вездеходы” давно засвечены в сети и на 99% домофонов заблокированы давно.

Согласен. Базы не рабочие. Я просто попросил вездеход у почтальона и скопировал. В моём доме во всех подъездах и домах рядом точно работает. Далеко не пробовал, мне не надо.

Офигеть, столица называется… У нас везде проксимити брелки используют. Ну, возможно, где то и 1990 остались, но мне не попадались. По хорошему, конечно, нужно бы домофонщиков расспросить сколько чего используется.

У вас, видимо, сами жильцы ставят что поудобней, а там массово за счёт застройщика/домофонной компании - уже что подешевле.

Да, родственница скидывалась на дверь с доводчиком и домофон. И как бы ещё и за облуживание чего то не платила.

Не, у нас тут домофоны на ключиках 1990 стоят практически во всех домах, в том числе в свежих коммерческих комплексах, где домофоны обслуживает ТСЖ. Хотя может я не того круга и бываю только нищих районах:)
Мы тоже платим за обслуживание домофона, и это норма.

У дочери в Краснодаре квартира в новом доме, въехали буквально 4-5 лет назад, целый жилой комплекс из нескольких новых многоэтажек, не элитный - домофон на проксимити брелке. Видимо, дело не только в цене

Что касается кода - я когда-то делал копировщик на основе, как мне кажется, этого же скетча. Только я его почистил и сократил. Пользуюсь конструкцией много лет - по причинам, описанным выше, мне записи только RS1990 вполне хватает :slight_smile:

По опыту использования - дисплей в этой конструкции абсолютно лишний. На что мне видеть код ключа? а больше ничего полезного на экране не показывается.

Вторая кривизна в коде - кнопки. Все эти короткие, средние и длинные нажатия - зачем? У этого девайса всего две функции - скопировать код с одного ключа и записать его на другой. Поэтому кнопок нужно две, иначе в запаре или по пьяни легко перепутать стереть единственный копируемый экземпляр.

ЗЫ Кстати - у многих кодов, лежащих в интернете, в алгоритме записи ключа намеренно добавлены ошибки. Копирование ключей - это бизнес.

этот экземпляр обычно не перезаписываемый. Записываемые ключики обычно дороже.

Почти всегда я вижу оригинал на таких же перезаписываемых болванках, как и те что я записываю.
Перезаписываемая болванка 1990 стоит 17-19 рублей в розницу

Как удалить тему ??? Мне не нужен исполнитель! Я не создавал в этом разделе эту тему!