Poking around in 3rd party hardware, baudmode?
xanatos
Posts: 1,120
I've got some RF tank level monitors and their receiver. I'm looking to be able to read the receiver's output. It's serial data, of unknown flavor. I've hit it with the usual 9600/8/N/1 and it returns garbage. So I put together the program below which looks at the output (the receiver outputs automatically every 7 seconds, so I just change the baudmode parameters, then listen for and debug the output each time, for five consecutive samples). Everything comes out garbage, but at least 4800 baud at various settings seems to give a more consistent garbage.
So after getting nowhere with that, I set up my brand new scope on the output and obtained the pic below.
The level rides high (1) at idle. The scope screen shown is set for 2ms/div.
Anyone out there who can help me understand what to look for on the scope output to recognize what baudmode ranges I should try here?
Thanks,
Dave
So after getting nowhere with that, I set up my brand new scope on the output and obtained the pic below.
The level rides high (1) at idle. The scope screen shown is set for 2ms/div.
Anyone out there who can help me understand what to look for on the scope output to recognize what baudmode ranges I should try here?
Thanks,
Dave
' ========================================================================= ' ' {$STAMP BS2px} ' {$PBASIC 2.5} ' ' ========================================================================= ' -----[ Constants ]------------------------------------------------------- #SELECT $STAMP #CASE BS2, BS2E, BS2PE T2400 CON 396 T9600 CON 84 T19K2 CON 32 #CASE BS2SX, BS2P T2400 CON 1021 T9600 CON 240 T19K2 CON 110 #CASE BS2PX T1200 CON 3313 T2400 CON 1646 T4800 CON 813 T9600 CON 396 T19K2 CON 188 T38K4 CON 84 #ENDSELECT ' -----[ I/O Definitions ]------------------------------------------------- Crx PIN 1 ' White Ctx PIN 0 ' Green ' -----[ Variables ]------------------------------------------------------- serStr VAR Byte(24) x VAR Nib ' -----[ Program Code ]---------------------------------------------------- PAUSE 1000 DEBUG "Polling", CR Main: DEBUG "8/N/I/1200 - 19697", CR FOR x = 1 TO 5 SERIN Ctx, 19697, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "8/N/I/2400 - 18030", CR FOR x = 1 TO 5 SERIN Ctx, 18030, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "8/N/I/4800 - 17197", CR FOR x = 1 TO 5 SERIN Ctx, 17197, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "8/N/I/9600 - 16780", CR FOR x = 1 TO 5 SERIN Ctx, 16780, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "8/N/1/1200 - 3313", CR FOR x = 1 TO 5 SERIN Ctx, 3313, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "8/N/1/2400 - 1646", CR FOR x = 1 TO 5 SERIN Ctx, 1646, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "8/N/1/4800 - 813", CR FOR x = 1 TO 5 SERIN Ctx, 813, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "8/N/1/9600 - 396", CR FOR x = 1 TO 5 SERIN Ctx, 396, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "7/E/I/1200 - 27889", CR FOR x = 1 TO 5 SERIN Ctx, 27889, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "7/E/I/2400 - 26222", CR FOR x = 1 TO 5 SERIN Ctx, 26222, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "7/E/I/4800 - 25389", CR FOR x = 1 TO 5 SERIN Ctx, 25389, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "7/E/I/9600 - 24792", CR FOR x = 1 TO 5 SERIN Ctx, 26222, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "7/E/1/1200 - 11565", CR FOR x = 1 TO 5 SERIN Ctx, 11565, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "7/E/1/2400 - 9838", CR FOR x = 1 TO 5 SERIN Ctx, 9838, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "7/E/1/4800 - 9005", CR FOR x = 1 TO 5 SERIN Ctx, 9005, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "7/E/1/9600 - 8588", CR FOR x = 1 TO 5 SERIN Ctx, 8588, [STR serStr\24] DEBUG STR serStr, CR NEXT GOSUB sep DEBUG "END OF OUTPUT", CR STOP ' ----[ Subroutines ]------------------------------------- sep: DEBUG "-----------------------", CR, CR RETURN
Comments
It is possible the device is using a binary protocol and/or a parity bit either of which could show up as garbage even if the baud rate is correct.
http://realterm.sourceforge.net/
And it is Free.
A scope may be useful to determine the baud rate, but stop bits and parity and whether you have 7 or 8 bit ASCII (or EBIDIC) really require a terminal application that lets you try things.
So I finally broke down and called their tech department and actually got someone who understood what I was doing - and it's serial data sort-of - it's not byte formatted, it's actually their own proprietary format that generates counts to drive their display, so it has to be interpreted.
Hence, terminal programs and basic stamps, expecting serial data, see serial junk.
Thanks for your help folks. It was fun poking around with the terminal program and being able to change formats with just a click - hadn't really thought to do that before.
It doesn't have to be UART serial, and if it is it doesn't have to be ASCII - binary values and a binary CRC are likely. The start of
the sequence could be a preamble. The coding may be designed to limit the max number of consecutive 0's or 1's for reliable clock-
reconstruction. If its off-air the timing might be a bit jittery too.
You need a "known-plaintext" attack - start capturing signals as the level changes by small amounts, look for patterns...
These are general observations for any kind of RF serial link - there are considerations of signal integrity that lead to
more complex coding schemes being used.
I get a signal every few seconds even without the transmitting units being on. I suspect the receiver has its own internal rom that loads values from the received signals, and just steps through the locations for the receivers in a round-robin sequence, outputting the last received value for that tank.
I'm hoping to get the document from the company today that outlines how to interpret their data stream. Should be interesting to see how close my observations and guesses were
Proprietary serial can have all sorts of odd stuff. You serial mouse and serial keyboard transmit 11 bits in one direction and 12 in the other.. just to keep us from easily hacking.
I'll try realterm... especially if it doesn't expect byte data. I'm looking for something that doesn't require 1, 1.5 or 2 stop bits... Just the bits, ma'am.
Thanks,
Dave
Uhm... well, at $299.00... maybe AFTER I get the contract!
http://www.parallax.com/product/32314
You were probably looking at the 16-bit.
This may or may not be a factor.
But if this is really 8N1, it all is rather easy to use RealTerm to display in HEX rather than ASCII. From there, you might begin to decode what the reality is as it does seem that the code is NOT ASCII.
What is in between can be 4, 5, 6, 7, or 8 bits. So it might be that what the OP is considering as a No Stop bit 8 bit is really a 7 bit packet with a 1 bit Stop bit.
Also, I believe that the BS2 can dump Hex or Decimal values to a terminal, rather than interpret data as being ASCII. But for the sake of verification, it might be wise to set aside the BS2 until something is confirmed.
The thing that the BS2 cannot do is Full duplex. Having Real Term running a Full duplex port might provide more insight into how the device interacts in the real world.
In any event, Real Term is intended to work with a serial port on a Windows computer and you can fool around quite a bit. So try 7N1 as well as 8N1. And also see the feature about reception of 'bursts' of more than one byte.
I've tried 8N1, 7N1, even/odd/no parity, etc. The data is apparently NOT ASCII or anything directly recognizable by human reading. I played around with RealTerm for a few hours last evening and no matter WHAT settings I had - and I stepped through a bunch, I would get the little "Framing Error" light blink on every TX from the unit.
As for receiving the data, either from a BS2 or via RealTerm, I'm getting the same strings. The nice thing about the data is that there is a data burst every three seconds - and nothing in between but the level riding high (mark). SO even if the BS2 was to start listening in the middle of the first burst, it just spits that out in a debug and goes back to waiting for the next burst, where it gets it all.
When I have the baud rate set to 4800, it appears to give me the most consistent data, whether I'm looking at the binary output or hex values, or even ASCII. With ASCII, the first two characters are always 0? followed by 7 characters which are all in the extended ASCII set (the little y's & a's with dots and lines above them, that kind of stuff). And the scope trace, as mentioned by Dave above, does seem to indicate pulse widths that correspond to 4800 baud, and my own measurements show a pulse width of approx. 205uS, which concurs.
The issue now seems to be that the system does not output human readable data directly, but rather some other type of data that needs to be interpreted in order to become readable data.
I now have access to a device that would normally take in that data and - display it as human readable. I'm going to try to feed that some data and see if I can figure out how to get it to read stuff, then - assuming I can accomplish that, I'll have a way to translate the initial devices' output stream. Theoretically. Maybe. ...
I'll post my level of success in this endeavor up here
Dave
To assume is to make an *** out of yoU and ME...
You're assuming that all 'packets' are of the same length...
Maybe it's not binary values as such, but just a row of pulses that the receiver has to count?
Possibly with some sort of 'break' inbetween to signal the end of one count and the start of the next?
You're assuming that I'm assuming - and I'm not! It's just that the data I have been able to acquire so far has been limited by the tools at my disposal. The scope display is the best reference I have yet simply because it is unfettered by any preconceived notion of what the incoming data should "look like". Additionally, in conversation with a tech who has some familiarity with these devices, he also suggested it was an interpreted binary stream, possibly, as you state, something that has to be counted in some way; however, with there being no section of data that is consistently 1/0 alternating transitions, it's an odd count.
Here is a sample of the output. It seems to repeat in blocks of 20 lines - which makes sense... 20 tanks. Each line is one data burst, with a three second rest in between. This is the data I will feed to the monitor box and see if I get intelligible readouts from it. If I do, I can start messing with values to see how it changes the display, and thereby, hopefully, figure out how to speak its language. Is it weird that I kind of enjoy this process? :nerd:
With 3 seconds between packets, and 4800 baud using the Stamp's STR modifier, it should be able to sync up and capture the packets. Absolutely so, since you are doing this with the speed demon BS2px. I'd do it something like this, dumping the hex values at a higher baud rate.
"Framing error" means that one or more of the bytes did not have a proper stop bit. That is the sort of thing that the Saleae logic analyzer can point out in detail.
There is some discussion of the older versions of RealTerm (aka Terminal) being more useful in some ways. That may be worth looking into if you can get a download of the earlier version. The latest expanded into being much more than an RS232 interface.
Just the fact that you can confirm that the data to the BS2 is the same as the data to RealTerm is a very useful piece of information. From there, you can focus more on what the binary code represents and not so much of the format.
If Dave Hein has it right at 7E1, you may finally move ahead with some clarity.
Are the sensors analog, or are they some sort of switches?
I'd start with making certain that all the inputs are tied to the exact same value.
That should get you data packets that are identical, except for any packet/port IDs.
Are the inputs numbered?
(Of course they are... )
Fiddling with one input should get you one data packet that is different.
And hopefully only one...
(Swap bit1 with bit8, bit2 with bit7, and so on)
What kind of chip is used as the 'brain' in the system?
EDIT: Oh, I see what you mean by it being backwards. The digits seem to be least significant first. Can you try different liquid levels on tank 18 to see what you get? These are liquid level sensors, correct?
SERIN Ctx, 813, [serStr(0), serStr(1), serStr(2), serStr(3), serStr(4), serStr(5), serStr(6), serStr(7), serStr(8)]
On slower Stamps, the PBASIC interpreter would really bog down on the individual array elements. The faster syntax for capture of 9 byte packets is...
SERIN Ctx, 813, [STR serStr\9]
Also could add in a timeout. I know the OP is familiar with PBASIC syntax! Are the packets always 9 bytes long?
In these tank packets, it looks like 9F is the Start key, so...
SERIN Ctx, 813, [WAIT($9F), STR serStr\8]
Lol... ya, the individual serStrings were a leftover result of a few dozen different iterations of code...
Always seem to be 9 packets, so far. I'm capturing a huge file full of the data now just to see if it's consistent over time, but it does appear stable.
Now I have to fill a 5 gallon bucket & drown my sensor Hopefully I'll be able to see raw non-zero level data from that. Life should get easier after that... all I have to do is store it all and package it every hour into an email from my Spinneret, which I've done many times now.
More for the interested soon!
PS., the BS2px screams. I love to develop with it, and then, once the full thing is designed, if I'm not needing to take advantage of the PX's speed & memory features, I can use a less steamin' stamp... but that PX is my favorite.
Basically it's an "every other nibble of the bytes" arrangement. Not sure why, still wondering about the format - but it's rock solid right now. Code below, including the commented out lines that show the code's evolution (along with viewing the output to figure out the nibble positions).
Thanks everybody for your suggestions and thoughts.