T.E.S.T.C.O.P.Y. • Просмотр темы - PortableProg v3.0. - полностью автономный программатор 24cXX

PortableProg v3.0. - полностью автономный программатор 24cXX

инструмент, переходники к программаторам, программаторы и т.д.

Актуален ли данный проект на сегодняшний день? Нужна ли этому проекту поддержка SPI Flash?

1. Да, возможно соберу себе такой
30 
60%
2. Да, но не для меня
6%
3. Нет, совсем не актуален все эти модели выкинули уже на помойку :(
14%
4. Нет, поддержка SPI Flash совсем не актуальна в данном проекте.
4%
5, Да , не мешало бы сделать поддержку SPI Flash в данном проекте (в комментариях можете написать с какой целью).
16%
 
Всего голосов : 50

Прилепить пост

Сообщение Krepton85 » Пт авг 31, 2018 3:23 pm

сделал смену серийного номера картриджа при каждой прошивке Ricoh.


У Рикох во многих моделях нет серийника, и менять там ничего не нужно.
Аватар пользователя
Krepton85   
Разработчик PortableProg

Прилепить пост

Сообщение 1dx » Пн сен 03, 2018 11:20 am

На самом картридже написано SP 201 series. Под него есть проверенный дамп - его и добавил отдельным пунктом.

Касаемо серийников - были проблемы с клиенткой, у нее SP150, и он отказывался нормально работать, пока не сменишь серийник. Так что сделал от греха подальше для моделей Ricoh с трехзначными номерами (SP-xxx). Отлично работает.
Ну и задержки чуть увеличил, чтобы успевать читать с дисплея.

Код: выделить все
/*
Auto Resetter wthiout sd card by Galavarez
* Версия 18.04.2018
- Исправлен глюк с обнулением картриджей Richo ricoh_sp_211_213_220, ricoh_sp_211_213_220 и ricoh_sp_4510

* Версия 06.03.2018
- Для скоростной записи чипа нужны 2 разные библиотеки 24с01_02 и 24с04_16. Они в папке Library.
- Теперь обнулятор сам выбирает какой библиотекой прошивать чип, опираясь на размер дампа чипа. Если до 256 байт то 24с01_02, иначе 24с04_16.

* Версия 05.03.2018
- На кнопке SELECT будет прошивка чипа с обратным отсчетом. Это удобно когда нужно держать картридж и чип обеими руками.
- Отсчет 8 секунд до прошивки. Время меняется в функции countdown_timer() переменная timer.

* Версия 04.03.2018
- Новая экспериментальная функция по определению плохого контакта с чипом. На экран будет выведено Concact Bad и тогда нужно будет перезапустить ардуино.
- Так же эта функция доступна по кнопке SELECT она полюбому пока не используется.

* Версия 02.03.2018
- Новая библиотека для работы с чипами, старая глючит при скоростной заливки дампа. Библиотека в папке Library.

* Версия 25.02.2018
- Не большое изменение в коде

* Версия 14.02.2018
- Добавлен круговой поиск чипов т.е. стоя на первом чипе при нажатие кнопки LEFT попадаете на последний чип
- Улучшена скорость записи чипов с 8 - 10 сек до 1 - 3 сек

* Версия 13.02.2018
- Добавил чип Ricoh SP 201HE для SP 211/213/220, принтера нет чтобы проверить прошивку.

* Версия 5.01.2018
- Не большое изменение в коде
- Добавил чип Xerox WC-4118 8k спасибо за дамп copiermaster
- Добавил чип Ricoh SP 3400 3410 (406522) 5k спасибо за дамп copiermaster
- Добавил чип Ricoh SP 3500XE (406990) 6.4k спасибо за дамп copiermaster
- Добавил чип Ricoh SP 4500HE (407318) 12k говорят что подходит к Ricoh SP 3610SF но я это не проверял

* Версия 29.12.2017
- Переписал код для упрощения добавления новых чипов
- Исправил ошибку в генерации серийного номера
- Исправил некоторые другие ошибки

* Версия 17.12.2017
- Добавил чип Ricoh SP 210 спасибо за дамп copiermaster

* Версия 25.11.2017
- Добавил чип Ricoh SP 200, 202, 203 на 2.6К

* Версия 21.11.2017
- Переписал проверку дампа после заливки его в чип
- Добавил распиновку чипа в правом верхнем углу G - gnd, V - vcc, D - data, C - clock

* Версия 14.11.2017
- Добавил вывод дампа из чипа на экран по кнопки вниз первых 128 байт

* Версия 03.11.2017 11:17
- Добавил чип Xerox PE 220

* Версия 13.10.2017 14:36
- Добавил проверку на запись дампа в чип

* Версия 12.10.2017 12:37
- Добавил задержку при подачи питания для стабильности
- Вернул обработку нажатий кнопок для DOWN и SELECT

* Версия 06.10.2017 19:17
- Добавил чип Ricoh SP 100 (SP 101E)
- Добавил чип Ricoh SP 111 (SP 110E)
- Добавил чип Ricoh SP 150
- Добавил чип Ricoh SP 300
- Добавил чип Ricoh SP 311
- Добавил чип Samsung SCX 4200 (автоматическая смена номера CRUM)
- Добавил чип Xerox WC 3119 (автоматическая смена номера CRUM)
*/

// Подключаем библиотеку которая позволяет управлять микросхемами 24CXX подключать их на ПИН A4 (SDA), A5 (SCL)
#include <Eeprom24C01_02.h> // Библиотека работает с 24C01 24C02
#include <Eeprom24C04_16.h> // Библиотека работает с 24C04 24C08 24C16
// Подключаем библиотеку которая позволяет взаимодействовать с различными устройствами по интерфейсу I2C / TWI.
#include <Wire.h>
// Подключаем библиотеку которая позволяет управлять различными жидкокристаллическими дисплеями (LCD)
#include <LiquidCrystal.h> 
// Подключаем библиотеку для записи статических строк во FLASH а не в RAM
// Serial.print(F(Тут_статическая_строка)) или const PROGMEM до вызова SETUP
// Serial.println(pgm_read_byte(&dump_ricoh_sp_150[i]), HEX); чтение переменной без изменений из FLASH
#include <avr/pgmspace.h>

// Пины LCD 1602 (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );

// Пин питания у Вас может быть другой
#define POWER_PIN A2
// Пин для работы генератора случайных чисел
#define RANDOM_PIN A3

// Адрес чипа (адрес динамический, меняется от чипа к чипу)
byte address_eeprom;

// Номер чипа по умолчанию
byte global_id = 1;

// Кол-во чипов в базе данных
int global_all_chip_in_database;

// Имя дампа
const byte *global_name_dump;

// Размер чипа
int global_size_dump;

// Номер байта конца серийного номера, переменных 2 т.к. серийников может быть два
int global_number_byte_end_of_sn;
int global_number_byte_end_of_sn_2;

// Состояние кнопки (защита от повторного срабатывания)
boolean global_button_press = false; // true - кнопка нажата

/****************************** ДАМПЫ ЧИПОВ ******************************/

// 24С01_02 // RICOH SP101E (407059) от Aficio SP 100 (SF/SU/E)
const PROGMEM byte dump_ricoh_aficio_sp_101e_sp_100[128] = {
  0x20, 0x00, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x64, 0x00, 0x34, 0x30, 0x36, 0x39, 0x34, 0x37,
  0x12, 0x04, 0x4D, 0x41, 0x16, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 //RICOH AFICIO SP 111 SF/SU CARTRIDGE SP 110E
const PROGMEM byte dump_ricoh_aficio_sp_110e_sp_111[128] = {
  0x20, 0x00, 0x01, 0x05, 0x01, 0x01, 0x03, 0x00, 0x64, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0x14, 0x05, 0x4D, 0x47, 0x21, 0x00, 0x08, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x30, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x82, 0xB9, 0x00, 0x00, 0x64, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 // SP150HE (408010) 1.5k от Aficio SP 150 (W/SU/SUW)
const PROGMEM byte dump_ricoh_aficio_sp_150[128] = {
  0x32, 0x00, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00, 0x64, 0x00, 0x34, 0x30, 0x38, 0x33, 0x33, 0x33,
  0x16, 0x03, 0x4D, 0x4D, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 // Ricoh R-SP200HS-2.6K for Ricoh SP 200,202,203 -- Ricoh SP200/201/202/203/204 (с картриджем SP200HE)
const PROGMEM byte dump_ricoh_sp_200_202_203[128] = {
  0x21, 0x00, 0x01, 0x04, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x34, 0x30, 0x37, 0x32, 0x35, 0x37,
  0x13, 0x07, 0x4D, 0x43, 0x11, 0x00, 0x22, 0x32, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 // Ricoh Ricoh SP201HE для Ricoh серии SP211/213/220 (2600стр) --  Ricoh SP211/213/220, с картриджем SP201HE
const PROGMEM byte dump_ricoh_sp_211_213_220[128] = {
  0x21, 0x00, 0x01, 0x04, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0x35, 0x37,
  0x13, 0x07, 0x4D, 0x43, 0x11, 0x00, 0x14, 0x91, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 // Ricoh Aficio SP 210 (407971)
const PROGMEM byte dump_ricoh_aficio_sp_210[128] = {
  0x21, 0x00, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00, 0x64, 0x00, 0x34, 0x30, 0x37, 0x39, 0x37, 0x31,
  0x15, 0x03, 0x4D, 0x50, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 // Ricoh Aficio SP 201 series (407971)
const PROGMEM byte dump_ricoh_sp_201s[128] = {
  0x21, 0x00, 0x01, 0x04, 0x02, 0x01, 0x01, 0x00, 0x64, 0x00, 0x34, 0x30, 0x37, 0x32, 0x36, 0x31,
  0x13, 0x01, 0x4D, 0x42, 0x08, 0x00, 0x27, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 // SP300 (406956) 1.5k от Aficio SP 300DN 24С01
const PROGMEM byte dump_ricoh_aficio_sp_300[128] = {
  0x13, 0x00, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x64, 0x00, 0x34, 0x30, 0x36, 0x39, 0x35, 0x36,
  0x11, 0x11, 0x4A, 0x4D, 0x51, 0x00, 0x19, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 // SP 311 (407246) 3.5K
const PROGMEM byte dump_ricoh_aficio_sp_311[128] = {
  0x07, 0x00, 0x01, 0x03, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x34, 0x30, 0x37, 0x32, 0x34, 0x36,
  0x13, 0x00, 0x47, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x58, 0x12,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С04_16 // SCX-4200от Samsung SCX-4200/4220 3k
const PROGMEM byte dump_samsung_scx_4200[512] = {
  0x43, 0x34, 0x32, 0x30, 0x30, 0x45, 0x58, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31, 0x33, 0x30, 0x37, 0x00, 0x00,
  0x43, 0x52, 0x55, 0x4D, 0x2D, 0x31, 0x33, 0x30, 0x37, 0x32, 0x35, 0x33, 0x32, 0x31, 0x31, 0x35,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x34, 0x32, 0x30, 0x30, 0x45, 0x58, 0x50,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xDD, 0x00, 0x22, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

// 24С04_16 // XEROX WC 3119 3k
const PROGMEM byte dump_xerox_wc_3119[512] = {
  0xA8, 0xCF, 0x58, 0x45, 0x52, 0x4F, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x30, 0x30, 0x36, 0x30, 0x36, 0x00, 0x00,
  0x43, 0x52, 0x55, 0x4D, 0x2D, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x39, 0x33, 0x31, 0x34,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xCF, 0x58, 0x45, 0x52, 0x4F, 0x58, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xDD, 0x00, 0x22, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x43, 0x72, 0x75, 0x6D, 0x20, 0x42, 0x79, 0x20,
  0x48, 0x77, 0x61, 0x6E, 0x67, 0x2E, 0x73, 0x6B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

// 24С04_16 // XEROX PE 220 2k
const PROGMEM byte dump_xerox_pe_220[512] = {
  0x20, 0x58, 0x45, 0x52, 0x4F, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31, 0x30, 0x30, 0x32, 0x00, 0x00,
  0x43, 0x52, 0x55, 0x4D, 0x2D, 0x31, 0x30, 0x30, 0x32, 0x30, 0x36, 0x39,
  0x38, 0x31, 0x36, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x20, 0x58, 0x45, 0x52, 0x4F, 0x58, 0x20, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xCC, 0xDD, 0x00, 0x22, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

// 24С04_16 // Xerox WC-4118 8k
const PROGMEM byte dump_xerox_wc_4118[512] = {
 0x20, 0x58, 0x45, 0x52, 0x4F, 0x58, 0x32, 0x20, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x32, 0x30, 0x30, 0x38, 0x30, 0x32, 0x00, 0x00,
  0x43, 0x52, 0x55, 0x4D, 0x2D, 0x30, 0x38, 0x30, 0x32, 0x30, 0x36, 0x31,
  0x36, 0x30, 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x20, 0x58, 0x45, 0x52, 0x4F, 0x58, 0x32, 0x20,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xCF, 0x58, 0x45,
  0x52, 0x4F, 0x58, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x32, 0x30, 0x30, 0x38, 0x30, 0x32, 0x00, 0x00, 0x43, 0x52, 0x55, 0x4D,
  0x2D, 0x30, 0x38, 0x30, 0x32, 0x30, 0x36, 0x31, 0x36, 0x30, 0x30, 0x31,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xA8, 0xCF, 0x58, 0x45, 0x52, 0x4F, 0x58, 0x32, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

// 24С01_02 // Ricoh SP 3400 3410 (406522) 5k
const PROGMEM byte dump_ricoh_sp_3400_3410[128] = {
  0x07, 0x00, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x64, 0x00, 0x34, 0x30,
  0x36, 0x35, 0x32, 0x32, 0x11, 0x01, 0x4A, 0x4D, 0x02, 0x01, 0x70, 0x88,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 // Принт-картридж Ricoh тип SP 3500XE (6.4 k) для Aficio SP3500N/SP3510DN/SP3500SF/SP3510SF (406990/407646)
const PROGMEM byte dump_ricoh_sp_3500_3510[128] = {
  0x07, 0x01, 0x01, 0x03, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x34, 0x30,
  0x36, 0x39, 0x39, 0x30, 0x12, 0x05, 0x4A, 0x4D, 0x53, 0x00, 0x33, 0x83,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 24С01_02 // Принт-картридж Ricoh SP 4500HE (12K) для SP 4510DN/SP4510SF (407318)
const PROGMEM byte dump_ricoh_sp_4510[128] = {
  0x23, 0x00, 0x01, 0x03, 0x78, 0x01, 0x01, 0x00, 0x64, 0x00, 0x34, 0x30, 0x37, 0x33, 0x31, 0x38,
  0x14, 0x09, 0x54, 0x4A, 0x03, 0x00, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


/****************************** SETUP ******************************/

void setup()
{   
  lcd.begin(16, 2);  // Инициализируем LCD 16x2
  Serial.begin(9600); //инициализируем последовательное соединение для работы с ПК
  while (!Serial) { ; } // Ждем когда подключится ардуино к пк по usb
  Wire.begin(); //инициализируем библиотеку I2C / TWI для работы с I2C устройствами
 
  // Пин А2 для питания чипа устанавливаем в положение OUTPUT
  // Пин A0-14 A1-15 A2-16 A3-17 A4-18 A5-19
  pinMode(POWER_PIN, OUTPUT);
 
  // Пин А3 для работы генератора случайных чисел
  randomSeed(analogRead(RANDOM_PIN));

  // Показываем первый чип на экране
  database(global_id);   
}


/****************************** LOOP ******************************/

void loop()

  /* ОБРАБОТКА НАЖАТИЯ КНОПОК */

  // Задаем номер порта с которого производим считывание
  int analog_number = analogRead(0);
  //Serial.println(analog_number);

  if (analog_number < 100 && global_button_press == false) // Если это кнопка Right и другие кнопки не нажаты то
  {
    if (analog_debonce(100) == true) // делаем проверку от дребезга кнопок
    {
       Serial.println(F("CLICK BUTTON RIGHT"));
      // Увеличиваем счетчик
      global_id++;
     
      if (global_id <= global_all_chip_in_database)
      {
        // Показываем на экране следующий чип
        database(global_id);
      }
      else
      {
        // Показываем на экране 1 чип
        global_id = 1;
        database(global_id);
      }
     
    }
  }
  else if (analog_number < 200 && global_button_press == false) // Если это кнопка UP и другие кнопки не нажаты то
  {
    if (analog_debonce(200) == true) // делаем проверку от дребезга кнопок
    {
       Serial.println(F("CLICK BUTTON UP")); // UPLOAD -- закачиваем дамп
      // Подаем питание и сканируем шину i2c на наличие чипа
      power_on_for_chip();
     
      // Скоростная прошивка чипа
      // если дамп чипа меньше либо равна 256 байт то это микросхема 24c01_02 иначе это 24c04_16
      if(global_size_dump <= 256)
      {
        firmware_24c01_02();
      }
      else
      {
        firmware_24c04_16();
      }
     
      // Выключаем питание
      power_off_for_chip();

      // Возврат в меню
      database(global_id);

      // Тест данных
      //test_chip_on_pc(128);
    }
  }
  else if (analog_number < 400 && global_button_press == false) // Если это кнопка Down и другие кнопки не нажаты то
  {
    if (analog_debonce(400) == true) // делаем проверку от дребезга кнопок
    {
      Serial.println(F("CLICK BUTTON DOWN"));
      // Подаем питание и сканируем шину i2c на наличие чипа
      power_on_for_chip();
      // Считываем чип и показываем его на lcd
      read_chip_and_display_it();
      // Выключаем питание
      power_off_for_chip();
    }
  }
  else if (analog_number < 600 && global_button_press == false) // Если это кнопка Left и другие кнопки не нажаты то
  {
    if (analog_debonce(600) == true) // делаем проверку от дребезга кнопок
    {
      Serial.println(F("CLICK BUTTON LEFT"));
      // Уменьшаем счетчик
      global_id--;
     
      if (global_id != 0)
      {
        // Показываем на экране предыдущий чип
        database(global_id);
      }
      else
      {
        // Показываем на экране последний чип в базе данных
        global_id = global_all_chip_in_database;
        database(global_id);
      }
    }
  }
  else if (analog_number < 800 && global_button_press == false) // Если это кнопка Select и другие кнопки не нажаты то
  {
    if (analog_debonce(800) == true)  // делаем проверку от дребезга кнопок
    {
      Serial.println(F("CLICK BUTTON SELECT"));
      // Таймер обратного отсчета
      countdown_timer();
     
      // Подаем питание и сканируем шину i2c на наличие чипа
      power_on_for_chip();
     
      //Скоростная прошивка чипа
      if(global_size_dump <= 256)
      {
        firmware_24c01_02();
      }
      else
      {
        firmware_24c04_16();
      }
     
      // Выключаем питание
      power_off_for_chip();

      // Возврат в меню
      database(global_id);
    }
  }

  // Обнуляем переменную globalBntPress если все кнопки отпущены
  if ( analogRead(0) > 1000)  { global_button_press = false; }
}

/****************************** БАЗА ДАННЫХ ******************************/
void database(byte id)
{
  // Кол-во чипов в БД, менять число при добавления или удаления чипов
  global_all_chip_in_database = 16;

  // Поиск чипа
  switch (id)
  {   
    case 1:
      lcd.clear();            lcd.print(F("RICOH       GVCD"));
      lcd.setCursor(0,1);     lcd.print(F("SP 150"));
      global_name_dump = dump_ricoh_aficio_sp_150;
      global_size_dump = sizeof(dump_ricoh_aficio_sp_150);
      global_number_byte_end_of_sn = 15;
      global_number_byte_end_of_sn_2 = 0;
      break;
    case 2:
      lcd.clear();            lcd.print(F("RICOH       GVCD"));
      lcd.setCursor(0,1);     lcd.print(F("SP 100 (SP 101E)"));
      global_name_dump = dump_ricoh_aficio_sp_101e_sp_100; // ссылка на дамп
      global_size_dump = sizeof(dump_ricoh_aficio_sp_101e_sp_100); // размер дампа
      global_number_byte_end_of_sn = 15; // младший разряд первого серийного номера, если 0 то серийного номера нет
      global_number_byte_end_of_sn_2 = 0; // младший разряд второго серийного номера, если 0 то серийного номера нет
      break;
    case 3:
      lcd.clear();            lcd.print(F("RICOH       GVCD"));
      lcd.setCursor(0,1);     lcd.print(F("SP 111 (SP 110E)"));
      global_name_dump = dump_ricoh_aficio_sp_110e_sp_111;
      global_size_dump = sizeof(dump_ricoh_aficio_sp_110e_sp_111);
      global_number_byte_end_of_sn = 15;
      global_number_byte_end_of_sn_2 = 0;
      break;     
    case 4:
      lcd.clear();            lcd.print(F("RICOH       GVCD"));
      lcd.setCursor(0,1);     lcd.print(F("SP 200 202 203"));
      global_name_dump = dump_ricoh_sp_200_202_203;
      global_size_dump = sizeof(dump_ricoh_sp_200_202_203);
      global_number_byte_end_of_sn = 15;
      global_number_byte_end_of_sn_2 = 0;
      break;
    case 5:
      lcd.clear();            lcd.print(F("RICOH       GVCD"));
      lcd.setCursor(0,1);     lcd.print(F("SP 201 series"));
      global_name_dump = dump_ricoh_sp_201s;
      global_size_dump = sizeof(dump_ricoh_sp_201s);
      global_number_byte_end_of_sn = 15;
      global_number_byte_end_of_sn_2 = 0;
      break;
    case 6:
      lcd.clear();            lcd.print(F("RICOH       GVCD"));
      lcd.setCursor(0,1);     lcd.print(F("SP 211 213 220"));
      global_name_dump = dump_ricoh_sp_211_213_220;
      global_size_dump = sizeof(dump_ricoh_sp_211_213_220);
      global_number_byte_end_of_sn = 15;
      global_number_byte_end_of_sn_2 = 0;
      break;
    case 7:
      lcd.clear();            lcd.print(F("RICOH       GVCD"));
      lcd.setCursor(0,1);     lcd.print(F("SP 210"));
      global_name_dump = dump_ricoh_aficio_sp_210;
      global_size_dump = sizeof(dump_ricoh_aficio_sp_210);
      global_number_byte_end_of_sn = 15;
      global_number_byte_end_of_sn_2 = 0;
      break; 
    case 8:
      lcd.clear();            lcd.print(F("RICOH       GVDC"));
      lcd.setCursor(0,1);     lcd.print(F("SP 300"));
      global_name_dump = dump_ricoh_aficio_sp_300;
      global_size_dump = sizeof(dump_ricoh_aficio_sp_300);
      global_number_byte_end_of_sn = 15;
      global_number_byte_end_of_sn_2 = 0;
      break;   
    case 9:
      lcd.clear();            lcd.print(F("RICOH       GVCD"));
      lcd.setCursor(0,1);     lcd.print(F("SP 311"));
      global_name_dump = dump_ricoh_aficio_sp_311;
      global_size_dump = sizeof(dump_ricoh_aficio_sp_311);
      global_number_byte_end_of_sn = 15;
      global_number_byte_end_of_sn_2 = 0;
      break;
    case 10:
      lcd.clear();            lcd.print(F("RICOH       GVDC"));
      lcd.setCursor(0,1);     lcd.print(F("SP 3400 3410"));
      global_name_dump = dump_ricoh_sp_3400_3410;
      global_size_dump = sizeof(dump_ricoh_sp_3400_3410);
      global_number_byte_end_of_sn = 0;
      global_number_byte_end_of_sn_2 = 0;
      break;
    case 11:
      lcd.clear();            lcd.print(F("RICOH       GVDC"));
      lcd.setCursor(0,1);     lcd.print(F("SP 3500 3510"));
      global_name_dump = dump_ricoh_sp_3500_3510;
      global_size_dump = sizeof(dump_ricoh_sp_3500_3510);
      global_number_byte_end_of_sn = 0;
      global_number_byte_end_of_sn_2 = 0;
      break;
    case 12:
      lcd.clear();            lcd.print(F("RICOH       GVCD"));
      lcd.setCursor(0,1);     lcd.print(F("SP 4510"));
      global_name_dump = dump_ricoh_sp_4510;
      global_size_dump = sizeof(dump_ricoh_sp_4510);
      global_number_byte_end_of_sn = 0;
      global_number_byte_end_of_sn_2 = 0;
      break;     
    case 13:
      lcd.clear();            lcd.print(F("SAMSUNG     VDCG"));
      lcd.setCursor(0,1);     lcd.print(F("SCX 4200"));
      global_name_dump = dump_samsung_scx_4200;
      global_size_dump = sizeof(dump_samsung_scx_4200);
      global_number_byte_end_of_sn = 63;
      global_number_byte_end_of_sn_2 = 0;
      break;
    case 14:
      lcd.clear();            lcd.print(F("XEROX       VDCG"));
      lcd.setCursor(0,1);     lcd.print(F("WC 3119"));
      global_name_dump = dump_xerox_wc_3119;
      global_size_dump = sizeof(dump_xerox_wc_3119);
      global_number_byte_end_of_sn = 63;
      global_number_byte_end_of_sn_2 = 0;
      break;
    case 15:
      lcd.clear();            lcd.print(F("XEROX       GCDV"));
      lcd.setCursor(0,1);     lcd.print(F("WC 4118"));
      global_name_dump = dump_xerox_wc_4118;
      global_size_dump = sizeof(dump_xerox_wc_4118);
      global_number_byte_end_of_sn = 63;
      global_number_byte_end_of_sn_2 = 191;
      break;
    case 16:
      lcd.clear();            lcd.print(F("XEROX       VDCG"));
      lcd.setCursor(0,1);     lcd.print(F("PE 220"));
      global_name_dump = dump_xerox_pe_220;
      global_size_dump = sizeof(dump_xerox_pe_220);
      global_number_byte_end_of_sn = 63;
      global_number_byte_end_of_sn_2 = 0;
      break;     
  }   
}

/****************************** ЗАЩИТА ОТ ДРЕБЕЗГА КНОПОК И ПОВТОРНЫХ НАЖАТИЙ ******************************/

boolean analog_debonce(int max_value)
{
  delay(50); // Пауза перед повторным считыванием кнопки
  if ( analogRead(0) < max_value) // Если все еще держим кнопку а не случайный дребезг то
  {
    global_button_press = true; // Запоминаем что нажали кнопку
    return true; // Проверка на дребегз пройдена
  }
  else
  {
    return false; // Проверка на дребегз НЕ пройдена
  }
}

/****************************** ВКЛЮЧАЕМ ПИТАНИЯ ЧИПА ******************************/

void power_on_for_chip()
{
  digitalWrite(POWER_PIN, HIGH); // Подаем питания на A2 для запитки чипа
  delay(500); // Задержка для поднятия напряжения
  //search_address_chip(); // Сканируем шину I2C на наличия чипа и сохраняем адрес его в памяти
  search_address_chip_2();
}

/****************************** ВЫКЛЮЧАЕМ ПИТАНИЯ ЧИПА ******************************/
void power_off_for_chip()
{
  digitalWrite(POWER_PIN, LOW); // Выключаем питания на A2 пине
}

/****************************** ПОИСК ЧИПА НА ШИНЕ I2C ******************************/
void search_address_chip()
{
  byte error, address;
  for(address = 1; address < 127; address++)
  {       
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) // Ошибок нет, устройство найдено
    {     
      Eeprom24C04_16 eeprom(address); // Берем адреес шины и пытаемся считать данные с чипа
      eeprom.initialize();
      if (eeprom.readByte(0) != 0xFF) // Считываем нулевой байт, если он 0xFF то ищим следующий адрес
      {
        address_eeprom = address; // Сохраняем адрес чипа в памяти
        //Serial.print(F("Address chip = 0x"));
        //Serial.println(address,HEX);  // Показываем адрес на котором сидит чип
        break;
      }     
    }
    else if (error==4) //Есть ошибки
    {
      Serial.println(F("error == 4"));
      Serial.println(address,HEX);
    }
  }   
}

/****************************** ПОИСК ЧИПА НА ШИНЕ I2C ВЕРСИЯ 2 ******************************/
void search_address_chip_2()
{
  // По умолчанию считается что контакта с чипом нет (если все хорошо то этого сообщения не увидите)
  lcd.clear(); lcd.print(F("CONTACT CHIP"));  lcd.setCursor(0,1); lcd.print(F("BAD"));
     
  byte error, address;
  for(address = 1; address < 127; address++)
  {       
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) // Ошибок нет, устройство найдено
    {     
      Eeprom24C04_16 eeprom(address); // Берем адреес шины и пытаемся считать данные с чипа
      eeprom.initialize();
      if (eeprom.readByte(0) != 0xFF) // Считываем нулевой байт, если он 0xFF то ищим следующий адрес
      {
        address_eeprom = address; // Сохраняем адрес чипа в памяти
        //Serial.print(F("Address chip = 0x"));
        //Serial.println(address,HEX);  // Показываем адрес на котором сидит чип
       
        //Serial.println("Contact GOOD");
        lcd.setCursor(0,1); lcd.print(F("GOOD")); // Контакт есть
               
        break;
      }     
    }
    else if (error==4) //Есть ошибки
    {
      Serial.println(F("error == 4"));
      Serial.println(address,HEX);
    }
  }   
}
 
/****************************** МЕДЛЕННАЯ ПРОШИВКА ЧИПА ******************************/
void firmware()
{
  lcd.clear();
  lcd.print(F("FIRMWARE CHIP"));
  lcd.setCursor(0, 1);     
  lcd.blink(); // влючаем мигание курсора для информативности
  Serial.println(F("FIRMWARE START"));

  Eeprom24C04_16 eeprom(address_eeprom);
  eeprom.initialize();
   
  for(int i = 0; i < global_size_dump; i++) // Циклы
  {
    eeprom.writeByte(i, pgm_read_byte(&global_name_dump[i])); 
    delay(10);

    //Serial.print(pgm_read_byte(&name_dump[i]), HEX);
    //Serial.print(F(" = "));
    //Serial.println(eeprom.readByte(i), HEX);
    //Serial.print(F("number byte = "));
    //Serial.print(i);
    //Serial.print(F(" value byte = "));
    //Serial.print(pgm_read_byte(&name_dump[i]), HEX);
    //Serial.print(F(" eeprom read byte = "));
    //Serial.println(eeprom.readByte(i), HEX);
  }
  Serial.println(F("FIRMWARE END"));
  lcd.print(F("DONE !!!"));
  lcd.noBlink(); // отключаем мигание курсора
 
  // Проверка чипа
  verification_dump();

  // Смена серийного номера чипа если это нужно
  if (global_number_byte_end_of_sn > 0) // Если серийник есть то меняем его
  {
    if (global_number_byte_end_of_sn_2 > 0) // Если серийников 2 то меняем в двух местах
    {
      change_crum_two(global_number_byte_end_of_sn, global_number_byte_end_of_sn_2);
    }
    else // иначе меняем в одном
    {
      change_crum_one(global_number_byte_end_of_sn);
    }
  }
}

/****************************** СКОРОСТНАЯ ПРОШИВКА ЧИПОВ 24c01-02 до 256 байт в чипе ******************************/
void firmware_24c01_02()
{
  lcd.clear();
  lcd.print(F("FIRMWARE CHIP"));
  lcd.setCursor(0, 1);     
  lcd.blink(); // влючаем мигание курсора для информативности
  Serial.println(F("FIRMWARE START"));

  // Скоростная прошивка чипа
  Eeprom24C01_02 eeprom(address_eeprom); eeprom.initialize();
 
  word address = 0; // Адрес начало дампа
  int count = global_size_dump; // байт в чипе
 
  byte array_bytes[count];  // Создаем массив с нужным размером
  for (int i = 0; i < count; i++)
  {   
    array_bytes[i] = pgm_read_byte(&global_name_dump[i]); // Заполняем массив
    Serial.println(pgm_read_byte(&global_name_dump[i]), HEX);
  }
  eeprom.writeBytes(address, count, array_bytes); // Записываем в чип
  Serial.println(address);
  Serial.println(count);
 
  lcd.print(F("DONE !!!"));
  lcd.noBlink(); // отключаем мигание курсора

  // Проверка чипа
  verification_dump();

  // Смена серийного номера чипа если это нужно
  if (global_number_byte_end_of_sn > 0) // Если серийник есть то меняем его
  {
    if (global_number_byte_end_of_sn_2 > 0) // Если серийников 2 то меняем в двух местах
    {
      change_crum_two(global_number_byte_end_of_sn, global_number_byte_end_of_sn_2);
    }
    else // иначе меняем в одном
    {
      change_crum_one(global_number_byte_end_of_sn);
    }
  }
}

/****************************** СКОРОСТНАЯ ПРОШИВКА ЧИПОВ 24c04-16 более 512 байт в чипе ******************************/
void firmware_24c04_16()
{
  lcd.clear();
  lcd.print(F("FIRMWARE CHIP"));
  lcd.setCursor(0, 1);     
  lcd.blink(); // влючаем мигание курсора для информативности
  Serial.println(F("FIRMWARE START"));

  // Скоростная прошивка чипа
  Eeprom24C04_16 eeprom(address_eeprom);
  eeprom.initialize();   

  word address = 0; // Адрес начало дампа
  int count = global_size_dump; // байт в чипе
 
  byte array_bytes[count];  // Создаем массив с нужным размером
  for (int i = 0; i < count; i++)
  {   
    array_bytes[i] = pgm_read_byte(&global_name_dump[i]); // Заполняем массив
    //Serial.println(pgm_read_byte(&global_name_dump[i]), HEX);
  }
  eeprom.writeBytes(address, count, array_bytes); // Записываем в чип
 
  lcd.print(F("DONE !!!"));
  lcd.noBlink(); // отключаем мигание курсора

  // Проверка чипа
  verification_dump();

  // Смена серийного номера чипа если это нужно
  if (global_number_byte_end_of_sn > 0) // Если серийник есть то меняем его
  {
    if (global_number_byte_end_of_sn_2 > 0) // Если серийников 2 то меняем в двух местах
    {
      change_crum_two(global_number_byte_end_of_sn, global_number_byte_end_of_sn_2);
    }
    else // иначе меняем в одном
    {
      change_crum_one(global_number_byte_end_of_sn);
    }
  }
}

/************************************* ПРОВЕРКА ДАМПА ПОСЛЕ ПРОШИВКИ *************************************/
void verification_dump()
{
  lcd.clear();
  lcd.print(F("VERIFICATION"));
  lcd.setCursor(0,1);
 
  Eeprom24C04_16 eeprom(address_eeprom);
  eeprom.initialize(); 
   
  for(int i = 0; i < global_size_dump; i++) // Циклы
  {
    if(pgm_read_byte(&global_name_dump[i]) != eeprom.readByte(i))
    {
      lcd.print(F("ERROR"));
      Serial.print(F("VERIFICATION ERROR"));
      delay(1000);
      break;     
    }
    else
    {
      lcd.print(F("GOOD")); 
      Serial.println(F("VERIFICATION GOOD"));
      delay(500);
      break;
    }
    //Serial.print(F("number byte = "));
    //Serial.print(i);
    //Serial.print(F(" value byte = "));
    //Serial.print(pgm_read_byte(&name_dump[i]), HEX);
    //Serial.print(F(" eeprom read byte = "));
    //Serial.println(eeprom.readByte(i), HEX);
  }
}

/****************************** ГЕНЕРАТОР СЕРИЙНОГО НОМЕРА ******************************/
void change_crum_one(int address_low_byte_sn)

  Eeprom24C04_16 eeprom(address_eeprom);
  eeprom.initialize();
   
  int temp_sn_one = address_low_byte_sn; // Получаем номер байта серийника
  for (int i = 4; i > 0; i--) // меняем 4 младших разрядов серийника (в оригинале было 6)
  {   
   int randomNum = random(48, 57); // ANSI (48-58) а в DEC (0-9)
   eeprom.writeByte(temp_sn_one, randomNum); // Записываем значение в адрес
   delay(10); // пауза для записи в ячейку EEPROM
   temp_sn_one--; // переход к старшему разряду
  }
  Serial.println(F("CHANGE CRUM 1 END"));
  // Показываем серийный номер на lcd
  print_sn_on_lcd();
}

void change_crum_two(int address_low_byte_sn_1, int address_low_byte_sn_2)
{
  Eeprom24C04_16 eeprom(address_eeprom);
  eeprom.initialize();

  int temp_sn_one = address_low_byte_sn_1;
  int temp_sn_two = address_low_byte_sn_2;
  for (int i = 5; i > 0; i--) // меняем 5 последних разрядов серийника
  {
    int randomNum = random(48, 57); // ANSI (48-58) а в DEC (0-9)
    eeprom.writeByte(temp_sn_one, randomNum); // Записываем значение в адрес
    delay(10); // пауза для записи в ячейку EEPROM
    eeprom.writeByte(temp_sn_two, randomNum); // Записываем значение в адрес
    delay(10); // пауза для записи в ячейку EEPROM
    temp_sn_one--; // переход к старшему разряду
    temp_sn_two--; // переход к старшему разряду
  }
 
  Serial.println(F("CHANGE CRUM 1-2 END"));
 
  // Показываем серийный номер на lcd
  print_sn_on_lcd();
}

/************************************* ВЫВОД СЕРИЙНОГО НОМЕРА НА LCD *************************************/
void print_sn_on_lcd()

  Eeprom24C04_16 eeprom(address_eeprom);
  eeprom.initialize();

  lcd.clear();
  lcd.print(F("SUCCESS!"));
  lcd.setCursor(0,1);
  lcd.print(F("CRUM="));
  lcd.setCursor(5,1);
  //
  Serial.println(F("SERIAL NUMBER"));
  Serial.print(F("CRUM="));
  //
  int temp_start = global_number_byte_end_of_sn - 5;
  int temp_end = global_number_byte_end_of_sn + 1;
  for(int i = temp_start; i < temp_end; i++)
  {
    char c = (char)eeprom.readByte(i); // получаем ascii из hex
    lcd.print(c);
    Serial.print(c);
  }
  Serial.println(" ");
  // Задержка для просмотра номера
  delay(2000);
}

/************************************* ПОКАЗ ДАМПА НА LCD *************************************/

void read_chip_and_display_it()
{
  power_on_for_chip();
 
  Eeprom24C04_16 eeprom(address_eeprom);
  eeprom.initialize();

  //char c = (char)eeprom.readByte(0); // получил hex to ascii
  int byte_in_str = 16;
  //int sizeof_chip = 256;  // Показываем 16 строк
  //int sizeof_chip = 128;  // Показываем 8 строк
  //int sizeof_chip = 96; // Показываем 6 строк
  int sizeof_chip = global_size_dump;
  int num_str_in_chip = sizeof_chip / byte_in_str;

  for(int i_1 = 0; i_1 < num_str_in_chip; i_1++)
  {
      lcd.clear();
      lcd.print(F("STRING # "));
      lcd.print(i_1);
      for (int i_2 = 0; i_2 < 17; i_2++)
      {
        lcd.setCursor(i_2,1);
        char a = (char)eeprom.readByte(i_2 + i_1 * byte_in_str); // Получаем ascii
        char b; //
        if (a < 32){ b = 32; } // если a 0 то ставим пробел HEX(32)
        else{ b = a; }
        lcd.print(b); // 15 31 47 63 79 95 111 127
        //lcd.setCursor(i_2,0);
        //Serial.println(eeprom.readByte(i_2 + i_1 * byte_in_str));
      }
      delay(1000);
  }
  lcd.clear();
  /*
  for (int i=0; i < 17; i++)
  {
    char a = (char)eeprom.readByte(i+i2); // Получаем ascii
    char b; //
    if (a < 32){ b = 32; } // если a 0 то ставим пробел HEX(32)
    else{ b = a; }
    lcd.print(b); // 15 31 47 63 79 95 111 127
    lcd.setCursor(i,0);
    Serial.println(eeprom.readByte(i+i2));
  }
  */
  power_off_for_chip();

  // Показываем текущий чип на экране
  database(global_id);
}

/************************************* ПРОВЕРКА КОНТАКТА НА ЧИПЕ *************************************/
void check_contact()
{
  // По умолчанию считается что контакта с чипом нет (если все хорошо то этого сообщения не увидите)
  lcd.clear(); lcd.print(F("CONTACT CHIP"));  lcd.setCursor(0,1); lcd.print(F("BAD"));
  byte address = 1;
  byte error = 0;
  for(address = 1 ; address < 127; address++ )
  {       
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0)
    {
      //Serial.println(F("Contact GOOD"));
      lcd.setCursor(0,1);
      lcd.print(F("GOOD"));
      break;
    }
  }
  delay(1000);
  // Показываем текущий чип на экране
  database(global_id);
}

/************************************* ТАЙМЕР ОБРАТНОГО ОТСЧЕТА *************************************/
void countdown_timer()
{
  int timer = 8; // Время которое ждем перед прошивкой чипа
  lcd.clear(); lcd.print(F("COUNTDOWN TIMER"));
  for(int i = timer; i > 0; i--)
  {
    lcd.setCursor(0,1);
    lcd.print(i);
    delay(1000); // Задержка в 1 сек перед повтором цикла
  }
}

/************************************* ОТЛАДКА *************************************/

/************************************* Узнаем сколько во время работы осталось RAM ******************************/
/*
//Использование
//Serial.println(memoryFree());

// Переменные, создаваемые процессом сборки,
// когда компилируется скетч
extern int __bss_end;
extern void *__brkval;
 
// Функция, возвращающая количество свободного ОЗУ (RAM)
int memoryFree()
{
   int freeValue;
   if((int)__brkval == 0)
      freeValue = ((int)&freeValue) - ((int)&__bss_end);
   else
      freeValue = ((int)&freeValue) - ((int)__brkval);
   return freeValue;
}

*/
Аватар пользователя
1dx   
Увидел чернила
  • Не в сети

Прилепить пост

Сообщение avds » Пн сен 03, 2018 3:47 pm

galavarez, я проверял дамп Ricoh SP 201HE для SP 211/213/220 нормально все, отдал клиенту все ок (не звонил)
Аватар пользователя
avds   
Понюхал тонер
  • Не в сети

Прилепить пост

Сообщение galavarez » Пн сен 03, 2018 6:41 pm

avds, спасибо что отписались, исправил описание на гитхабе.

1dx, на сколько я знаю в первой строке дампа это не серийник, а номер. Смысла его менять нет, даже не знаю почему у Вас все работает =)
С Вашего позволения я взял дамп и добавил его в рессетер (пока в конец очереди). Ребята по тестируют и скажут.


Скрытый текст +
https://github.com/Galavarez/Chip_Resetter
Аватар пользователя
galavarez   
Собрал картридж

Прилепить пост

Сообщение 1dx » Ср окт 17, 2018 12:58 pm

Ага, сорри, по серийникам и коду модели я напутал, виноват.

Можно просьбу еще? По адресам 0x41, 0x40 у Ricoh находятся данные о числе отпечатанных копий. Очень хочется вывести, скажем, на самую правую кнопку считывание этих данных, конвертацию в dec и вывод на дисплей. Иногда бывает очень нужно, для выяснения вопросов с клиентами. Я вот ни капельки не кодер, не умею. Можете добавить?
Аватар пользователя
1dx   
Увидел чернила
  • Не в сети

Прилепить пост

Сообщение galavarez » Ср окт 17, 2018 5:46 pm

1dx, на самую правую кнопку не получится т.к. это кнопка сброса ардуино, ее не переназначить.
Специально для Вас написал функцию и этот скетч.
По нажатию на кнопку Select (это самая левая кнопка), будут с читаны поля 0x41 и 0x40, объеденные в месте и переведены в десятичную систему, а так же показаны на экране.
Правда думаю будет больше вопросов чем ответов :-) у меня б.у. чипы показывали от 200 листов до 500 не более

ссылка на скетч
Скрытый текст +


p.s. Если буду много нуждающихся в этой функции, то можно будет подумать как это все получше расположить в обнуляторе.
Аватар пользователя
galavarez   
Собрал картридж

Прилепить пост

Сообщение 1dx » Чт окт 18, 2018 10:21 am

Большущее спасибо! Попробовал, вычитало из чипа. Функция для меня и вправду более важна, чем таймер.
Аватар пользователя
1dx   
Увидел чернила
  • Не в сети

Прилепить пост

Сообщение 1dx » Чт окт 18, 2018 4:05 pm

Ricoh SP277, вычитанный из стартового картриджа у нового принтера, и сделанный мной - надо проверить.
Вложения
sp277.rar
(291 байт) Скачиваний: 193
Аватар пользователя
1dx   
Увидел чернила
  • Не в сети

Прилепить пост

Сообщение galavarez » Чт окт 18, 2018 5:37 pm

1dx, спасибо за дамп, добавил в обнулятор Ваш отредактированный дамп. Пока в самом низу списка, после теста поставлю по возрастанию.
Так же сделал в основной ветке проверку отпечатанных страниц по кнопке select, может кому пригодится =)
Новый скетч на гитхабе.
Аватар пользователя
galavarez   
Собрал картридж

Прилепить пост

Сообщение Krepton85 » Чт окт 18, 2018 6:10 pm

1dx писал(а):Ага, сорри, по серийникам и коду модели я напутал, виноват.

Можно просьбу еще? По адресам 0x41, 0x40 у Ricoh находятся данные о числе отпечатанных копий. Очень хочется вывести, скажем, на самую правую кнопку считывание этих данных, конвертацию в dec и вывод на дисплей. Иногда бывает очень нужно, для выяснения вопросов с клиентами. Я вот ни капельки не кодер, не умею. Можете добавить?

Эта инфа 100% и распостроняется на все модели Рикох? И какой из этих 2-х байтов старший, а какой младший?
Аватар пользователя
Krepton85   
Разработчик PortableProg

Прилепить пост

Сообщение blod » Чт окт 18, 2018 7:35 pm

galavarez Не надо вставлять неправильный дамп SP-277 в прогер !! Прошивка от стартового картриджа , отредактирована неправильно , 408160 на 2,6к стр. , а по прошивке отпечатает страниц как стартовый чип , и серийник чипа не изменён , если этот дамп залить повторно в тот-же аппарат, то ошибка по картриджу обеспечена!! :((
В прогер , лучше дампы считанные с новых , максимальных по тонеру, чипов картриджей Ricoh SP- серии.
Аватар пользователя
blod   
Увидел чернила
  • Не в сети

Прилепить пост

Сообщение 1dx » Пт окт 19, 2018 10:47 am

Сначала 0х41, потом 0х40. То есть в прошивке видим 02 AB, а в калькулятор для конвертирования надо вбить AB 02.

Вообще хорошо бы разобраться побайтно, что в дампе за что отвечает, было б здорово.

Вот из интернета:

Аватар пользователя
1dx   
Увидел чернила
  • Не в сети

Прилепить пост

Сообщение Krepton85 » Пт окт 19, 2018 3:36 pm

Сначала 0х41, потом 0х40. То есть в прошивке видим 02 AB, а в калькулятор для конвертирования надо вбить AB 02.

В таком случае объеденяем ячейки так:
word counts_pages = (eeprom.readByte(0x41)<<8)|eeprom.readByte(0x40);
Аватар пользователя
Krepton85   
Разработчик PortableProg

Прилепить пост

Сообщение galavarez » Ср окт 31, 2018 3:42 pm

В общем долго ждать не пришлось, получил дамп с нового чипа sp 277 на 2.6.
Добавил его в обнулятор. По идее все должно быть с ним ок.
Аватар пользователя
galavarez   
Собрал картридж

Пред.

Вернуться в Своими руками

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

вверх
вниз
x

#{title}

#{text}