RS232, mysterious protocol, and reverse engineering

RS232, mysterious protocol, and reverse engineering

We recently bought a magnetic hotplate stirrer that you can remotely drive thanks to an RS232 port. Unfortunately, the manufacturer seems to have forgotten to document the communication protocol. It was already too late when we noticed this. Not to worry, it's the ideal opportunity to show you how to work around this issue with a Yocto-RS232 .




In short, a magnetic hotplate stirrer is a heating plate able to stir by itself, thanks to a magnet that moves inside the container that the plate heats.

The stirrer rotates a magnet in the liquid to stir.
The stirrer rotates a magnet in the liquid to stir.


The said stirrer is an AG802 sold under the LMR brand name. However, a quick search on Internet shows that it is in fact a generic model sold by different brands but manufactured by DragonLab Instruments under the MS-H-Pro reference.

The MS-H-Pro stirrer by DragonLab, a.k.a. AG802
The MS-H-Pro stirrer by DragonLab, a.k.a. AG802


So we bought this cheap stirrer for its RS232 port. No luck, the user's guide (in French) does not describe the protocol used to control the agitator and the retailer was unable to help us. We did try to contact DragonLab to ask them some details, but they didn't care to answer us. However, a monitoring application, StirrerPC, is provided. It's a good starting point to try to understand how the control protocol works with the help of a Yocto-RS232.

The control software provided by DragonLab
The control software provided by DragonLab



Yocto-RS232 and snooping mode

It so happens that the Yocto-RS232 contains an interesting feature: it can work in analysis mode and display the content of the communications which transit on a serial cable. To do this, we insert a small adaptor on the connection and we connect the Yocto-RS232 to this adaptor. We configure the Yocto-RS232 in snooper mode and voila.

The adaptor to analyze RS232 communications with a Yocto-RS232
The adaptor to analyze RS232 communications with a Yocto-RS232


The said adaptor is sold ready-made by Yoctopuce under the RS232-Snooping-Adapter name, but you can also build one yourself: it doesn't contain any electronics. You can find the wiring diagram in the Yocto-RS232 documentation.

The Yocto-RS232 can analyze an RS232 communication
The Yocto-RS232 can analyze an RS232 communication




When the Yocto-RS232 is connected, you only need to configure it with the VirtualHub. In the opposite to what is said in the AG802 documentation, the protocol is binary, at 9600 bauds, 8N1 and not 7N1. Do not forget to set the Yocto-RS232 in Snooping mode.

Configuring the Yocto-RS232 in snooping mode
Configuring the Yocto-RS232 in snooping mode



When everything is configured correctly, the Yocto-RS232 records in its internal memory everything that occurs on the serial cable. You can view the recorded data with the API, but it is faster to use the VirtualHub. The http://127.0.0.1:4444/bySerial/serial/rxmsg.json?dir=2 URL displays the complete content of the Yocto-RS232 buffers. For example, if the serial number of the Yocto-RS232 is RS232MK1-33E7F:

http://127.0.0.1:4444/bySerial/RS232MK1-33E7F/rxmsg.json?dir=2



Decoding the protocol

When everything is set up, we must simply perform some basic operations with the application provided by DragonLab. By modifying a single parameter each time and by observing how the data transiting on the cable are affected, we can try to understand what happens.

Instructions

For example, if we ask the application to start the stirrer with the 63░C and 255 rpm parameters, we observe the following communication:

=>FE =>B1 =>00 =>FF =>00 =>B0 <=FDB1000000B1 =>FE =>B2 =>02 =>76 =>00 =>2A <=FDB2000000B2


We noticed that the application sends its commands as 6 byte packets. We noticed as well that these bytes are sent very slowly: about a byte every 50ms. We discovered the reason later: if we try to send them faster, the stirrer crashes. After a few trials with different instruction values, we determined that the packets follow this format:

OffsetValueSizeMeaning
000xFE 1packet header
010xB2 1command
020xXXXX2temperature value in 1/10 degrees encoded over two bytes,
for example: 63░C -> 630 -> 0x0276 -> 0x02,0x76
040x00 1unknown, always zero
050xXX 1checksum : LSB of the sum of bytes 1..4



Packets for the instruction on the stirring speed are very similar: the command is 0xB1 and the speed is directly encoded, for example a 255 rpm speed is encoded 0x00 0xFF. The agitator confirms each command with a six byte packet.

OffsetValueSizeMeaning
000xFD1packet header
010xB21command
02001unknown, always zero
03001unknown, always zero
04001unknown, always zero
060xXX1Checksum : LSB of the sum of bytes 1..4



Apparently, there is no explicit command to stop the agitator: when we click on the stop button, the DragonLab software simply repeats the latest instruction and the device stops. A rather strange design choice.

Decoding monitoring packets

We also discovered that the application sends at regular interval packets informing on the state of the agitator. Thus, we regularly see the following packet:
0xA2,0x00,0x00,0x00,0xA2 and the answer has the following format:

OffsetValueSizeMeaning
000xFD1packet header
010xA21command
020xXXXX2speed in rpm instruction
040xXXXX2actual speed in rpm
060xXXXX2temperature in tenth of degree instruction
080xXXXX2actual temperature in tenth of degree
0A0xXX2checksum : LSB of the sum of bytes 1 ..9



We also observed another packet, 0xA1,0x00,0x00,0x00,0xA1 , enabling you to know the parameters of the agitator. The answer has the following format:

OffsetValueSizeMeaning
000xFD1packet header
01A11command
02031mode : 0x01=A, 0x02=B , 0X03=C
030xXX1stirring : 0x01=off 0x00=on
040xXX1heating : 0x01= off 0x00=on
050xXXXX2security residual temperature in tenth of degree
070xXX1security residual temperature: 0x01=on, 0x00=off
08001unknown, always, zero
090xXX1stirring bar security : 0x01=on, 0x00=off
0A0xXX1checksum : LSB of the sum of by 1 to 9



Initialization packets

We also noticed that during startup, the application sends 16 packets, [0xFE,x0A3,0x00,0xXX,0x00,checksum] with 0xXX taking the values 0x00 then 0x10 to 0x1F. Apparently, this is used to retrieve a character string describing the agitator model. The transaction has the following format:

PacketAnswerMeaning
FEA0000000A0FDA0000000A0\0
FEA3001000B3FDA34D0000F0M
FEA3001100B4FDA3530000F6S
FEA3001200B5FDA32D0000D0-
FEA3001300B6FDA3480000EBH
FEA3001400B7FDA32D0000D0-
FEA3001500B8FDA3500000F3P
FEA3001600B9FDA372000015r
FEA3001700BAFDA36F000012o
FEA3001800BBFDA3000000A3\0
FEA3001900BCFDA3000000A3\0
FEA3001A00BDFDA3000000A3\0
FEA3001B00BEFDA3000000A3\0
FEA3001C00BFFDA3000000A3\0
FEA3001D00C0FDA3000000A3\0
FEA3001E00C1FDA3000000A3\0
FEA3001F00C2 FDA3000000A3\0



Conclusion

Thanks to the Yocto-RS232 and its snooping mode, we were able to reverse-engineer the serial protocol used between the application provided by DragonLab and the stirrer. We are now able to write a short library enabling us to drive the stirrer with a Yocto-RS232. So, despite the absence of documentation, we managed to get back on our feet. Note, however, that reverse-engineering allowed us only to rebuild commands that can be seen on the serial cable. It is probable that the stirrer accepts other commands, but it's impossible to guess them.

You are probably wondering what Yoctopuce intends to do with a magnetic hotplate stirrer, well, you'll have to wait until next time to find out...

Add a comment No comment yet
Back to blog












Yoctopuce, get your stuff connected.