Hackers of MeFi, assemble! I have an undocumented serial protocol I want to reverse engineer - help me turn some mysterious bit strings into meaningful data.
I recently bought a V-Fit 10kpt treadmill for use in a treadmill desk arrangement, which is working out well. Like most treadmills it has a fairly rubbish interface on a control unit; the control unit talks to the treadmill itself over a single-wire serial protocol, which I've reverse-engineered enough to replace the control unit with my own microprocessor + desktop application.
So far so good, but my solution involves capturing the serial traffic at a given speed as a bit sequence and then playing that bit sequence back to set that speed on the treadmill. I'm like the man in the chinese room experiment.
This is where you, the good people of ask metafilter, come in; can you help me turn these meaningless bits into comprehensible data?
At a given speed the device plays out a 120 bit sequence at 1200 baud, repeated every 7.2 milliseconds; here is an example bit sequence (this is a recording of the logic levels on the wire with no further processing). Each of these 120 bit sequences is a speed command.
bin: 00001011 00110000 10000011 00000010 00110000 01010111 00000000 01110100 00111111 00000000 01110001 01000111 01011011 00110110 00010011
hex: 0x0b 0x30 0x83 0x02 0x30 0x57 0x00 0x74 0x3f 0x00 0x71 0x47 0x5b 0x36 0x13
I've broken this into bytes as its length is divisible by 8, and I can't see any obvious pattern of start and stop bits like you'd get in normal RS232.
It turns out that every command starts with 0x0b 0x30 0x83 0x02 0x30, and ends with 0x13, so I'll leave those off from now on; from there we have one special command, played when the device is stopped:
stop (bin): 00000111 00000000 01110000 00000111 00000000 01110001 01000111 00011110 01110110
stop (hex): 0x7 0x0 0x70 0x7 0x0 0x71 0x47 0x1e 0x76
and then at least 96 speed commands, going from 0.5kph to 10kph in 0.1kph increments. Every speed command is prefixed with 0x57, presumably identifying it as a speed, followed by 3 variable bytes, followed by 0x00 0x71 0x47, followed by two variable bytes whose final nibble is always 6. Here are some examples (leading 0x57 omitted):
0.5kph 00000000 01110100 00111111 00000000 01110001 01000111 01011011 00110110
0x0 0x74 0x3f 0x0 0x71 0x47 0x5b 0x36
0.6kph 01000000 00110011 10000011 00000000 01110001 01000111 01101100 10110110
0x40 0x33 0x83 0x0 0x71 0x47 0x6c 0xb6
0.7kph 01000000 00110110 11100011 00000000 01110001 01000111 00001001 10110110
0x40 0x36 0xe3 0x0 0x71 0x47 0x9 0xb6
0.8kph 01000000 00110000 10110011 00000000 01110001 01000111 01010111 11110110
0x40 0x30 0xb3 0x0 0x71 0x47 0x57 0xf6
0.9kph 01000000 00110101 01001111 00000000 01110001 01000111 00100010 01110110
0x40 0x35 0x4f 0x0 0x71 0x47 0x22 0x76
1.0kph 01000000 00110010 00011011 00000000 01110001 01000111 01111001 00110110
0x40 0x32 0x1b 0x0 0x71 0x47 0x79 0x36
1.1kph 01000000 00110111 10111011 00000000 01110001 01000111 00011111 00110110
0x40 0x37 0xbb 0x0 0x71 0x47 0x1f 0x36
1.2kph 00100000 00110001 11000011 00000000 01110001 01000111 00101010 11110110
0x20 0x31 0xc3 0x0 0x71 0x47 0x2a 0xf6
9.9kph 01000100 01110110 10110011 00000000 01110001 01000111 00001000 00110110
0x44 0x76 0xb3 0x0 0x71 0x47 0x8 0x36
10kph 01000100 01110000 11001011 00000000 01110001 01000111 01010110 01110110
0x44 0x70 0xcb 0x0 0x71 0x47 0x56 0x76
My guesses so far on speed command format are:
- First 3 bytes could be a 24-bit floating point; they are not lexically ordered against speed which fits this possibility
- Final two bytes could be a checksum of some sort; the device has lots of ambient EMF because of the motor, and it would be bad if a few bit errors could stop the belt or run it at 10kph suddenly
- Middle bytes are just a separator, maybe again to provide some bit error / timing error stability
One other point of interest: the devices speaking this protocol are AVR ATMega8 microprocessors, so any common data they use could be involved (I don't get why the engineers here didn't just use the built-in standard 8N1 serial?!?!). The micros' flash memories have their lock bits set, so I can't just download their programs and reverse-engineer directly (first thing I tried).
Over to you, metafilter; thanks!