Everything about the Canon W6400 and W8400

This is a followup post on my earlier post about chip resetting cartridges for the Canon ImagePrograf W6400 and W8400 series printers. I had the W8400D for quite a while, but haven’t used it a lot. Meanwhile I have bought a used W6400PG dirt cheap, with problematic heads and no ink.

The W6400 and W8400 has many secrets. But not so many now 😉

So on with the investigation.

THIS IS A WORK IN PROGRESS!

Using the worlds best research tool (the interwebz coupled with Google), I have found the service manuals, technical diagrams, user guides, firmware update tools and firmware. Also a lot of knowledge has been dug up, with various “crubles” of information found on Canon’s sites, forums, in readme files etc.

Resetting cartridges BCI-1411, BCI-1431, BCI-1451

Readily available on eBay are replacement “empty” chips for the wide format printers. But no resetters are available anywhere I could find. Previous investigations into the cartridges show that the chips are unencrypted serial eeproms with a capacity of 128 bytes.

A nice person called “rMud” posted some information as a comment on my previous post, which gave me enough information to get a chip resetter done. And it will cost you around $10,- if you build it yourself.

Cartridges are encoded with a header (CANON INC.), details about the cartridge type (1411, 1431, 1451 etc), dye/pigment flag, original capacity etc. Also the usage data are written to the cartridge in two seperate places, I think it’s a backup if the cartridge is removed while being written to.

An Arduino based chip resetter follows.

A simple chip resetter is inplemented with a Arduino Nano Pro. I used the model with onboard USB, but if you only want to reset chips I guess you could do without it.

ARDUINO NANO PRO CONNECTIONS

USB - computer
Pin4 - to cartridge pin4
Pin5 - to cartridge pin3
Pin6 - to cartridge pin2
Pin7 - to cartridge pin1
Pin8 - not connected
Pin9 - to loose wire, for touch input (triggers chip read)
Pin10 - to loose wire, for touch input (triggers chip reset)
GND - to cartridge pin5
5V - to cartridge pin6 (front right)

 

The idea is that you connect the chip to the Arduino, and touch the wire on pin 9 for 2 seconds. This triggers a read of the chip. You can check the status on the serial monitor. If everything goes well, you touch the other wire for two seconds. This resets the usage, writes the chip and finally verifies the written data. If the data write fails, you can just touch the second wire again to retry.

Heres the code:

/*
  eeprom class
*/

class m93C46 {
    void startbit();
    void enable_write();
    void disable_write();
    void busy();
    int8_t _cs1, _sck, _sdi, _sdo, _org;

  public:
    m93C46(int8_t, int8_t, int8_t, int8_t, int8_t);
    word read_word(byte);
    void write_word(byte, word);
    void erase_all();
    void write_all(word);
};

m93C46::m93C46(int8_t cs1, int8_t sck, int8_t sdi, int8_t sdo, int8_t org) {

  _cs1 = cs1;
  _sck = sck;
  _sdi = sdi;
  _sdo = sdo;
  _org = org;

  pinMode(_cs1, OUTPUT);
  pinMode(_sck, OUTPUT);
  pinMode(_sdi, OUTPUT);
  pinMode(_sdo, INPUT);
  pinMode(_org, OUTPUT);
  digitalWrite(_cs1, LOW);
  digitalWrite(_sck, LOW);
  digitalWrite(_sdi, LOW);
  digitalWrite(_sdo, HIGH);
  digitalWrite(_org, LOW);
}

word m93C46::read_word(byte address) {
  bitSet(address, 7);
  bitClear(address, 6);
  startbit();
  /*  digitalWrite(_sdi,HIGH);
    digitalWrite(_sck,HIGH);
    digitalWrite(_sck,LOW);*/
  shiftOut(_sdi, _sck, MSBFIRST, address);
  byte data = shiftIn(_sdo, _sck, MSBFIRST);
  byte data2 = shiftIn(_sdo, _sck, MSBFIRST);
  digitalWrite(_cs1, LOW);
  return word(data2, data);
}

void m93C46::write_word(byte address, word data) {
  bitClear(address, 7);
  bitSet(address, 6);
  enable_write();
  startbit();
  /*digitalWrite(_sdi,LOW);
  digitalWrite(_sck,HIGH);
  digitalWrite(_sck,LOW);*/
  shiftOut(_sdi, _sck, MSBFIRST, address);
  shiftOut(_sdi, _sck, MSBFIRST, lowByte(data));
  shiftOut(_sdi, _sck, MSBFIRST, highByte(data));
  digitalWrite(_cs1, LOW);
  delay(5);
  disable_write();
}

void m93C46::startbit() {
  digitalWrite(_sck, LOW);
  digitalWrite(_cs1, HIGH);
  digitalWrite(_sdi, HIGH);
  digitalWrite(_sck, HIGH);
  digitalWrite(_sck, LOW);
}


void m93C46::enable_write() {
  startbit();
  /*  digitalWrite(_sdi,LOW);
    digitalWrite(_sck, HIGH);
    digitalWrite(_sck, LOW);*/
  shiftOut(_sdi, _sck, MSBFIRST, B00110000);
  digitalWrite(_cs1, LOW);
}

void m93C46::disable_write() {
  startbit();
  /*digitalWrite(_sdi,LOW);
  digitalWrite(_sck, HIGH);
  digitalWrite(_sck, LOW);*/
  shiftOut(_sdi, _sck, MSBFIRST, B00001111);
  digitalWrite(_cs1, LOW);
}

void m93C46::erase_all() {
  startbit();
  /*digitalWrite(_sdi,LOW);
  digitalWrite(_sck, HIGH);
  digitalWrite(_sck, LOW);*/
  shiftOut(_sdi, _sck, MSBFIRST, B00100000);
  digitalWrite(_cs1, LOW);
  delay(5);
  busy();
}

void m93C46::write_all(word data) {
  byte address = B00010000;
  enable_write();
  startbit();
  /*digitalWrite(_sdi,LOW);
  digitalWrite(_sck,HIGH);
  digitalWrite(_sck,LOW);*/
  shiftOut(_sdi, _sck, MSBFIRST, address);
  shiftOut(_sdi, _sck, MSBFIRST, highByte(data));
  shiftOut(_sdi, _sck, MSBFIRST, lowByte(data));
  digitalWrite(_cs1, LOW);
  delay(5);
  disable_write();
}


void m93C46::busy() {
  digitalWrite(_cs1, HIGH);
  do {
    delay(50);
  } while (digitalRead(_sdo) == 0);
  digitalWrite(_cs1, LOW);
}

/*
  CAPACITIVE TOUCH
*/
// readCapacitivePin
//  Input: Arduino pin number
//  Output: A number, from 0 to 17 expressing
//  how much capacitance is on the pin
//  When you touch the pin, or whatever you have
//  attached to it, the number will get higher
#include "pins_arduino.h" // Arduino pre-1.0 needs this
uint8_t readCapacitivePin(int pinToMeasure) {
  // Variables used to translate from Arduino to AVR pin naming
  volatile uint8_t* port;
  volatile uint8_t* ddr;
  volatile uint8_t* pin;
  // Here we translate the input pin number from
  //  Arduino pin number to the AVR PORT, PIN, DDR,
  //  and which bit of those registers we care about.
  byte bitmask;
  port = portOutputRegister(digitalPinToPort(pinToMeasure));
  ddr = portModeRegister(digitalPinToPort(pinToMeasure));
  bitmask = digitalPinToBitMask(pinToMeasure);
  pin = portInputRegister(digitalPinToPort(pinToMeasure));
  // Discharge the pin first by setting it low and output
  *port &= ~(bitmask);
  *ddr  |= bitmask;
  delay(1);
  uint8_t SREG_old = SREG; //back up the AVR Status Register
  // Prevent the timer IRQ from disturbing our measurement
  noInterrupts();
  // Make the pin an input with the internal pull-up on
  *ddr &= ~(bitmask);
  *port |= bitmask;

  // Now see how long the pin to get pulled up. This manual unrolling of the loop
  // decreases the number of hardware cycles between each read of the pin,
  // thus increasing sensitivity.
  uint8_t cycles = 17;
  if (*pin & bitmask) {
    cycles =  0;
  }
  else if (*pin & bitmask) {
    cycles =  1;
  }
  else if (*pin & bitmask) {
    cycles =  2;
  }
  else if (*pin & bitmask) {
    cycles =  3;
  }
  else if (*pin & bitmask) {
    cycles =  4;
  }
  else if (*pin & bitmask) {
    cycles =  5;
  }
  else if (*pin & bitmask) {
    cycles =  6;
  }
  else if (*pin & bitmask) {
    cycles =  7;
  }
  else if (*pin & bitmask) {
    cycles =  8;
  }
  else if (*pin & bitmask) {
    cycles =  9;
  }
  else if (*pin & bitmask) {
    cycles = 10;
  }
  else if (*pin & bitmask) {
    cycles = 11;
  }
  else if (*pin & bitmask) {
    cycles = 12;
  }
  else if (*pin & bitmask) {
    cycles = 13;
  }
  else if (*pin & bitmask) {
    cycles = 14;
  }
  else if (*pin & bitmask) {
    cycles = 15;
  }
  else if (*pin & bitmask) {
    cycles = 16;
  }

  // End of timing-critical section; turn interrupts back on if they were on before, or leave them off if they were off before
  SREG = SREG_old;

  // Discharge the pin again by setting it low and output
  //  It's important to leave the pins low if you want to
  //  be able to touch more than 1 sensor at a time - if
  //  the sensor is left pulled high, when you touch
  //  two sensors, your body will transfer the charge between
  //  sensors.
  *port &= ~(bitmask);
  *ddr  |= bitmask;

  return cycles;
}

/*
  HEX utils
*/
void PrintHex16(word data) // prints 16-bit data in hex with leading zeroes
{
  uint8_t MSB = byte(data >> 8);
  uint8_t LSB = byte(data);

  if (MSB < 0x10) {
    Serial.print("0");
  } Serial.print(MSB, HEX); Serial.print(" ");
  if (LSB < 0x10) {
    Serial.print("0");
  } Serial.print(LSB, HEX); Serial.print(" ");

}

byte HexDigit(byte c)
{
  if (c >= '0' && c <= '9') {
    return c - '0';
  } else if (c >= 'a' && c <= 'f') {
    return c - 'a' + 10;
  } else if (c >= 'A' && c <= 'F') {
    return c - 'A' + 10;
  } else {
    return -1;   // getting here is bad: it means the character was invalid
  }
}

byte HexByte(byte a, byte b)
{
  if (a < 0 || b < 0) {
    return -1;  // an invalid hex character was encountered
  } else {
    return (HexDigit(a) * 16) + HexDigit(b);
  }
}

/*
  Endianess utilities
*/
word SwapEndian(word val)
{
  return (val << 8) | (val >> 8);
}

unsigned long SwapEndian(unsigned long val)
{
  return (val << 24) | ((val << 8) & 0x00ff0000) |
         ((val >> 8) & 0x0000ff00) | (val >> 24);
}

/*
  status LED vars
*/
const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;

/*
  BCI resetter stuff from here
*/

typedef union usage {
  struct {
    unsigned long remaining;
    unsigned long used;
    word a;
    word b;
    word checksum; // $55aa - sum remaining1+used1+a1+b1
  } data;
  word w[7];
  byte b[14];
};

typedef union remaining {
  struct {
    unsigned long remaining;
    word a;
    word b;
    word zeros2;
    word checksum;
  } data;
  word w[6];
  byte b[12];
};

typedef union eeprom_type {
  struct {
    char vendor[10]; //0-4
    word cartridge; //5
    char color[2]; //6
    unsigned long serial; //7-8
    word type; //9
    unsigned long unknown_10; //10-11
    unsigned long serial2; //12-13
    word zeros_14; //14
    union usage usage1; //15-21
    union usage usage2; //22-28
    word zeros_29; //29
    char type_text[4]; //30-31
    word zeros_32; //32
    word checksum_static; //33
    unsigned long capacity; //34-35
    union remaining remaining1; //36-41
    union remaining remaining2; //42-47
    word zeros_rest[16];
  } data;
  word w[64];
  byte b[128];
};

union eeprom_type eeprom_data;

m93C46 chip(7, 6, 4, 5, 8);

word checksum_usage(union usage data) {
  word checksum = (word)0x55aa;
  for (byte i = 0; i < 6; i++) {
    checksum -= SwapEndian(data.w[i]);
  }
  return SwapEndian(checksum);
}

word checksum_remaining(union remaining data) {
  word checksum = (word)0x55aa;
  for (byte i = 0; i < 5; i++) {
    checksum -= SwapEndian(data.w[i]);
  }
  return SwapEndian(checksum);
}

int mode = 0; // 0 = nothing read, 1 = eeprom ok new, 2 = eeprom ok used, 11 = eeprom generic error, 12 = checksum1 error, 13= checksum2 error
int touch1 = 0;
int touch2 = 0;

int _read = 0; int _write = 0; // touch counter
int _reset = 0;

String incoming = "";

void validateEeprom() {
  if (memcmp("CANON INC.", eeprom_data.data.vendor, 10) != 0) {
    Serial.println(F("VENDOR data mismatch"));
    mode = 10;
  };
  if (eeprom_data.data.usage1.data.checksum != checksum_usage(eeprom_data.data.usage1)) {
    Serial.println(F("CHECKSUM error for usage1"));
    mode = 11;
  };
  if (eeprom_data.data.remaining1.data.checksum != checksum_remaining(eeprom_data.data.remaining1)) {
    Serial.println(F("CHECKSUM error for remaining1"));
    mode = 11;
  };
  if (eeprom_data.data.usage2.data.checksum != checksum_usage(eeprom_data.data.usage2)) {
    Serial.println(F("CHECKSUM error for usage2"));
    mode = 12;
  };
  if (eeprom_data.data.remaining2.data.checksum != checksum_remaining(eeprom_data.data.remaining2)) {
    Serial.println(F("CHECKSUM error for remaining2"));
    mode = 12;
  };

  if (SwapEndian(eeprom_data.data.usage1.data.used) == 0) {
    Serial.println(F("Cartridge is NEW"));
    mode = 1;
  } else {
    Serial.println(F("Cartridge is USED"));
    mode = 2;
  }

  Serial.print(F("Cartridge is a ")); Serial.print(SwapEndian(eeprom_data.data.cartridge), HEX); Serial.print("-"); Serial.print((char)eeprom_data.b[12]); Serial.println((char)eeprom_data.b[13]);
  Serial.print(F("Serial no: "));   Serial.println(SwapEndian(eeprom_data.data.serial));

  Serial.print(F("Capacity HARD CODED: ")); Serial.print(SwapEndian(eeprom_data.data.capacity)); Serial.println();
  Serial.print(F("1 Remaining ink: ")); Serial.print(SwapEndian(eeprom_data.data.usage1.data.remaining)); Serial.println();
  Serial.print(F("1 Used ink: ")); Serial.print(SwapEndian(eeprom_data.data.usage1.data.used)); Serial.println();
  Serial.print(F("1 Remaining ink2: ")); Serial.print(SwapEndian(eeprom_data.data.remaining1.data.remaining)); Serial.println();

  Serial.print(F("2 Remaining ink: ")); Serial.print(SwapEndian(eeprom_data.data.usage2.data.remaining)); Serial.println();
  Serial.print(F("2 Used ink: ")); Serial.print(SwapEndian(eeprom_data.data.usage2.data.used)); Serial.println();
  Serial.print(F("2 Remaining ink2: ")); Serial.print(SwapEndian(eeprom_data.data.remaining2.data.remaining)); Serial.println();
  Serial.println();
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.setTimeout(1500UL); // 1.5secs
  Serial.println(F("Canon BCI resetter ready"));

  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  touch1 = readCapacitivePin(9);
  touch2 = readCapacitivePin(10);

  if (touch1 > 1) _read++; else _read = 0;
  if (touch2 > 1) _reset++; else _reset = 0;

  if (Serial.available()) {
    char incoming[4]; int error = 0;
    incoming[3] = 0;
    Serial.println(F("Incoming data transmission ... stand by ;)"));
    if (Serial.peek() == 'W') {
      _write = 7;
      while (Serial.available()) Serial.read();
    } else if (Serial.peek() == 'R') {
      _read = 7;
      while (Serial.available()) Serial.read();
    } else {
      byte i = 0;
      while (i < 128) {
        while (Serial.available() < 3) delay(5);
        incoming[0] = Serial.read();
        incoming[1] = Serial.read();
        incoming[2] = Serial.read();
        if (incoming[2] == 10 || incoming[2] == 13 || incoming[2] == 32) {
          //Serial.print(incoming[0]); Serial.print(incoming[1]); Serial.print(" "); Serial.print(HexByte(incoming[0], incoming[1]), HEX);
          eeprom_data.b[i] = HexByte(incoming[0], incoming[1]);
        } else {
          Serial.println(F("Invalid data recieved"));
          error = 1;
          while (Serial.available()) Serial.read();
          break;
        }
        // Serial.print(i); Serial.print(" ");
        if (i % 2 == 1) PrintHex16(eeprom_data.w[i / 2]); if (i % 16 == 15) Serial.println();
        i++;
      }
      if (!error) {
        Serial.println(F("128 hexbytes recieved. Validating data."));
        validateEeprom();
      }
    }
  }

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }

  if (_read > 6) { // read eeprom
    _read = 0; // reset button counter

    for (int i = 0; i < 64; i++) {
      word data = chip.read_word(i);
      eeprom_data.w[i] = data;
      PrintHex16(SwapEndian(eeprom_data.w[i]));
      if (i % 16 == 15) Serial.println();
    }
    Serial.println();

    validateEeprom();
  }

  if (_reset > 6) {
    _reset = 0;

    Serial.println(F("Resetting cartridge to NEW state"));

    eeprom_data.data.usage1.data.remaining = eeprom_data.data.capacity;
    eeprom_data.data.usage2.data.remaining = eeprom_data.data.capacity;
    eeprom_data.data.usage1.data.used = 0;
    eeprom_data.data.usage2.data.used = 0;
    eeprom_data.data.usage1.data.checksum = checksum_usage(eeprom_data.data.usage1);
    eeprom_data.data.usage2.data.checksum = checksum_usage(eeprom_data.data.usage2);

    eeprom_data.data.remaining1.data.remaining = eeprom_data.data.capacity;
    eeprom_data.data.remaining2.data.remaining = eeprom_data.data.capacity;
    eeprom_data.data.remaining1.data.checksum = checksum_remaining(eeprom_data.data.remaining1);
    eeprom_data.data.remaining2.data.checksum = checksum_remaining(eeprom_data.data.remaining2);

    _write = 7;
  }
  if (_write > 6 and mode != 10) { // reset eeprom
    _write = 0; // reset button counter

    for (int i = 0; i < 64; i++) {
      chip.write_word(i, eeprom_data.w[i]);
      delay(20);
    }
    Serial.println(F("Chip has been written"));

    union eeprom_type eeprom_data2;
    for (int i = 0; i < 64; i++) {
      word data = chip.read_word(i);
      eeprom_data2.w[i] = data;
      PrintHex16(SwapEndian(eeprom_data2.w[i]));
      if (i % 16 == 15) Serial.println();
    }
    if (memcmp(&eeprom_data, &eeprom_data2  , 128) != 0) {
      Serial.println(F("Eeprom data validation failed"));
    }
  }

  delay(300);
}

If you send a “R”+newline, you trigger a read (as if you held the first wire). A “W” writes the currently contained data to the eeprom. Also you can send 128 hex bytes (00 00 00 etc), and the program will write these data to the eeprom. (You can use this feature to reset MT tanks, se hex dump below)

Resetting maintenance cartridges

These chips do not have a usage counter, as they are not meant to be removed and put back in at a later time. When they’re new, they just state that they are a “single cartridge, looking for a spouse”. Insert them into a printer, and the printer writes its serial number and a running cartridge number onto the eeprom. The cartridge can not be used in another printer, and if you remove it and put in a new, you can not use the first cartridge anymore. Or so it seems …

You can reset the internal counter on the printer, with this procedure:

Hold ROLL + INFORMATION and press POWER to turn on printer. When display says "Initializing" you can let go of the two buttons. There will be an S in the upper right corner, if you did this right.

Now press online twice, to get to the SERVICE MENU. Go to INITIALIZE, W-INK and hold OK a couple of seconds. It should have cleared the MT cartridge.

If you wait too long, and fill the MT cartridge completely, the printer will error out and you can not enter the service menu. You can reset the cartridge by writing this HEX code to the eeprom (using the above Arduino solution):

00 10 43 41 4E 4F 4E 20 49 6E 63 2E 31 34 33 31
00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 E9
00 10 43 41 4E 4F 4E 20 49 6E 63 2E 31 34 33 31
00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 E9
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

PLEASE REMEMBER TO DRAIN THE INK FROM THE MT CARTRIDGE and replace the wick/padding, or it will make a horrible mess on your floor.

To sum things up:

  • Ink tanks can be reset quite easily, but requires a little hardware and software
  • The print heads BC-1300, BC-1350, BC-1400 are *THE SAME*. They contain an EEPROM which tells the printer what kind of head it is
  • The DYE and PIGMENT models are (as far as I can tell) excactly the same. Again the difference is in the firmware. I have NO idea how to flash from one type of firmware to another at the moment.

This Post Has 15 Comments

  1. Alberto

    Hi,

    Do you know at this moment where can I find a cartridge Resetter ?
    It’a not an easy task to make one.
    Put the Canon W8400PG or W6400PG series in a very large plastic bag with zipper closed, and open only for printing avoid clogged nozzles in the print head.

    Alberto

  2. lkarlslund

    No, I do not know of a commercial product offering. You can build it yourself, like I did – or buy ready to use chips on ebay/aliexpress.

  3. Alberto

    Hi lkarlslund

    Thank you for your prompt response.
    Why don’t you produce and sell ?
    The colors more prone to cloggs in the print head of Canon W series large format printers are the extremes in the print head the yellow and the black, why is that ?

    Alberto

  4. lkarlslund

    I’ll leave the chinese to do the producing. Everything is here 😉

    Yellow is horrible, also magenta is bad. In my experience black dissolves easily in an water/ammonia mix.

  5. Coen

    Hi Build the chip resetter but the data out put is
    Canon BCI resetter ready
    Incoming data transmission … stand by 😉
    FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

    VENDOR data mismatch
    CHECKSUM error for usage1
    CHECKSUM error for remaining1
    CHECKSUM error for usage2
    CHECKSUM error for remaining2
    Cartridge is USED
    Cartridge is a FFFF-ÿÿ
    Serial no: 4294967295
    Capacity HARD CODED: 4294967295
    1 Remaining ink: 4294967295
    1 Used ink: 4294967295
    1 Remaining ink2: 4294967295
    2 Remaining ink: 4294967295
    2 Used ink: 4294967295
    2 Remaining ink2: 4294967295

    Any advice please thanks

  6. JP

    Hello,
    does anyone HEX code of EEPROM printhead BC-1350.
    Thank you for your help

  7. Jerome

    Hello,

    Very interesting read.

    Did you investigate about pinout on BC1350 printhead? I have a printhead from a W6400PG which reports that it has a bad checksum(or something similar). There are 6 pins standing apart on the printhead, I suppose these are the 6 pins for the eeprom, yet if I use the above procedure it reports only “00 00 FF FF …” and repeats it. I would have expected to have at least the vendor data. I tried left to right and right to left pinouts, same result in both cases.

    Any info about the printhead would be useful, thanks!

    Thanks

  8. lkarlslund

    Honestly I haven’t had the time to tinker more with this. Actually I bought a W8400PG which had problems, and tried to tinker with that. But too many projects and too little time. You can find the printhead pinout in the service diagrams for the W6400/W8400. I assume it would be pretty trivial to deduce the EEPROM contents, having enough print head HEX samples to work with.

  9. Vidmar Slavko

    Hello all,

    I accidentally broke chip on the MT cartridge.Does anyone know how I can print without
    chip?
    thank you ,I would be grateful.

    Slavko V.

  10. Janezki

    Hi
    Old topic but do someone give me a hand . Where do i get or found technical diagrams of this Canon W6400 printer to be shure ink tank pinouts. Worked reseter with andruino uno and all elses. But maybe chip pinouts is not so shure.

  11. Timo

    Thank you for this great instruction. It takes 15 minutes for me for flash arduino and build a connector for the ink cartridges. Everything is working fine <3

  12. Paul

    Hi Timo
    Any chance you could take a photo how does the final connection. Look like ?
    Thank you
    Paul

  13. Matt

    Anyone tested this on the BC1350 printhead yet?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.