Banner publicitario de PCBWay

Proyecto Arduino Reset para Caja de Mantenimiento Canon MC-G02 (G2160 / G3160)

Este proyecto utiliza Arduino para restablecer el chip dentro del cartucho de mantenimiento MC-G02 de su impresora Canon, de modo que el chip vuelva a estar como nuevo y reutilice el cartucho una y otra vez.

¿Qué es el cartucho de mantenimiento?​

El cartucho de mantenimiento es un cartucho que se encuentra dentro de algunas impresoras, no se limita a Canon, es el lugar donde se almacenan las "tintas desperdiciadas". Este cartucho eventualmente se llenará y su impresora se negará a imprimir más. Entonces normalmente tendrás que comprar uno nuevo de Canon.

¿Qué es MC-G02?​

MC-G02 es un tipo de cartucho de mantenimiento que se utiliza en las impresoras recientes de la serie Canon PIXMA G, que incluye:

Versión de EE. UU.: G620/G1220/G2260/G3260

Versión china: G580/G680/G1820/G2820/G2860/G3820/G3860

(y otras versiones en otros países..)

¿Qué le impide reutilizar el cartucho de mantenimiento MC-G02?​

Puede desmontar la impresora de cartucho MC-G02 con bastante facilidad y puede limpiarla usted mismo y eliminar la tinta acumulada en su interior. Canon no utiliza un sensor para detectar cuánta tinta hay dentro del cartucho; en su lugar, hay un chip en el cartucho, que se comporta como un "contador" y aumenta cada vez que se utiliza el cartucho. Incluso si ha limpiado la tinta desperdiciada dentro del cartucho, el contador dentro del chip no disminuirá y la impresora seguirá negándose a imprimir.

Volver a este proyecto​

Este proyecto le permite "restablecer" el contador dentro del chip mencionado anteriormente. Entonces podrás reutilizar el cartucho MC-G02.

Uso​

Requisito previo​

Para utilizar este proyecto, necesita:

Conozca el uso básico de Arduino, como cargar un programa en Arduino y ejecutarlo, leer la salida del Serial Monitor.

Retire el chip del cartucho y conéctelo a Arduino.

Descripción general​

Este proyecto consta de un programa de lectura (volcado) y un programa de escritura.

El programa de escritura es literalmente el reiniciador del chip. Pero para poder utilizar el programa de escritura, necesitas una rom.

Para obtener una rom, necesitas:

  1. Consíguelo de otra persona que ya hizo el volcado, tal vez en Internet.
  2. volca una rom tu mismo.
La ROM volcada simplemente le permite restablecer el cartucho exactamente al mismo estado que cuando se volcó la ROM, por lo que se puede utilizar para restablecer el cartucho. Entonces, si desea desecharlo usted mismo, hágalo temprano, antes de que se llene el cartucho.

Conecta el chip a arduino​

Separe el cartucho de la impresora, retire el chip del cartucho y conecte los cables.

1711224075762.png

wire1.png
wire2.png
wire3.png

Esas dos resistencias son de 10k ohmios y se utilizan como resistencias "pull-up". El circuito es sugerido por [1].

Deshazte de la rom (si no puedes obtener una rom de otros)​

Abra el programa interno sketch_hack_readcon Arduino IDE, cárguelo en Arduino y ejecútelo.

Si todo es como se esperaba, obtendrá el siguiente resultado de Serial Monitor (use velocidad en baudios 9600):

Start Dumping...
Below is your rom:

const unsigned char my_rom1[] PROGMEM=
{
0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,...,
...
...
}


Entonces el {0xXX,0xXX,0xXX,0xXX,...}material es la rom que tiraste. Cada 0xXX representa un byte; debería obtener 2048 de esos bytes. Ya que el chip es una eeprom de 16Kbits. Guárdelo para usarlo en el futuro, mejor con el const unsigned char my_rom1[] PROGMEM=prefijo, para poder copiarlo completo cómodamente.

Si obtiene algo más como Wire Not Ready!!!, entonces debe haber algún problema. (por ejemplo, su cable no está conectado correcta o sólidamente).

Nota​

EssugirióEs obligatorio volcarlo 2 veces y asegurarse de que los 2 volcados sean idénticos, en caso de que obtenga un volcado dañado.

Nota 2​

Se recomienda encarecidamente cargar el sketch_hack_readprograma en su Arduino antes de conectar el chip del cartucho al circuito. Para que esté seguro en el momento de conectar su chip, el programa que se ejecuta en arduino es el correcto.

Escribe la rom volcada en el chip.​

Abra el programa interno sketch_hack_writecon Arduino IDE, copie todo const unsigned char my_rom1[] PROGMEM={0xXX,0xXX,0xXX,0xXX,...}y péguelo en el lugar correcto del programa abierto en Arduino IDE (hay un indicador para ayudarlo a ubicar el lugar).

cárguelo en Arduino y ejecútelo. Si todo es como se esperaba, obtendrá el siguiente resultado del Serial Monitor (velocidad en baudios 9600):

Start Writing Rom...
current writing page:0
current writing page:16
......
current writing page:112

Write Done!

Start Dumping for Verification...
Check if this dump matches with before by yourself:

const unsigned char my_rom1[] PROGMEM=
{
0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,...,
...
...
}


El programa primero escribe la ROM volcada en el chip y luego inicia un volcado de verificación. Al menos necesitas hacer una verificación visual rápida del valor: el volcado de verificación debe ser idéntico a la rom que usaste para escribir. Para mayor seguridad, se sugiere asegurarse de que esos valores sean idénticos mediante algunas herramientas de diferenciación (p. ej. vimdiff).

Nota​

Tanto el programa de lectura como el programa de escritura utilizaron [2] [3] como referencia durante la escritura.

Todo listo.​

El chip de su cartucho ahora está "restablecido". Inserte el chip nuevamente en el cartucho y conecte el cartucho a la impresora. (Es posible que desees limpiar/secar las tintas desperdiciadas en el interior antes de reutilizar el cartucho).

Preguntas y respuestas​

P: ¿Por qué necesito Arduino y conectar los cables? Escuché que se pueden restablecer los contadores de la impresora Canon simplemente presionando algunos botones de la impresora o usando el software "Serivice Tool".​

R: Esos métodos sólo funcionan con impresoras antiguas. Hasta donde yo sé, para las nuevas impresoras Canon con MC-G02, por el momento no se conocen métodos tan sencillos.

P: ¿Cuál es el chip dentro del MC-G02?​

R: Para el MC-G02 que compré, está etiquetado como 416RT, STMicroelectronicsque en realidad es un M24C16-R, la hoja de datos se puede encontrar en el sitio web de ST[4]. Parece que también hay chips etiquetados como G16 4G16, pero la función del chip debería ser compatible con 416RT.

P: ¿Este proyecto funciona para otros cartuchos?​

Podría funcionar también para otros cartuchos, sin modificaciones o pequeñas modificaciones, siempre que se utilice un chip similar.


Análisis básico del contenido del ROM.

Los 2048 bytes del chip están organizados en seis secciones distintas:

Sección 1 - 64 bytes .
Bytes 0-1: no estoy seguro de cuáles son (posiblemente dígitos de suma de verificación).
Bytes 2 a 11: los siguientes 10 bytes son el número de serie de 9 caracteres del cartucho (como valores little-endian de 16 bits) rellenados con un byte 0x00.
Bytes 12-13: no estoy seguro de cuáles son (posiblemente dígitos de suma de verificación)
Bytes restantes, todos 0x00

Sección 2 - duplicado de la sección 1

Sección 3 - 320 bytes

Bytes 0-1: 0xA5A5 en un cartucho nuevo, seguido de todos los 0x00
Bytes 0-257: datos hexadecimales seguidos de 62 0x00

Sección 4 - duplicado de la sección 3

Sección 5: 640 bytes

Bytes 0-1: 0xA5A5 en un cartucho nuevo, seguido de todos los 0x00
Bytes 0-513: datos hexadecimales seguidos de 126 0x00

Sección 6 - duplicado de la sección 5

Cada sección tiene bytes de suma de comprobación (¿el primero o los dos últimos bytes?), de modo que si agrega contenidos como números little-endian de 16 bits, cada sección suma 0xA5A5, ignorando cualquier desbordamiento.

Las secciones duplicadas son, presumiblemente, para mitigar la corrupción de datos. Hay exactamente el doble de datos en la sección 5 que en la sección 3, por lo que imagino que estas son tablas que registran algo sobre cada vez que se deposita tinta en el cartucho. También sospecho que la primera advertencia que se le da al usuario sobre el reemplazo del cartucho se da cuando se alcanza un cierto número de entradas y la impresora deja de imprimir por completo cuando las mesas están llenas o casi llenas.

Lo que muchos venden por todos lados y acá les comparto la ROM vacía.

Comparto esto porque:
Destesto la obsolescencia programada,
La gente siempre lucrando con las cosas
Acaban de borrar 2 repositorios con lo mismo en GitHub por compartir material protegido con derechos de autor y en los cuales no hay nada de derechos propietarios y si el moderador examina, verá que no tiene nada de propietario algo que el mismo autor ha compartido.




Creditos al autor Wangyu al publicarlo en la red, por su aporte, yo solo lo comparto
 

Adjuntos

  • Canon MC-G01 (Vacio) Bin Dump Formato C.rar
    284 bytes · Visitas: 125
  • sketch_hack_read.rar
    610 bytes · Visitas: 80
  • sketch_hack_write.rar
    1.1 KB · Visitas: 82
Este proceso funciona en la Megatank G3110?
Lea bien por favor mi estimado,
Se ve bien, las expresiones que usas me confunden completamente, pero por lo demás se ve interesante, aunque no tengo esas impresoras.
El usuario es chino, compartió el código y lo traduje con Google Translate, la idea es usar una ROM que he adjuntado, cargarla con Arduino y listo.
 
Descripción general
Este proyecto consta de un programa de lectura (volcado) y un programa de escritura.

El programa de escritura es literalmente el reiniciador del chip. Pero para poder utilizar el programa de escritura, necesitas una rom.


wire3.png

Buenas tardes
En tus paseos por China, ¿ Encontraste algo para realizar el reset de chip´s de impresoras Lexmark ?
Tienen bastante similitud con el de esta imagen.

1758327088353.png
 
Buenas tardes
En tus paseos por China, ¿ Encontraste algo para realizar el reset de chip´s de impresoras Lexmark ?
Tienen bastante similitud con el de esta imagen.

Ver el archivo adjunto 332152
Voy a buscar en Weibo, con mis amigos chinos, esos locos siempre tienen ese tipo de procesos, a veces los venden y a veces los comparten a cambio de fotos... aajajajajajaja ya fuera de bromas, si, voy a consultar con ellos o con los rusos, los últimos usan vpn por las restricciones impuestas por el Donald Cheeto Trump. Si encuentro algo te lo publico acá para que todos lo aprovechemos.
 
Buenas, una pregunta, tengo una impersora igual a la tuya pero el chip es el MC-G02, desconosco si la tuya trae ese mismo chip o el MC-G01, y si tiene el MC-g02 igual que la mia, ¿Al cargar los datos que compartieron modificaste algo? o tu chip era el MC-G01. Saludos
El chip MC-G02 no es compatible con el MC-G01, tendrás que comprar uno nuevo y leer su EEPROM para poder restablecerlo.
El proyecto que acá presento, se basa en el chip MC-G01, la Dump está también disponible. Pero no tengo Dump ni he probado con un cartucho MC-G02 como para apoyarte. Y no te recomiendo usar el Dump comprtido acá con el nuevo Cartucho MC-G02.

Aunque ya en el mercado están los restablecedores (resetters) y son baratos. Ya vienen listos para solo conectaerlos a presión mientras lo desbloqueas. Los asiáticos son muy buenos en este tipo de comercio.

1773410368815.png
 
Tiro una idea como para trabajar con otras marcas que tengan eeprom I2c; Es una base, hay que pulirlo...
Lo primero seria cambiar la dirección I2C (DEVICE_ADDRESS) mirando el hardware y luego editando en el programa la linea:

Código:
#define DEVICE_ADDRESS 0x50

Por lo general esa es la dirección estándar, pero puede pasar con algunas marcas que usen otras direcciones... dentro del IDE, hay un sketch sencillo para detetctar la dirección (I2C Scanner)… teniendo este dato, pasamos a ajustar el tamaño de lectura según hardware...
En el ejemplo del repositorio lee un 24C02 que tiene 256 bytes... Ahora, si la memoria es mas grande (un 24C16, por ejemplo), cambiamos el límite del bucle for en la función de lectura para no dejar datos fuera:

Código:
for (int i = 0; i < 256; i++)
  {
   Serial.print(eepromRead(i), HEX);
  }

Hasta acá, viene facil… ahora el tema esta en localizar el "Contador" por que cada empresa guarda los datos en distintos lugares; Por eso decía que seria bueno tener varios archivos de distintas marcas para armar un backup y ya saber las posiciones de cada cosa...
Con estos datos localizados, para adaptarlo a una marca nueva:
Usamos el sketch base del repo para hacer un Dump de la eeprom cuando esté lleno. Lo usamos hasta que baje un 10% y hacemos otro Dump… Comparamos ambos archivos y el offset (la posición) donde los números bajaron o subieron es donde esa marca guarda el tóner.
Con ese daro, modificamos la función resetChip() del repo para que escriba los valores del "chip lleno" solo en esas posiciones específicas.
No todo va a ser soplar y hacer botella... Hay que tener cuidado con el Checksum. No todas las marcas lo emplean, pero puede pasar que si cambiamos el contador pero no actualizamos el checksum, seguro la impresora va tirar "Error de cartucho".

Este es el sketch original del repo:

CSS:
//
//    FILE: Reset.ino
//  AUTHOR: Ludovic Guégan
// VERSION: 0.1
// PURPOSE: Reset chip for Ricoh SP112 toner
//    DATE: 2016-03-03
//     URL: https://github.com/lugu/reset_sp112
//
// Released to the public domain
//


#include <Wire.h>


// the content to flash on the eeprom to reset the chip.
// defines:
//     * unsigned int dump_bin_len;
//     * unsigned char dump_bin[];
#include "reset_bin.h"


// Set current address:
//    master send start condition
//    master send eeprom address + read bit
//    master send data address
//    master send start condition
unsigned int setCurrentAddress(int eeprom, unsigned int address) {


    Wire.beginTransmission(eeprom);


    byte size = Wire.write(address);
    if (size == 0) {
        Serial.println("Failed to write address");
        return 10;
    }
    byte error = Wire.endTransmission(false);
    if (error == 0) {
        // Serial.println("tranmission success");
    } else if (error == 1) {
        Serial.println("data too long to fit in buffer");
    } else if (error == 2) {
        Serial.println("receive NAK when transmiting address");
    } else if (error == 3) {
        Serial.println("receive NAK when transmiting data");
    } else if (error == 4) {
        Serial.println("other error");
    } else {
        Serial.println("unknown error");
    }


    // return error value
    return error;
}


// Current read:
//     master send eeprom address + read bit
//     device respond with data
//     master send stop condition
unsigned int printCurrentAddress(int eeprom) {
    byte size = Wire.requestFrom(eeprom, 1, true);
    if (size == 0) {
    }
    if (Wire.available()) {
        byte rdata = Wire.read();
        Serial.print("0x");
        Serial.print(rdata, HEX);
        Serial.println("");
        return 0;
    } else {
        Serial.println("no data available from device");
        return 1;
    }
}


// Current write:
//     master send eeprom address + write bit
//     master send data
//     master send stop condition
unsigned int randomWrite(int eeprom, unsigned int address, byte data) {


    Wire.beginTransmission(eeprom);


    byte size = Wire.write(address);
    if (size == 0) {
        Serial.println("Failed to write address");
        return 1;
    }
    size = Wire.write(data);
    if (size == 0) {
        Serial.println("Failed to write data");
        return 2;
    }


    byte error = Wire.endTransmission(true);
    if (error == 0) {
        // Serial.println("tranmission success");
    } else if (error == 1) {
        Serial.println("data too long to fit in buffer");
    } else if (error == 2) {
        Serial.println("receive NAK when transmiting address");
    } else if (error == 3) {
        Serial.println("receive NAK when transmiting data");
    } else if (error == 4) {
        Serial.println("other error");
    } else {
        Serial.println("unknown error");
    }


    delay(5); // wait 5 ms, a write cycle


    return error;
}


// Random read:
//    1. set current address
//    2. read current address
unsigned int printRandomAddress(int eeprom, unsigned int address) {


    if (setCurrentAddress(eeprom, address) != 0) {
        Serial.println("failed to set current address");
        return 1;
    }
    delay(5); // wait 5 ms between write and read


    if (printCurrentAddress(eeprom) != 0) {
        Serial.println("failed to read current address");
        return 2;
    }
    return 0;
}


// display the content of the eeprom
void eepromRead(unsigned int eeprom) {


    Serial.print("reading device ");
    Serial.print(eeprom, HEX);
    Serial.println("");


    unsigned int address;
    for (address = 0; address < 256; address++) {
        if (printRandomAddress(eeprom, address) != 0) {
            Serial.print("Read failed at ");
            Serial.print(address, HEX);
            Serial.println("!");
            break;
        }
    }
    Serial.println("read end.");
}


// erase the content of the eeprom
void eepromWrite(unsigned int eeprom, unsigned char data[],
        unsigned int data_length) {


    Serial.print("writing device ");
    Serial.print(eeprom, HEX);
    Serial.println("");


    unsigned int address;
    for (address = 0; address < data_length; address++) {
        if (randomWrite(eeprom, address, data[address]) != 0) {
            Serial.print("Write failed at ");
            Serial.print(address, HEX);
            Serial.println("!");
            break;
        }
    }
    Serial.println("write finished.");
}


// initialize serial connection and wait for user input.
// initialize i2c bus after user input.
void initialize(void) {


    Serial.begin(115200);
    while (!Serial.available()) {
        ; // wait for serial port to connect
    }
    Serial.println("Let's start!");


    // define the i2c bus speed
    // 400kHz, 800kHz or 1MHz
    unsigned int clock = 800000L;


    Wire.begin();
    Wire.setClock(clock);
    Serial.println("I2C bus initalized!");
}


// erase the content of the eeprom with the value of
void work(void) {


    // eeprom address on the i2c bus
    // 0x53 = 83 = 1010011 = 1010 A0=0 A1=1 A2=1
    unsigned int eeprom = 0x53;


    eepromRead(eeprom);
    eepromWrite(eeprom, dump_bin, dump_bin_len);
    eepromRead(eeprom);
}


void setup(void) {


    initialize();
    work();
}


void loop() {}


Supongamos que es OneWire, una posible edición de lectura podría ser:

Código:
#include <OneWire.h>
OneWire ds(10);

void leerOneWire() {
  byte addr[8];
  if (!ds.search(addr)) {
    Serial.println("No se detectó chip OneWire.");
    ds.reset_search();
    return;
  }


  ds.reset();
  ds.select(addr);
  ds.write(0xF0); // Comando estándar de "Read Memory"
  ds.write(0x00); // Dirección inicial (Byte Bajo)
  ds.write(0x00); // Dirección inicial (Byte Alto)


  for (int i = 0; i < 32; i++) { // Ejemplo leyendo 32 bytes
    byte data = ds.read();
    Serial.print(data, HEX);
    Serial.print(" ");
  }
}

En el caso de que sea SPI, podría ser:

Código:
#include <SPI.h>
const int CS_PIN = 10;


void leerSPI() {
  digitalWrite(CS_PIN, LOW); // Activa el chip
 
  SPI.transfer(0x03); // Comando estándar de "Read"
  SPI.transfer(0x00); // Dirección de memoria MSB
  SPI.transfer(0x00); // Dirección de memoria LSB


  for (int i = 0; i < 64; i++) {
    byte data = SPI.transfer(0x00); // Envía "nada" para recibir datos
    Serial.print(data, HEX);
    Serial.print(" ");
  }


  digitalWrite(CS_PIN, HIGH); // Desactiva el chip
}


Son solo ideas por si alguien algún dia toma la iniciativa de querer trabajar su propia versión multimarca/multiprotocolo....
 
Atrás
Arriba