SD Codefree
Reverse engineered by Diego Elio Pettenò.
Cable
The data cable that you can buy together with the device is an USB Serial adapter, based on Silicon Laboratories CP210x chipset.
It appears to be a fairly standard USB-to-TRS serial adapter, though the connector is a subminiature (2.5mm connector):
Connector | Meaning |
---|---|
Tip | Device-to-Host |
Ring | Host-to-Device |
Sleeve | GND |
USB IDs
Device | Vendor ID | Product ID |
---|---|---|
SDCodefree Cable | 10c4 | ea60 |
Protocol
The communication happens over a serial binary protocol. The device initiates the connection once turned on, and the computer needs to respond to the opening challenge and follow up packets from the device with either commands or acknowledgments.
If the device receives an invalid command, it reports E-5
on the display and
needs to be turned off.
Serial port configuration
The serial port should be configured as such:
- 8 data bits;
- no parity bits;
- 1 stop bit;
- 38400 baud rate.
Packet structure
Packets follow a simple format:
packet = STX direction length message checksum ETX
STX = %x53
direction = direction-in / direction-out
direction-in = %x20
direction-out = %x10
length = OCTET
message = [length-3]OCTET
checksum = OCTET
ETX = %xAA
The packets are variable length, with the following length provided in the third byte of the packets (length does not include the three bytes up to that point, but does include checksum and ETX). The second byte is a direction indication (device-to-host and host-to-device).
The second to last byte is a checksum calculated as an 8-bit bitwise xor of the
message
bytes.
Protocol initialization
When the device is turned on it sends the following packet on the wire:
challenge = STX direction-in %x04 %x10 %x30 checksum ETX
Sometimes a leading null byte might be read from the message, unclear if this is due to the USB adapter, a bug in the driver or the device.
If the device is not given a response within time, it ignores the cable. The expected response is:
response = STX direction-out %x04 %x10 %x40 checksum ETX
Following the response, the device will send a packet that is composed mostly of
0xAA
values, which include the count of readings in the device:
count-packet = STX direction-in %x18 %x30 readings-count [19]%xAA checksum ETX
readings-count = 2 OCTET ; 16-bit big-endian value
The count of reading is assumed to be 16-bit because the manual references a memory of 1000 readings.
Setting date and time
The only parameter that can be tweaked on the device appears to be the date and time.
This is done through what appears like a text command sent over the binary protocol.
The packet need to be sent right after initialization and is acknowledge by the meter.
set-time-packet = STX direction-out %x13
'ADATE' set-year set-month set-day
set-hour set-minute checksum ETX
set-year = 4DIGIT
set-month = 2DIGIT
set-day = 2DIGIT
set-hour = 2DIGIT
set-minute = 2DIGIT
set-time-ack-packet = STX direction-in %x04 %x10 %x10 checksum ETX
Note that while the date is set with a full four-digits year, the device will ignore the first two digits — 1999, 2099 and 2199 appear as exactly the same value internally.
After receiving the acknwoeldgement, the device need to be told to disconnect, as otherwise it'll be stuck in PC connection mode. This can be done with the same packet used to fetch readings (see later in this document).
disconnect-packet = STX direction-out %x04 %x10 %x60 checksum ETX
disconnect-ack-packet = STX direction-in %x04 %x10 %x70 checksum ETX
Dumping the readings history
Alternatively from setting the date, it is possible to dump the records from the device. The readings will be returned in inverse order of them being taken, one for each fetch packet:
fetch-packet = STX direction-out %x04 %x10 %x60 checksum ETX
reading-packet = STX direction-in %x20 %x13 OCTET year month day
hour minute value flag-meal 7OCTET checksum ETX
year = OCTET
month = OCTET
day = OCTET
hour = OCTET
minute = OCTET
value = 2OCTET ; 16-bit big-endian value
flag-meal = no-meal / before-meal / after-meal
no-meal = %x00
before-meal = %x10
after-meal = %x20
The last seven bytes of the message are not understood yet, they seem to change independently from any settings on the device or on the reading itself, but they also don't change enough to look like a checksum of any kind.
After the last reading is provided, a further fetch causes a disconnection.