0

I'm trying to reverse engineer an old sensor interface program (Draeger Pac III). I have meaningful values as reported on the sensor screen and have identified the raw hex data via serial port sniffer. Now I am trying to figure out the pattern to write some code to receive and transmit the data in real numbers on an arduino.

Edit and update: So far this link to another, much newer, Draeger module has been the only possible link available but does not help explain the meaning behind the counting scheme below.

I'm 100% sure these bytes are the bytes of interest. For example this is the raw data from one value from the readout : 01 02 01 05 b0 00 19 00 d2 01 02 01 1d b0 00 00 43 9d 80 00 00 3e cc cc cd 42 5c 00 00 01 01 01 01 02 00 00 04 02 01 01 05 80. The first 8 bytes are the command with a checksum in the 9th position. Up to and including the 21st byte there is no change for each value change and I can only assume these correspond to other status components. 3e cc cc cd some how represents 0.40. 42 5c 00 00 represents 55 (still not sure how). The next section represents on/off for other components and can be changed independently of the two 4 byte data sets representing numbers. The last 2 bytes are the checksum.

Real #  Byte 1  Byte 2  Byte 3  Byte 4
0.00    0   0   0   0
0.01    3c  23  d7  0a
0.02    3c  a3  d7  0a
0.03    3c  f5  c2  8f
0.04    3d  23  d7  0a
0.05    3d  4c  cc  cd
0.06    3d  75  c2  8f
0.07    3d  8f  5c  29
0.08    3d  a3  d7  0a
0.09    3d  b8  51  ec
0.10    3d  cc  cc  cd
0.20    3e  4c  cc  cd
0.30    3e  99  99  9a
0.40    3e  cc  cc  cd
0.50    3f  0   0   0
0.99    3f  7d  70  a4
1.00    3f  80  0   0
1.01    3f  81  47  ae
2.00    40  0   0   0
3.00    40  40  0   0
4.00    40  80  0   0
4.10    40  83  33  33
4.11    40  83  85  1f
5.00    40  a0  0   0
8.14    41  2   3d  71
10.00   41  20  0   0
19.00   41  98  0   0
20.00   41  a0  0   0
21.00   41  a8  0   0
30.00   41  f0  0   0
31.00   41  f8  0   0
31.51   41  fc  14  7b
32.00   42  0   0   0
33.00   42  4   0   0
34.00   42  8   0   0
39.00   42  1c  0   0
40.00   42  20  0   0
41.00   42  24  0   0
65.00   42  82  0   0
70.00   42  8c  0   0
80.00   42  a0  0   0
95.00   42  be  0   0
100.00  42  c8  0   0

What is the pattern to this data?

  • A couple of things: maybe if you mention the sensor in particular or at least the brand. Somebody might come up with the protocol documentation. And second: How did you get the hex dump? sniffing on the bus? Are you sure you used the right format? If you explain that I think it might help to see if what you are getting makes sense. – Marcos G. Aug 07 '19 at 17:41
  • Marcos, I've attempted to contact the manufacturer and they have been less than helpful. Google has also turned up nothing so I've resorted to this method of backing into the answer. Technically this isn't a 'hex dump' per se but rather a scavenging of the data by hand. I know for a fact the real numbers correspond to the hex numbers but I'm not sure what that relationship is. I think there is a rollover counter maxing at 255 but I cant seem to figure out why the counter is not uniformly split across all ranges of values. – Research8472 Aug 07 '19 at 18:23
  • I don't know exactly what you mean by manual scavenging but you can try [this approach](https://stackoverflow.com/a/57062146/11476836) to listen on the port and record the transactions. Just to double check your values – Marcos G. Aug 07 '19 at 19:01
  • @MarcosG. I used serial port monitor to get the values above just like your link showed. My problem is understanding how the system is counting so that I can take the hex values that are being spit out by the sensor and 'read' them into real numbers in my arduino. – Research8472 Aug 07 '19 at 19:10
  • I thought it was too obvious to write but here it is: I haven't seen the instrument or the software but I doubt it only sends 4 bytes. Most protocols include many more things than data, how sure you are what you posted on your question is the data itself and how sure you are it is all there is. – Marcos G. Aug 07 '19 at 19:17
  • 100% sure. For example this is the section from the readout : 01 02 01 05 b0 00 19 00 d2 01 02 01 1d b0 00 00 43 9d 80 00 00 3e cc cc cd 42 5c 00 00 01 01 01 01 02 00 00 04 02 01 01 05 80. The first 8 bytes are the command with a checksum in the 9th position. Up to and including the 21st byte there is no change for each value change and I can only assume these correspond to other status components. 3e cc cc cd some how represents 0.40. 42 5c 00 00 represents 55 (still not sure how). the next section represents on/off for other components followed by 2 bytes of checksum at the end. – Research8472 Aug 07 '19 at 19:28
  • The key to crack the code is, I think, that not all bits on your data bytes (which you are 100℅ sure of, no more, no less) are data. Probably one or two bits on each byte are used as sync or to transmit some other flags. Maybe that makes sense? – Marcos G. Aug 07 '19 at 19:35
  • [This](https://www.google.com/url?sa=t&source=web&rct=j&url=ftp://hubble.informatimago.com/users/pjb/medical-equipment-documentation/Respirador_drager/medibus_drager.pdf&ved=2ahUKEwjIw5iauvHjAhXG4IUKHct7ClUQFjACegQIBRAC&usg=AOvVaw29Rp8YJqkcb9tnUYkef5ex) might give you some hints or at least a taste for how non-ovbious things can be. – Marcos G. Aug 07 '19 at 19:45
  • Thanks! Though this seems all pretty obvious based on what I have seen so far of the datastream. What do you mean by non-obvious? – Research8472 Aug 07 '19 at 19:54
  • Everything is obvious after you know it, that's what I meant – Marcos G. Aug 07 '19 at 19:57
  • This is why i posted the bytes that mattered as I already knew the "sync", "transmit", "flag", and "checksum bytes. SO the question still remains, how does one translate the data from hex to real (not decimal) numbers? – Research8472 Aug 07 '19 at 20:01

1 Answers1

1

The answer was in IEEE-754 Floating Point Converter. This gets me all the results I wanted.

https://www.h-schmidt.net/FloatConverter/IEEE754.html

And for ease of use to convert hex to decimal in python3:

import struct 

input='3f   81  47  ae'

val=struct.unpack('!f', bytes.fromhex(input))[0]
print (round(val,2))