Ricoh SP150 Hack

Posted on May 30, 2026

Most printers do not have a mechanism to measure the amount of ink left inside their cartridges. Therefore, instead of measuring ink, they use a print counter on the cartridge chip. When the counter reaches to zero, the cartridge becomes unusable, even if there is ink still left. That’s why filling the cartridge doesn’t work. The only “legal” solution is to throw away the old cartridge and get a new one. While searching for cartridges on the internet for my old Ricoh SP150 model printer, I came across a very useful blog. The blog explains how an old chip of the cartridge can be reset just with an Arduino and some wires.

Please visit the original blog post about this hack. I found it very informative and interesting. I wanted to post it here as a reference for future readers, including myself. And also as a way to preserve the information in that post.

Summary

Chip uses I2C protocol to communicate with the printer. The counter value could be set using the I2C protocol as well. Connect wires to the Arduino and the chip as shown in images, and use the code below to reset the chip. Adjust the pins as necessary.

Arduino wire connections Chip wire connections

// Update EEPROM_I2C_ADDRESS define value with the chip you want to reprogram
// 83 is Chip K - black
#define EEPROM_I2C_ADDRESS 83
#include <Wire.h>

byte KChipData[]={ 50,0,1,3,18,1,1,255,100,0,52,48,55,53,52,51,20,9,65,66,22,0,22,38,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,100,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0};
void setup() {

// find EEPROM_I2C_ADDRESS 
// WhatI2CAddress();
// return;

 byte WriteData[128];
 memcpy(WriteData,KChipData,128*sizeof(byte));

 // Start Wire and Serial bus
 Wire.begin();
 Serial.begin(9600);
 delay(1000);

Serial.println("Start");
Serial.println(" ");
delay(3000);
Serial.println("go");

if (0){ // set to 1 to write to chip
 Serial.println("Write 128 bytes:");
 byte wordaddress;

 for(byte i=0;i<128;i++){
   wordaddress = i;
   i2cwrite((byte)wordaddress,(byte)WriteData[i]);
   //Serial.print(wordaddress);
   //Serial.print(":");
   Serial.print(WriteData[i]);
   Serial.print(",");
 }
}

// Start Read chip
 Serial.println(" ");
 Serial.println("Read 128 bytes:");
 for(byte i=0;i<128;i++){
   byte readVale = i2cread(i);
   //Serial.print(i);
   //Serial.print(":");
   Serial.print(readVale);
   Serial.print(",");
 } 
 Serial.println(" "); 
 Serial.println("End");

}

void loop() {

}

void i2cwrite(byte address, byte data) {
 Wire.beginTransmission(EEPROM_I2C_ADDRESS);
 Wire.write((byte)address);
 Wire.write((byte)data);
 Wire.endTransmission();
 delay(20);
}

byte i2cread(byte address) {
  byte rData = 0;
  Wire.beginTransmission(EEPROM_I2C_ADDRESS);
  Wire.write((byte)address);
  Wire.endTransmission();

  Wire.requestFrom(EEPROM_I2C_ADDRESS,1);
  while (Wire.available()){
    rData = Wire.read();
    return rData;
  }
}

void WhatI2CAddress() {
  Serial.println("started");
  for(int i=0;i<128;i++){
    Wire.requestFrom(i,1); //request first data byte
    Serial.print(i);
    Serial.print(":");
    while(Wire.available()){
      byte c = Wire.read();
      Serial.print(c); //if data exist, print it out. That way you can identify which address.
    }
    Serial.println(" ");
    delay(5);
  }
}