Author Topic: RS-232 Protocol decoding Puzzle  (Read 6014 times)

0 Members and 1 Guest are viewing this topic.

Offline sileTopic starter

  • Contributor
  • Posts: 15
RS-232 Protocol decoding Puzzle
« on: October 19, 2012, 04:11:20 am »
I've a digital scale i'm trying to read off of: MBSC Ultra U-2 from My Weigh.  What is curious is that the output from the scale on the com port will be completely different from time to time but the actual weight is the same. I haven't been able to figure it out yet...    Does anyone see what they are doing?

There are 6 bytes in the middle that are all the same when it's at 0g.  And then the right most  digits start to go up as I add weight.  But, I haven't been able to determine how to calculate it yet.   For each weight I pressed the send button a bunch of times.  So, each line is the bytes I would see come across for each measurement:

0g

 02 99 B5 94 9F 9F 9F 9F 9F 9F 8F 06 2B 03
 02 03 2F 0E 05 05 05 05 05 05 15 00 73 03
 02 4C 60 41 4A 4A 4A 4A 4A 4A 5A 03 03 03
 02 AA 86 A7 AC AC AC AC AC AC BC 06 9B 03
 02 20 0C 2D 26 26 26 26 26 26 36 01 73 03
 02 89 A5 84 8F 8F 8F 8F 8F 8F 9F 05 AB 03
 02 FA D6 F7 FC FC FC FC FC FC EC 09 9B 03
 02 6F 43 62 69 69 69 69 69 69 79 04 03 03
 02 EA C6 E7 EC EC EC EC EC EC FC 09 1B 03
 02 4C 60 41 4A 4A 4A 4A 4A 4A 5A 03 03 03
 02 C6 EA CB C0 C0 C0 C0 C0 C0 D0 07 CB 03     

 
 16g
 
 02 16 3A 1B 10 10 10 10 10 01 06 00 C2 03
 02 79 55 74 7F 7F 7F 7F 7F 6E 69 04 94 03
 02 D4 F8 D9 D2 D2 D2 D2 D2 C3 C4 08 46 03
 02 33 1F 3E 35 35 35 35 35 24 23 01 E0 03
 02 8C A0 81 8A 8A 8A 8A 8A 9B 9C 05 96 03
 02 11 3D 1C 17 17 17 17 17 06 01 00 E4 03
 02 90 BC 9D 96 96 96 96 96 87 80 05 DE 03
 02 06 2A 0B 00 00 00 00 00 11 16 00 62 03
 02 5D 71 50 5B 5B 5B 5B 5B 4A 4D 03 7C 03
 02 B7 9B BA B1 B1 B1 B1 B1 A0 A7 06 C8 03
 02 09 25 04 0F 0F 0F 0F 0F 1E 19 00 B4 03
 02 7A 56 77 7C 7C 7C 7C 7C 6D 6A 04 8A 03
 02 E7 CB EA E1 E1 E1 E1 E1 F0 F7 08 E8 03 

 
 750g

 
 02 E3 CF EE E5 E5 E5 E5 F2 F0 F5 09 0B 03
 02 85 A9 88 83 83 83 83 94 96 93 05 7F 03
 02 2A 06 27 2C 2C 2C 2C 3B 39 3C 01 B7 03
 02 97 BB 9A 91 91 91 91 86 84 81 05 BB 03
 02 12 3E 1F 14 14 14 14 03 01 04 00 C7 03
 02 95 B9 98 93 93 93 93 84 86 83 05 BF 03
 02 EF C3 E2 E9 E9 E9 E9 FE FC F9 09 2B 03
 02 56 7A 5B 50 50 50 50 47 45 40 03 37 03
 02 A7 8B AA A1 A1 A1 A1 B6 B4 B1 06 7B 03
 02 FC D0 F1 FA FA FA FA ED EF EA 09 6B 03
 02 3D 11 30 3B 3B 3B 3B 2C 2E 2B 01 EF 03   

 10,750g
 
 02 32 1E 3F 34 34 25 24 23 21 24 01 A8 03
 02 BF 93 B2 B9 B9 A8 A9 AE AC A9 06 CA 03
 02 2E 02 23 28 28 39 38 3F 3D 38 01 C8 03
 02 98 B4 95 9E 9E 8F 8E 89 8B 8E 05 DC 03
 02 FF D3 F2 F9 F9 E8 E9 EE EC E9 09 4A 03
 02 64 48 69 62 62 73 72 75 77 72 04 1C 03
 02 D1 FD DC D7 D7 C6 C7 C0 C2 C7 08 2E 03
 02 1E 32 13 18 18 09 08 0F 0D 08 00 C8 03
 02 70 5C 7D 76 76 67 66 61 63 66 04 2C 03
 02 BE 92 B3 B8 B8 A9 A8 AF AD A8 06 C8 03
 02 27 0B 2A 21 21 30 31 36 34 31 01 9A 03
 02 75 59 78 73 73 62 63 64 66 63 04 1E 03
 02 CB E7 C6 CD CD DC DD DA D8 DD 08 5A 03
 02 11 3D 1C 17 17 06 07 00 02 07 00 AE 03
 02 5B 77 56 5D 5D 4C 4D 4A 48 4D 03 5A 03   
 
 
 10,020g:
 02 A5 89 A8 A3 A3 B2 B3 B3 B1 B3 06 98 03
 02 09 25 04 0F 0F 1E 1F 1F 1D 1F 00 E8 03
 02 6C 40 61 6A 6A 7B 7A 7A 78 7A 04 42 03
 02 D0 FC DD D6 D6 C7 C6 C6 C4 C6 08 32 03
 02 25 09 28 23 23 32 33 33 31 33 01 98 03
 02 81 AD 8C 87 87 96 97 97 95 97 05 B8 03
 02 E6 CA EB E0 E0 F1 F0 F0 F2 F0 09 0E 03
 02 3B 17 36 3D 3D 2C 2D 2D 2F 2D 01 E4 03
 02 8F A3 82 89 89 98 99 99 9B 99 05 C4 03
 02 E1 CD EC E7 E7 F6 F7 F7 F5 F7 09 38 03
 02 3B 17 36 3D 3D 2C 2D 2D 2F 2D 01 E4 03   

 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 10141
  • Country: nz
Re: RS-232 Protocol decoding Puzzle
« Reply #1 on: October 19, 2012, 05:13:13 am »
That look suspiciously like the baud rate is wrong.

Or maybe the serial data has been inverted (or hasn't been).
UART <--> RS232 conversion involves inverting the signal. The max232 does that for you but if you try and level shift the signal yourself then you have to do it.

« Last Edit: October 19, 2012, 05:29:42 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline DRT

  • Regular Contributor
  • *
  • Posts: 54
  • Country: gb
Re: RS-232 Protocol decoding Puzzle
« Reply #2 on: October 19, 2012, 09:02:50 am »
I think the data is received correctly: The 16-bit sum of the 2nd to 11th bytes equals the 16-bit value in the 12th and 13th bytes.
« Last Edit: October 19, 2012, 09:04:22 am by DRT »
 

Offline firewalker

  • Super Contributor
  • ***
  • Posts: 2452
  • Country: gr
Re: RS-232 Protocol decoding Puzzle
« Reply #3 on: October 19, 2012, 09:19:34 am »
Does it use 7-segment display? It could send the values of the individual segments. As many DMM do.

Alexander.
Become a realist, stay a dreamer.

 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 10141
  • Country: nz
Re: RS-232 Protocol decoding Puzzle
« Reply #4 on: October 19, 2012, 09:41:34 am »
That wouldn't explain why the same weight value has so many different data payloads.
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline PA0PBZ

  • Super Contributor
  • ***
  • Posts: 5173
  • Country: nl
Re: RS-232 Protocol decoding Puzzle
« Reply #5 on: October 19, 2012, 09:49:19 am »
When I google "MBSC Ultra U-2" it has an USB port, where exactly are you taking this data from?
Keyboard error: Press F1 to continue.
 

Offline firewalker

  • Super Contributor
  • ***
  • Posts: 2452
  • Country: gr
Re: RS-232 Protocol decoding Puzzle
« Reply #6 on: October 19, 2012, 09:52:23 am »
It probably has a UART<->USB (e.g. FT232 chip) bridge.

Alexander.
Become a realist, stay a dreamer.

 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 10141
  • Country: nz
Re: RS-232 Protocol decoding Puzzle
« Reply #7 on: October 19, 2012, 09:55:25 am »
Can we get a picture of the display showing some value?

The digit arrangement/grouping may give some clues.

EDIT: Found this by googling, is this what it looks like?



Also, have you tried different stop/start bit settings? If there are extra bits being treated as data it might do something like that.
« Last Edit: October 19, 2012, 10:01:08 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline HackedFridgeMagnet

  • Super Contributor
  • ***
  • Posts: 2031
  • Country: au
Re: RS-232 Protocol decoding Puzzle
« Reply #8 on: October 19, 2012, 10:13:58 am »
Seems to have a stack of redundancy.
Maybe you should post about 3 messages each from a few different weights.

oops Sorry you already did that.
« Last Edit: October 19, 2012, 02:09:06 pm by HackedFridgeMagnet »
 

Offline amyk

  • Super Contributor
  • ***
  • Posts: 8345
Re: RS-232 Protocol decoding Puzzle
« Reply #9 on: October 19, 2012, 10:38:31 am »
XOR the 2nd byte with the 3rd through 11th and you get...
0g:
Code: [Select]
02 99 2c 0d 06 06 06 06 06 06 16 06 2b 03
02 03 2c 0d 06 06 06 06 06 06 16 00 73 03
02 4c 2c 0d 06 06 06 06 06 06 16 03 03 03
02 aa 2c 0d 06 06 06 06 06 06 16 06 9b 03
02 20 2c 0d 06 06 06 06 06 06 16 01 73 03
02 89 2c 0d 06 06 06 06 06 06 16 05 ab 03
02 fa 2c 0d 06 06 06 06 06 06 16 09 9b 03
02 6f 2c 0d 06 06 06 06 06 06 16 04 03 03
02 ea 2c 0d 06 06 06 06 06 06 16 09 1b 03
02 4c 2c 0d 06 06 06 06 06 06 16 03 03 03
02 c6 2c 0d 06 06 06 06 06 06 16 07 cb 03
16g:
Code: [Select]
02 16 2c 0d 06 06 06 06 06 17 10 00 c2 03
02 79 2c 0d 06 06 06 06 06 17 10 04 94 03
02 d4 2c 0d 06 06 06 06 06 17 10 08 46 03
02 33 2c 0d 06 06 06 06 06 17 10 01 e0 03
02 8c 2c 0d 06 06 06 06 06 17 10 05 96 03
02 11 2c 0d 06 06 06 06 06 17 10 00 e4 03
02 90 2c 0d 06 06 06 06 06 17 10 05 de 03
02 06 2c 0d 06 06 06 06 06 17 10 00 62 03
02 5d 2c 0d 06 06 06 06 06 17 10 03 7c 03
02 b7 2c 0d 06 06 06 06 06 17 10 06 c8 03
02 09 2c 0d 06 06 06 06 06 17 10 00 b4 03
02 7a 2c 0d 06 06 06 06 06 17 10 04 8a 03
02 e7 2c 0d 06 06 06 06 06 17 10 08 e8 03
750g:
Code: [Select]
02 e3 2c 0d 06 06 06 06 11 13 16 09 0b 03
02 85 2c 0d 06 06 06 06 11 13 16 05 7f 03
02 2a 2c 0d 06 06 06 06 11 13 16 01 b7 03
02 97 2c 0d 06 06 06 06 11 13 16 05 bb 03
02 12 2c 0d 06 06 06 06 11 13 16 00 c7 03
02 95 2c 0d 06 06 06 06 11 13 16 05 bf 03
02 ef 2c 0d 06 06 06 06 11 13 16 09 2b 03
02 56 2c 0d 06 06 06 06 11 13 16 03 37 03
02 a7 2c 0d 06 06 06 06 11 13 16 06 7b 03
02 fc 2c 0d 06 06 06 06 11 13 16 09 6b 03
02 3d 2c 0d 06 06 06 06 11 13 16 01 ef 03
10750g:
Code: [Select]
02 32 2c 0d 06 06 17 16 11 13 16 01 a8 03
02 bf 2c 0d 06 06 17 16 11 13 16 06 ca 03
02 2e 2c 0d 06 06 17 16 11 13 16 01 c8 03
02 98 2c 0d 06 06 17 16 11 13 16 05 dc 03
02 ff 2c 0d 06 06 17 16 11 13 16 09 4a 03
02 64 2c 0d 06 06 17 16 11 13 16 04 1c 03
02 d1 2c 0d 06 06 17 16 11 13 16 08 2e 03
02 1e 2c 0d 06 06 17 16 11 13 16 00 c8 03
02 70 2c 0d 06 06 17 16 11 13 16 04 2c 03
02 be 2c 0d 06 06 17 16 11 13 16 06 c8 03
02 27 2c 0d 06 06 17 16 11 13 16 01 9a 03
02 75 2c 0d 06 06 17 16 11 13 16 04 1e 03
02 cb 2c 0d 06 06 17 16 11 13 16 08 5a 03
02 11 2c 0d 06 06 17 16 11 13 16 00 ae 03
02 5b 2c 0d 06 06 17 16 11 13 16 03 5a 03
10,020g:
Code: [Select]
02 a5 2c 0d 06 06 17 16 16 14 16 06 98 03
02 09 2c 0d 06 06 17 16 16 14 16 00 e8 03
02 6c 2c 0d 06 06 17 16 16 14 16 04 42 03
02 d0 2c 0d 06 06 17 16 16 14 16 08 32 03
02 25 2c 0d 06 06 17 16 16 14 16 01 98 03
02 81 2c 0d 06 06 17 16 16 14 16 05 b8 03
02 e6 2c 0d 06 06 17 16 16 14 16 09 0e 03
02 3b 2c 0d 06 06 17 16 16 14 16 01 e4 03
02 8f 2c 0d 06 06 17 16 16 14 16 05 c4 03
02 e1 2c 0d 06 06 17 16 16 14 16 09 38 03
02 3b 2c 0d 06 06 17 16 16 14 16 01 e4 03

Now we get:
blank: 06 = 0000 0110
0: 16 = 0001 0110
1: 17 = 0001 0111
2: 14 = 0001 0100
5: 13 = 0001 0011
6: 10 = 0001 0000
7: 11 = 0001 0001

Probably not encryption, but rather they're raw drive signals for the display. The 2nd byte seems to be the backplane and the rest are the segments (some might be inverted).
 

Offline HackedFridgeMagnet

  • Super Contributor
  • ***
  • Posts: 2031
  • Country: au
Re: RS-232 Protocol decoding Puzzle
« Reply #10 on: October 19, 2012, 11:03:03 pm »
Good work Amyk

Any idea why they would xor those bytes?


Quote
The 2nd byte seems to be the backplane
  which byte is this?

Also I dont think the rest of the output of your decoding are the segments whether they are inverted or not. as it there should be two bits difference between blank and one. It must be slightly more complicated mapping to the segments, I guess just done with a few gates.

 

Offline amyk

  • Super Contributor
  • ***
  • Posts: 8345
Re: RS-232 Protocol decoding Puzzle
« Reply #11 on: October 20, 2012, 05:31:21 am »
LCDs need an AC drive signal to the crystal to prevent electrolysis. When there is a voltage difference between a segment and common electrode, the segment turns on. When there isn't, the segment is off. A xor makes the desired segments' drive signal 180 degrees out of phase with the common when it's on, and in phase when it's off.

That still doesn't explain why the drive signals are being sent raw over RS-232; I had some thoughts that it might be some sort of scrambling of the data to reduce EMI but in that case it wouldn't be a simple xor like this.

There might be a few more gates between the signal and the display, or I might just be xor'ing the wrong values together --- anything that's driven in phase with the common would've produced similar results. We need to see the values for the other few digits to figure that out. Also from the large picture above the display appears to contain 8 segments (middle bar is two segments?)
« Last Edit: October 20, 2012, 05:37:44 am by amyk »
 

Offline sileTopic starter

  • Contributor
  • Posts: 15
Re: RS-232 Protocol decoding Puzzle
« Reply #12 on: October 21, 2012, 02:25:59 am »
Thanks everyone for your help! 

I did some more testing and I now have some code that can decode it reliably.  Once I get it finished up i'll post it here as well.  The plan is to get it running on a raspberry pi and upload the measurements to a web server.  The interface is indeed USB, but the driver for the PL2303 USB device just creates a local COM port to use. 

As for the format, I still have not figured out what bytes 3 & 4 are for.  They look like some kind of satus codes "2C 0D", but no matter what units I change on the scale or tare , hold, etc, those bytes stay the same.  Also, as far as the individual digits I don't think it is just pulling the 7 segment bits.  My main reason that in 7 bytes that are transmitted for digits, 08 is used to indicate a decimal.  So, even though the decimal is a part of a single 7 segment display it takes up a whole character in the serial output.  Grams is the only unit that won't ever have a decimal, so i can check and if there are no 0x08 i know it's in grams.  Kind of a dumb way to do it.  You would think if they are going to all the trouble to build this they would have thought to include the UNIT in that data stream... crazy.  Even the dumb little application (not sure you can even call it an application), forces you to manually pick the unit.

Also, the other thing I never found out was what bytes 12 & 13 are used for.  They look like a checksum of some sort, but every checksum/CRC I tried never matched what they had.  It's not really that import unless they contain the unit data... which I don't think they do.

so,  0x06 0x06 0x06 0x11 0x08 0x12 0x13  =    7.45 on the display

lookup = {6,7,4,5,2,3,0,1,11,11,11,11,11,11,8,9};
decimal = lookup[ byteVal & 0x0f];

0x06 = blank
0x08 = decimal
0x10 = 6
0x11 = 7
0x12 = 4
0x13 = 5
0x14 = 2
0x15 = 3
0x16 = 0
0x17 = 1
0x1E = 8
0x1F = 9


« Last Edit: October 21, 2012, 01:59:14 pm by sile »
 

Offline sileTopic starter

  • Contributor
  • Posts: 15
Re: RS-232 Protocol decoding Puzzle
« Reply #13 on: December 15, 2012, 03:24:26 am »
For those interested this is my full Python code running on the Raspberry Pi.  Requires to "apt-get install python-serial" .  This is my first Python program btw, so go easy on me.  I originally wrote this in Java, but decided to re-do it and learn a new language.

Code: [Select]
import sys, os, serial, time


def dump_port_list():

    comports = []
    files = os.listdir("/dev/")
    for file in files:
        if file.startswith("ttyU"):
            comports.append("/dev/" + file)

    return comports


def decodeData(data):

    output = []
    lookup = [6,7,4,5,2,3,0,1,11,11,11,11,11,11,8,9]

    #XOR and mask all the values
    for x in range(4,11) :
        output.append(  ( ord(data[x]) ^ ord(data[1]) ) & 0x0f )

    #use lookup to change to decimal
    value=0
    print "Converted: ",
    for x in range(7):
        digit = lookup[output[x]]
        print hex(digit) + " ",
        value += digit * 10**(6-x)
    print ""

    return value


def uploadData(value):
    url = "https://docs.google.com/spreadsheet/formResponse?formkey=dFJYcWVkWVJRZakf3JSajd0U09OYmN1UVE6MQ&ifq"
    url += "&backupCache=&pageNumber=0&submit=Submit&entry.1.single="

    url += str(value)

    import urllib2

    try:
        f=urllib2.urlopen(url)
        f.read(1000)
        f.close()
    except :
        print "Error! Could not upload value"


def main():

    ### Main Loop
    while True :

        allports = []
        #Loop until we find a USB Port
        while len(allports) == 0:
            allports = dump_port_list()
            time.sleep(1)

        print "USB Ports:" + str(allports)

        try:
            ser = serial.Serial()
            bad_data_timer = 0

            ## Open serial port

            ser.port = allports[0]
            ser.baud = 9600
            print "Opening port: " + ser.port
            ser.open()

            while ser.isOpen() and ser.readable :

                if ser.inWaiting() > 13 :
                    serdata = ser.read(14)
                    print "Serial data: " ,
                    for x in serdata:
                        print hex(ord(x)) ,
                    print ""

                    value = decodeData(serdata)
                    print "Value: " + str(value)
                    uploadData(value)

                    bad_data_timer=0


                elif ser.inWaiting() > 0 :
                    if bad_data_time == 0 :
                        ##Start timer for bad data
                        bad_data_timer = time.time()
                    elif (time.time() - bad_data_timer) > 5:
                        ##It's been over 5 seconds lets dump our data stuck in the stream
                        print "Bad data dump: " + str(ser.read(ser.inWaiting()))
                        bad_data_timier=0

                time.sleep(1)
            #while ser.isOpen() and ser.readable


        except:
            try:
                if ser.isOpen(): ser.close()

            except:
                print "Error closing stream"
            print "Error while reading "

        ##try

    ### End Main Loop

## def main()


 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf