Serial TX/RX Communication Question
Wookie
Posts: 27
I am attempting to parse and then display (via a serial LCD) serial transmitted data from a 3rd party device. Nothing fancy on the settings:
baud rate: 9600 bits per second
parity: none
No. of data bits: 8
No. of stop bits: 1
Flow control: Xon/Xoff (Software controlled handshaking)
I am using an Sipex RS233 to shift the signal levels over to pins P6 & P7. Output to my LCD is same serial criteria as listed above, but is done on P0. Display is currently working properly, so no issues here.
I have successfully interfaced with other serial devices sending data (mostly GPS units in NEMA format), but all of these continuously transmitted data and I had existing code to work with. The device I am attempting to link to requires me to send a command (in this case "OUTPUT<cr>"). The unit will respond with a data stream "output 75.2 64.5 25.1 50. 0.435", where each of the variables may be from 1 to 8 digits in length (i.e., 75.2 could grow to be 2000.255). I need to take each of the five variables (separated by the spaces) and break them out independently.
The question is this, do I need to use the full extended serial code to perform the parsing, and if so, does the data stream exceed the 15 character length maximum or is this maximum for each of the parsed variables? If not, what would be the easiest way to attack this problem?
Any example code would be greatly appreciated.
Thanks in advance!
Joe
baud rate: 9600 bits per second
parity: none
No. of data bits: 8
No. of stop bits: 1
Flow control: Xon/Xoff (Software controlled handshaking)
I am using an Sipex RS233 to shift the signal levels over to pins P6 & P7. Output to my LCD is same serial criteria as listed above, but is done on P0. Display is currently working properly, so no issues here.
I have successfully interfaced with other serial devices sending data (mostly GPS units in NEMA format), but all of these continuously transmitted data and I had existing code to work with. The device I am attempting to link to requires me to send a command (in this case "OUTPUT<cr>"). The unit will respond with a data stream "output 75.2 64.5 25.1 50. 0.435", where each of the variables may be from 1 to 8 digits in length (i.e., 75.2 could grow to be 2000.255). I need to take each of the five variables (separated by the spaces) and break them out independently.
The question is this, do I need to use the full extended serial code to perform the parsing, and if so, does the data stream exceed the 15 character length maximum or is this maximum for each of the parsed variables? If not, what would be the easiest way to attack this problem?
Any example code would be greatly appreciated.
Thanks in advance!
Joe
Comments
Once the buffer is larger than the longest expected response string, it won't matter much how you do the parsing since the response will just sit in the buffer until you use it.
·
> exceed the 15 character length maximum or is this maximum for each of the parsed variables? If not, what would be the
> easiest way to attack this problem?
Parsing is preferably done with a finite state machine.
WHAT!?
You need to read char by char and react upon *events*. One of the events is the "." or the blank or a number and the final event is the <CR>.
Reading the numbers is just another FSM. A perfect number-parsing FSM can read numbers like ".3", "123.4" "1234", "-123" "-123E-6".
An FSM is a (big) case statement with events. Every event changes the FSM's state to a new state. States are normally enums.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
Mike, I looked at that code you hinted at, but being relatively new to the Propeller, I am not sure how easily it would be to modify it for my task. Any further thoughts or direction would be greatly appreciated.
Thanks
The DongleBasic version of FullDuplexSerial is usable by itself. I think there's only a couple of constant definitions in the BB_definitions.spin file that you could just copy to BB_FullDuplexSerial.spin, then rename the file to FullDuplexSerial.spin. It should be a drop-in replacement with just some extra functionality.
If you don't need the actual numeric value, you could just use the Extended FullDuplexSerial routines to pick out the pieces between the spaces (or space and return) and make them available as zero terminated strings for display or other output.
·
Mike,
Thanks for the help. The only major question if I were to go that route, would be how to do this multiple times for a single data string. If I understand correctly, I could break the first reading up to the decimal, then from the decimal to the space, but how do I go on to the next variable in the string and do the same thing (x3) until the end, giving each separate variable a unique name?
If you are going to keep these fields as strings, just define several byte arrays, each long enough to hold one field. Write your routine so that one of the parameters is the address of the byte array to store the value in (like @x). I think the Extended FullDuplexSerial routines return the address of their own work area and you can just copy it to the byte array you want (like: bytemove(@x,resultString,strsize(resultString)) where resultString contains the address of the Extended FullDuplexSerial result field).
Have a look at the Extended FullDuplexSerial package including the demo program you'll probably find in it. The actual documentation and examples are always much better than my trying to explain it without a copy in front of me.
Thanks in advance!
Joe
If you want, you could use the tx routine in FullDuplexSerial as a model and implement Xon/Xoff in that as described above. You can then substitute this for the existing tx routine. The other transmit routines that do editing (like str / dec / hex) all use tx, so this addition would be transparent.
I have yet another serial question. I have managed to solve the Software Xon/Xoff flow control issue by building in a small delay into the TX routine. Normally, I would imagine this would be less than desired, but the serial command I am sending is only several bytes and is repeated once a second anyway. So far, I have seen no complaints from the receiving device.
Anyway, now that I can talk to the device, I have another question. Originally, I thought I would have a variable width reply as discussed in my first post. I have now learned that the reply is fixed width (i.e., OUTPUT______1.9______1.9__74.2__34___0.296#13 , where "_" = number of blank spaces between fields).
My trouble seems to be in reading the reply. I have modified the serial.rx code to increase the buffer size to 64, but am still not getting the entire string (let alone the parsed pieces) to display on my LCD, which I know is working fine. Anyone see any reasons why my code isnt working?
Here is the serial.rx code that has been modified:
Followed by the LCD display code:
Thanks,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.