String parsing
Thric
Posts: 109
Hi,
I've been working on my project haphazardly for a while now and now that its winter break I can finally get a bit organized. I'm fixing up my new PCB this Friday and so while that is on hold I've been working on the software protocol with one of my older propeller boards. I just finished typing up a computer program that sends a string of characters much like NMEA in a GPS:
$WLO,3,1234,1234,1234,p
Sent through an XBEE the propeller confirms the sent data and then parses the data, supposedly creating a pointer to each of the value between the commas. I'm not exactly sure how the function copy_buffer ( buffer,args) actually works as I took that aspect from a GPS parsing program (see attachment). The program itself is suppose to return one of the values it receives, but currently its only transmitting 4696 instead of 1234. I know that it does actually collect the string I sent it as I can send all the characters from comm_buff back to a terminal screen and its the same.
How does the copy_buffer function work?
What is wrong with my implementation that is making it return the wrong values?
Thanks
This is the code that is running in my propeller
I've been working on my project haphazardly for a while now and now that its winter break I can finally get a bit organized. I'm fixing up my new PCB this Friday and so while that is on hold I've been working on the software protocol with one of my older propeller boards. I just finished typing up a computer program that sends a string of characters much like NMEA in a GPS:
$WLO,3,1234,1234,1234,p
Sent through an XBEE the propeller confirms the sent data and then parses the data, supposedly creating a pointer to each of the value between the commas. I'm not exactly sure how the function copy_buffer ( buffer,args) actually works as I took that aspect from a GPS parsing program (see attachment). The program itself is suppose to return one of the values it receives, but currently its only transmitting 4696 instead of 1234. I know that it does actually collect the string I sent it as I can send all the characters from comm_buff back to a terminal screen and its the same.
How does the copy_buffer function work?
What is wrong with my implementation that is making it return the wrong values?
Thanks
This is the code that is running in my propeller
Con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 led = 17 var byte comm_buff[100] long cptr long Rx long MMMb[100],MMMa[100] long cog,ptr,arg,j long Null[1] byte GPRMCb[68],GPGGAb[80],PGRMZb[40],WLOb[100] long GPRMCa[20],GPGGAa[20],PGRMZa[20],WLOa[20] Obj uart: "pcFullDuplexSerial4FC"' Pub Main |p,int {*****Set up the communications*****} uart.init uart.AddPort(2,2,3,-1,-1,0,0,9600) 'XBEE uart.start repeat until p=="$" p:=uart.rx(2) cptr:=0 repeat until Rx== "p" 'continue to collect data until the end Rx:=uart.rx(2) if Rx == "," comm_buff[cptr++] := 0 ' If "," replace the character with 0 else comm_buff[cptr++] := Rx ' else save the character if comm_buff[0] == "W" if comm_buff[1] == "L" if comm_buff[2] == "O" uart.tx(2,"s") copy_buffer(@WLOb, @WLOa) waitcnt(300_000_000+cnt) repeat uart.dec(2,valid) uart.newline(2) ld show pub copy_buffer ( buffer,args) bytemove(buffer,@comm_buff,cptr) ' copy received data to buffer ptr := buffer arg := 0 repeat j from 0 to 79 ' build array of pointers if byte[ptr] == 0 ' to each if byte[ptr+1] == 0 ' record long[args][arg] := Null ' in else ' the long[args][arg] := ptr+1 ' data buffer arg++ ptr++ ' now we just need to return the pointer to the desired record pub valid return WLOa[1] Pub show repeat dira[19]:=1 outa[19]:=1 waitcnt(10_000_000+cnt) !outa[19] pub ld dira[19]:=1 outa[19]:=1 waitcnt(100_000_000+cnt) !outa[19]
Comments
To write the function more simply:
Computer side:
my computer sends a string that starts with a $ and then the name of the string, so: $WLO, $WLA, $DGS, so on and so forth for a few others
At the end of each string is the letter p which is what tells the propeller that the string has come to an end.
My computer constantly sends it until the propeller sends a character telling it that everything is received.
Propeller side:
The propeller constantly waits until it receives a $ sign.
It then starts collecting the entire string until a p is received.
After sending the confirmation character it needs to view the data that the string has so as an example:
$WLO,3,1234,567,893,p
I need to be able to isolate the 3, the 1234, the 567, and the 893 or more.
Is this what you were looking for?
$WLO,3,1234,567,893,p
...indicate that there are three parameters? Any reason you chose to terminate with "p"? If you use CR then terminal entry is user-intuitive (assuming you want that, as I did in HFCP).
The string header changed from "$" to ">" (this is constant in the program). Why? Well, in my strings library I have the ability to convert a string to a number, and if binary (%) or hex ($) is indicated, those values are properly parsed. If any of your commands have to do with setting/clearing bits, using binary is easier IMHO.
The terminating character is CR to make entry from a terminal very intuitive. The program allows your known commands to have from 0 to 8 parameters -- again, the parameter count can be changed by a constant. The field separator is the comma, and that can be changed, too. One of the methods counts the number of separator characters in your string to know how many parameters you've passed. You can do anything you'd like with them, including using one of them to verify the others.
The screen shot shows the program in action, accepting a decimal, binary, and hex value. Happy Holidays!
Thank you!
Happy holidays to you too!
In case you're interested in my HFCP, which uses numeric commands (versus strings like your "WLO", etc.), I've just posted it in ObEx with a demo program.
-- http://obex.parallax.com/objects/826/
BTW... the numeric conversion code tolerates the underscore character, so the text in your string could be "3_142" -- I use the underscore in most of my listings to make large values easy to read; in this case it could represent a decimal point.