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 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
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
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 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
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
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:
Offset | Value | Size | Meaning |
---|---|---|---|
00 | 0xFE | 1 | packet header |
01 | 0xB2 | 1 | command |
02 | 0xXXXX | 2 | temperature value in 1/10 degrees encoded over two bytes,
for example: 63°C -> 630 -> 0x0276 -> 0x02,0x76 |
04 | 0x00 | 1 | unknown, always zero |
05 | 0xXX | 1 | checksum : 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.
Offset | Value | Size | Meaning |
---|---|---|---|
00 | 0xFD | 1 | packet header |
01 | 0xB2 | 1 | command |
02 | 00 | 1 | unknown, always zero |
03 | 00 | 1 | unknown, always zero |
04 | 00 | 1 | unknown, always zero |
06 | 0xXX | 1 | Checksum : 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:
Offset | Value | Size | Meaning |
---|---|---|---|
00 | 0xFD | 1 | packet header |
01 | 0xA2 | 1 | command |
02 | 0xXXXX | 2 | speed in rpm instruction |
04 | 0xXXXX | 2 | actual speed in rpm |
06 | 0xXXXX | 2 | temperature in tenth of degree instruction |
08 | 0xXXXX | 2 | actual temperature in tenth of degree |
0A | 0xXX | 2 | checksum : 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:
Offset | Value | Size | Meaning |
---|---|---|---|
00 | 0xFD | 1 | packet header |
01 | A1 | 1 | command |
02 | 03 | 1 | mode : 0x01=A, 0x02=B , 0X03=C |
03 | 0xXX | 1 | stirring : 0x01=off 0x00=on |
04 | 0xXX | 1 | heating : 0x01= off 0x00=on |
05 | 0xXXXX | 2 | security residual temperature in tenth of degree |
07 | 0xXX | 1 | security residual temperature: 0x01=on, 0x00=off |
08 | 00 | 1 | unknown, always, zero |
09 | 0xXX | 1 | stirring bar security : 0x01=on, 0x00=off |
0A | 0xXX | 1 | checksum : 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:
Packet | Answer | Meaning |
---|---|---|
FEA0000000A0 | FDA0000000A0 | \0 |
FEA3001000B3 | FDA34D0000F0 | M |
FEA3001100B4 | FDA3530000F6 | S |
FEA3001200B5 | FDA32D0000D0 | - |
FEA3001300B6 | FDA3480000EB | H |
FEA3001400B7 | FDA32D0000D0 | - |
FEA3001500B8 | FDA3500000F3 | P |
FEA3001600B9 | FDA372000015 | r |
FEA3001700BA | FDA36F000012 | o |
FEA3001800BB | FDA3000000A3 | \0 |
FEA3001900BC | FDA3000000A3 | \0 |
FEA3001A00BD | FDA3000000A3 | \0 |
FEA3001B00BE | FDA3000000A3 | \0 |
FEA3001C00BF | FDA3000000A3 | \0 |
FEA3001D00C0 | FDA3000000A3 | \0 |
FEA3001E00C1 | FDA3000000A3 | \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...