Help identifying a two-contact make-up fluid cartridge chip — Sellenicode S-Jet900

Hi everyone,

We use a Sellenicode S-Jet900 continuous inkjet printer at our business. I’m trying to identify the chip on its ADENTECH SJ3024M, 0.75-litre make-up fluid cartridge.

Our longer-term goal is to understand whether the cartridge can be reused. For now, we want to identify the interface and read any accessible data without modifying it.

The PCB has two gold contact pads and a six-pin component labelled U1. The IC marking is not readable in our photos. The board markings are SOP-MHB, ZLW Z05, 21.12.15 and SOL / INK. No antenna coil is visible.

We have two used, empty cartridges and can obtain a sealed, unused cartridge for comparison. We have not taken electrical measurements yet. The pinout, operating voltage and protocol are unknown.

I found an Arduino forum discussion about a Videojet make-up cartridge using a DS2431, but ours is a different cartridge, so I’m not assuming compatibility.

Does anyone recognise this board? What non-destructive checks would help identify the contacts and interface? Once identified, what equipment would you recommend for a read-only attempt?

I can provide close-up photos of both sides. Any advice or pointers to similar projects would be appreciated.

Put a "raking" light behind the chip so the light bounces directly into the camera lens rather than being scattered. Some labeling is smooth from a LASER etcher.

That's a weird circuit. There seem to be only two pins used in total. Any ordinary IC would generally have a GND and a VCC for power and functions on the other pins. However, here, the remaining 4 pins are just shorted together with no vias, so they appear not to be connected to anything except themselves. So what function would that serve exactly? The vias that are present link the connected pins to two large pads on the other side so there must be a reason for connecting them. Could it simply send a code in some way when power is applied to the contacts to identify the cartridge?

To clarify how the printer behaves: once the make-up cartridge is reported as fully used up, refilling the same cartridge with fluid does not restore operation. The printer still refuses to draw make-up fluid from it. We want to understand how the used-up state is tracked: in the cartridge chip, in the printer’s memory linked to the cartridge ID, or through a combination of both.

it sounds to me like one of the 1-wire ID chips like a DS2401 Silicon Serial Number. Or a 1-wire memory chip with a unique serial number.

Would be worth the time to see if it can be read like one of those.

Thanks, that gives us a useful direction. The pinout and operating voltage are still unknown. What checks would you recommend before attempting a read-only 1-Wire test? If it is an ID-only chip such as the DS2401, could the printer be tracking the used-up state against its serial number?

If it's a serial-number-only device one way to use it would be that the printer would write its unique serial number in nonvolatile memory and then not allow the use of a filled cartridge with the same serial number. There are other 1-wire devices with read/write capability that could be used in an appropriately different scheme.

I would just try to read it and see what information it contains and what 1-wire device that might line up with. If successful, then maybe you can figure out how to counterfeit one. Analog will sell you devices with a certain range of numbers so the printer firmware could check to see if the replacement is in that range, for example.

It's an RFID transponder.

Kuerig defeats all the newest hacks so you drink their one cup of coffee.

Thanks for your help. I took a clearer photo and can now read “GXCAS” and “28E01” on the chip. It appears to be a GX28E01, which the manufacturer describes as a 1-Wire EEPROM with SHA-1 authentication.

The printer stops drawing make-up fluid once the cartridge is reported as used up, even after refilling it. We still don’t know where the used-up state is stored.

Our first goal is to read the ROM ID and, if possible, the memory without modifying anything. Does anyone have experience with this exact chip or access to its full command documentation? The public short datasheet does not provide the memory commands.


Sometime the smart engineer works on the smart interface while the interns work on the rest. Maybe the widget in question can be bypassed by a jumper.

A quick query of ChatGPT produced this:

readContents.ino
#include <OneWire.h>

// DS28E01 data pin connected here.
// Use an external pullup resistor from DATA to +5V.
// For the DS28E01, Maxim recommends a relatively strong pullup;
// 2.2k is a good starting value.
const byte ONE_WIRE_PIN = 2;

OneWire ow(ONE_WIRE_PIN);

byte rom[8];

// ------------------------------------------------------------
// Print one byte as two hex digits
// ------------------------------------------------------------
void printHex(byte b) {
  if (b < 0x10)
    Serial.print('0');

  Serial.print(b, HEX);
}


// ------------------------------------------------------------
// Read and display the 64-bit ROM ID
// ------------------------------------------------------------
bool readRom() {
  if (!ow.reset()) {
    Serial.println("No 1-Wire device detected.");
    return false;
  }

  // READ ROM command
  // This assumes ONLY ONE 1-Wire device is connected.
  ow.write(0x33);

  for (int i = 0; i < 8; i++)
    rom[i] = ow.read();

  Serial.println();
  Serial.println("64-bit ROM contents:");

  Serial.print("Family:        0x");
  printHex(rom[0]);
  Serial.println();

  Serial.print("Serial number: ");

  // Serial number is bytes 1 through 6
  for (int i = 6; i >= 1; i--) {
    printHex(rom[i]);
  }
  Serial.println();

  Serial.print("CRC:           0x");
  printHex(rom[7]);
  Serial.println();

  byte crc = OneWire::crc8(rom, 7);

  Serial.print("Calculated CRC: 0x");
  printHex(crc);
  Serial.println();

  if (crc == rom[7]) {
    Serial.println("ROM CRC OK");
    return true;
  } else {
    Serial.println("ROM CRC ERROR");
    return false;
  }
}


// ------------------------------------------------------------
// Read EEPROM beginning at address 'address'
//
// DS28E01 EEPROM:
//   Page 0: 0x0000 - 0x001F
//   Page 1: 0x0020 - 0x003F
//   Page 2: 0x0040 - 0x005F
//   Page 3: 0x0060 - 0x007F
// ------------------------------------------------------------
void readMemory(uint16_t address, byte *buffer, int count) {
  if (!ow.reset()) {
    Serial.println("Device disappeared!");
    return;
  }

  // Since we know the ROM number, address this particular device.
  ow.select(rom);

  // DS28E01 READ MEMORY command
  ow.write(0xF0);

  // Target address, least significant byte first.
  ow.write(address & 0xFF);         // TA1
  ow.write((address >> 8) & 0xFF);  // TA2

  for (int i = 0; i < count; i++)
    buffer[i] = ow.read();
}


// ------------------------------------------------------------
// Dump all 128 bytes
// ------------------------------------------------------------
void dumpEEPROM() {
  byte data[16];

  Serial.println();
  Serial.println("DS28E01 EEPROM dump:");
  Serial.println();

  for (uint16_t address = 0; address < 128; address += 16) {

    readMemory(address, data, 16);

    // Address
    Serial.print("0x");
    if (address < 0x10)
      Serial.print("00");
    else if (address < 0x100)
      Serial.print('0');

    Serial.print(address, HEX);
    Serial.print(":  ");

    // Hex representation
    for (int i = 0; i < 16; i++) {
      printHex(data[i]);
      Serial.print(' ');
    }

    Serial.print("  ");

    // ASCII representation
    for (int i = 0; i < 16; i++) {
      if (data[i] >= 32 && data[i] <= 126)
        Serial.write(data[i]);
      else
        Serial.print('.');
    }

    Serial.println();
  }
}


void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println();
  Serial.println("DS28E01-100 Reader");
  Serial.println("===================");

  if (readRom()) {
    dumpEEPROM();
  }
}


void loop() {
  // Nothing further to do.
}

Compiles for Uno R3, untested, looks like it will work.

A more thorough datasheet. https://taoic.oss-cn-hangzhou.aliyuncs.com/8676/product/STD_1640765578000.pdf

One thing to be aware of with this device is since it uses SHA-1, writing to the one from your printer cartridge will not be possible.

Write access requires knnowledge of the secret and the capability of computing and transmitting a 160-bit MAC as authorization.

If you can figure out how to program a blank chip to mimic one from a new cartridge then this won't be a problem since you will not need to write to the original.

After studying the data sheet a bit, I have concluded that you don't need to be particularly clever to thwart any attempt at bypassing the copy protection.

If you have a scope, you can determine which wire is common and which is the data line. I agree with @EmilyJane that it may be a Dallas 1-Wire interface. If so, the only external part normally needed with the Arduino is a pull-up resistor, about 3.3K for 3V3 or 4.7K for 5V.

I would do the initial testing with one of the old units. Once you have the Arduino communicating with it and know the interface is correct, connect the new working unit and periodically read and save its data while keeping track of equipment usage. Correlating changes in the data with usage should give you a good idea of what is being stored and how it is being updated.

Once that is understood, you may be able to copy the required data from the new unit and program it into an old one.

From the datasheet...

image

it a GXCAS GX28E01D, a 1-Kbit protected 1-Wire EEPROM with a SHA-1 authentication engine. So your earlier suspicion that it was a Dallas-style 1-Wire device was right.

There's one important wrinkle to my proposed "read the new one and program the old one" approach. It turns out this isn't merely an ordinary EEPROM. Some pages can be write-protected. Note authenticated writes require knowledge of the secret and generation of the correct SHA-1 MAC. The unique 64-bit ROM registration number is factory programmed, so that portion cannot simply be cloned by rewriting EEPROM.

If you are really serious you can get a inexpensive logic analyzer and let it decode the data for you. They can be gotten from chin for less then a pack of cigarettes but be cautious of shipping.

Here is the data sheet link: https://gxcas.com/uploads/files/202509/GX28E01_short_datasheet_V5.0_20250919173108.pdf

Good Luck.

What if the "1-wire" (and ground) were connected here, to an open terminal/serial monitor and try trapping whatever passes by...

Apologies. Totally wide of the mark earlier. Now that the IC has been identified, this totally makes sense. I thought this noteworthy:

All memory pages can be write protected, and one page can be put in EPROM-emulation mode, where bits can only be changed from a 1 to a 0 state.

It is not known whether that feature has been used in this case, but it would allow for at least some of the useful information to be wiped once the cartridge end of life has been reached.

I have some of the devices arriving from Mouser later today and I intend to experiment with various ways they could be used for printer ink DRM.

The really good information is only available from Analog after signing an NDA but they have published some useful information on challenge/response that will be worth testing. I don't give OP much hope for getting around the copy protection unless the printer manufacturers are total idiots.