Reverse Engineering to Emulate Ink Cartridges for a Epson Printer using PIC18F

Reverse Engineering to Emulate Ink Cartridges for a Epson Printer

For the past two years, I’ve been planning to build myself a 3D printer from some old Inkjet printers that I had collected over the years. But not until two weeks ago had I actually started to work on it.

The 3D printer I want to made uses a ink jets to print a chemical onto a building platform. The building platform goes down as a new layer of powder is spread onto it. Then a chemical is sprayed from the print head that will cause powder to bind. If you want more information on these kinds of printers look here

My printer of choice was an old Epson Stylus C63 for these reasons:
1. The ink cartridges only supply ink, they do not have ink jet nozzles themselves
2. I can attach rubber hoses or some other form of tubing that allows me to print another chemical of my choosing
3. The print head nozzles uses a piezoelectric material to produce droplets of ink (lasts much longer than thermal inkjets)
4. Most service manuals for Epson Printers come with a detailed schematic of the main board.

Note: Due to certain circumstances, this printer had already been pulled apart.

The first thing I needed to do was get my printer running so I could plug my logic analyser in and look at the signals, the problem was that I was missing one ink cartridge so the printer refused to print, or do anything.
Due to my budget (jobless and about to start university) I decided to try and Emulate the missing cartridge, or all of them using one microcontroller, thus allowing me to move forward and using water for the print head instead of ink that stains.



Getting familiar with it

So in order to emulate the ink cartridges, I need to know how they work first. Luckily the ink cartridges in my printer have simple EEPROMs that hold the ink usage and other important information about the ink cartridge such as the expiration date, colour, serial number and so on.

Inside the print head, there is a circuit board with pads mapped out that are an exact mirror of the pads on the ink cartridges and a ribbon cable that connects this board up to the main board on pins 1 to 6.

A quick look at the schematic for the main board reveals that pins 1 – 6 are named CVDD, CSDA, CRST, GND, CSCK and COI.

With these signal names I decided it would be best to draw out a schematic of the connecting board as it was not present in the service manual. This revealed that CSDA, CSCK, CRST have 100KOhm Pull-Down resistors, a bit unusual in my opinion as it’s not like I2C (uses Pull-Up Resistors typically 1.8KOhms to 47KOhms). The COI signal connects serially to the ink cartridges but on the end is shorted to GND. Curiously I tested the continuity of the pads on the ink cartridges and found that they are shorted, this means that when COI is grounded, all ink cartridges are present.


Now that I know the signal names, I wanted to see what the signals themselves looked like.
I got out my soldering iron, a ribbon cable (used to be an IDE cable from an old computer) and a craft knife. I cut 6 wire wide ribbon cable about 30cm long, stripped the ends carefully using the craft knife (a lot easier to use a craft knife to strip a ribbon cable than a pair of clippers or pliers), and soldered them onto the circuit board that mates with the ink cartridges.
I also stripped the other ends and soldered on some pins so I could plug them into my logic analyser.After plugging in the logic analyser into the circuit board and having a look at the signals, I found that immediately the SCK, SDA look nothing like I2C, I’m pretty sure that Epson must have invented their own serial protocol for talking to the EEPROMs inside the ink cartridges.What I found is that CVDD gets powered up and shortly after, CRST and CSDA go up at the exact same time shortly followed by CSCK which pulses. CSDA changes on the Rising Edge of the CSCK and I’ll assume it gets read on the Falling Edge.
CSCK is Serial ClocK
CSDA is Serial Data
CRST is Reset
and CVDD is the power
Looks easy enough but I wanted more information about this protocol, were there any addresses being sent?

I turned up the sample rate on my logic analyser and found that there are 4 clock cycles, a pause, then 8 cycles, pause, 8 more and so on. The 4 clock cycles at the beginning gave me the idea that the first four could possibly be a 4 bit address of the ink cartridge. Still a lot of information was unknown about this protocol. So I did some research!

Googling around found nothing about this protocol, the next best place to look was in patents.
Yes, patents, I searched for “Epson SDA SCK RST memory eeprom” on   and one of the patents I found (US7660008 ) contained exactly what I was looking for. It outlined the SCK, SDA, RST and VDD of the protocol.
I’ll save you the hassle and point out what I found:
1. Flow chart diagrams describing what the Host and Slave does
2. A timing diagram of the protocol
3. The first 3 bits are a 3bit address followed by a Read/Write bit (Read = 0, Write = 1)
4. The address counter always starts at 0x00 and increments by 1 every clock cycle (This must mean it writes in bits, not bytes)
5. The moment RST goes low, the EEPROM stops everything and resets itself
6. There are 252 bits to read, the last 3 bits (actually they’re at the start) is the address of the ink cartridge.

Using what I had found, I decided to start writing code

Schematic Cartridges

Step 3: Basic Code Routines

What I wanted to do was read out the ROMs from the ink carts and then use those to try and emulate the missing ink cartridge I don’t have. This means creating a library that will act as a host to read the data but can also be used to emulate an ink cartridge.
Using previous knowledge from creating software based protocols, I created a header file with these functions:
• extern void epsnCartInit(void);
• extern void epsnCartStart(unsigned char addr, unsigned char write);
• extern void epsnCartStop(void);
• extern void epsnCartWrite(unsigned char data);
• extern unsigned char epsnCartRead(void);I also created the following definitions that help with remembering which pin was what:
For you microcontroller, you will need to modify these values to suit your application#define _ecSCKTRIS TRISCbits.TRISC0
#define _ecSDATRIS TRISCbits.TRISC1
#define _ecRSTTRIS TRISCbits.TRISC2
#define _ecVDDTRIS TRISBbits.TRISB1

#define _ecSCKLat LATCbits.LATC0
#define _ecSDALat LATCbits.LATC1
#define _ecRSTLat LATCbits.LATC2
#define _ecVDDLat LATBbits.LATB0

#define _ecSCK PORTCbits.RC0
#define _ecSDA PORTCbits.RC1
#define _ecRST PORTCbits.RC2
#define _ecVDD PORTBbits.RB1

#define wait() DelayUS(50)

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:

Leave a Comment

Your email address will not be published. Required fields are marked *

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