Prop 2 Prop Serial Communication
zlantz
Posts: 136
So, I have been putting together a means of serial prop 2 prop comms (2-wire) for a project I am working on. I can send data from one chip to the other and i can view it directly on the second chip. However, I need to parse the data from the stream so it can be used, not just viewed. That is were the problems come in.
For this example, I am sending Parsed GPS data from Prop2 to Prop1:
I am using FullDuplexSerial4port.spin to save cog space, however, I have tested with FullDuplexSerial.spin as well.
and on the receiving side (Prop1):
Displays received data from Prop2 Correctly.
My problem comes in when I try to Parse the data.
I have 20 GPS data items, 11 Waypoint items, 6 Filtered items & 2 Misc items that are being sent from Prop2 to Prop1.
My string format was made to be similar to GPS data so i could just modify a gps parseing method.
ie:
$GPS,1,2,3,4,...18,19,20
$WAP,1,2,3,...10,11
$LCF,1,2,3,4,5,6
$AIR,1,2
Each ending with a <CR> (ser.tx(13)).
*** Problem is HERE
The parsing code (Replaces above Prop1 Code):
When I run the above parsing code, it makes it threw, however, everything is garbled & propterm "dings" alot. Kinda similar to missmatched baudrates or incorrect timing. but i have checked these. multiple times even! I cannot track down were the problem is.
Now i know these are the "expected" problems when adopting someone elses code.
BUT... Can you show me another example that can handle multiple strings with mixed characters that is not adopting someone elses code???
There is not too much info floating around the internet on this one. It would be nice to have a fully working prop2prop comms system.
Can I get a little help?
Thanks,
Zack
For this example, I am sending Parsed GPS data from Prop2 to Prop1:
' This runs in its own cog (Prop2): ' // Prop 2 Prop Communications (*** Typically Transmitting, Bi-Directional) Pri rxP2P repeat SendData ' Send Data to Propeller 1 SendDataTerm ' Send Data to PropTerm (Identical to Above)
I am using FullDuplexSerial4port.spin to save cog space, however, I have tested with FullDuplexSerial.spin as well.
and on the receiving side (Prop1):
' This runs in its own cog (Prop1): ' // Prop 2 Prop Communications (*** Typically Recieving, Bi-Directional) Pub rxP2P repeat ser.tx(pDBG, ser.rx(pSer))
Displays received data from Prop2 Correctly.
My problem comes in when I try to Parse the data.
I have 20 GPS data items, 11 Waypoint items, 6 Filtered items & 2 Misc items that are being sent from Prop2 to Prop1.
My string format was made to be similar to GPS data so i could just modify a gps parseing method.
ie:
$GPS,1,2,3,4,...18,19,20
$WAP,1,2,3,...10,11
$LCF,1,2,3,4,5,6
$AIR,1,2
Each ending with a <CR> (ser.tx(13)).
*** Problem is HERE
The parsing code (Replaces above Prop1 Code):
byte p2p_buff[500] ' Extra Large for Debug long P2P_Stack[100] ' Extra Large for Debug 'byte GPSb[68], WAPb[40], LCFb[40], AIRb[40] ' Original Sizes for GPS byte GPSb[100], WAPb[100], LCFb[100], AIRb[100] ' Extra Large Buffers long GPSa[20], WAPa[20], LCFa[20], AIRa[20] ' Original Sizes for GPS ' This runs in its own cog: ' // Prop 2 Prop Communications (*** Typically Recieving, Bi-Directional) Pub rxP2P Null[0] := 0 repeat longfill(p2p_buff,20,0) repeat while Rx <>= "$" ' wait for the $ to insure we are starting with Rx := ser.rx(pSer) ' a complete NMEA sentence cptr := 0 repeat while Rx <>= CR ' continue to collect data until the end of the NMEA sentence Rx := ser.rx(pSer) ' get character from Rx Buffer if Rx == "," p2p_buff[cptr++] := 0 ' If "," replace the character with 0 else p2p_buff[cptr++] := Rx ' else save the character if p2p_buff[0] == "G" if p2p_buff[1] == "P" if p2p_buff[2] == "S" copy_buffer(@GPSb, @GPSa) if p2p_buff[0] == "W" if p2p_buff[1] == "A" if p2p_buff[2] == "P" copy_buffer(@WAPb, @WAPa) if p2p_buff[0] == "L" if p2p_buff[1] == "C" if p2p_buff[1] == "F" copy_buffer(@LCFb, @LCFa) if p2p_buff[0] == "A" if p2p_buff[1] == "I" if p2p_buff[2] == "R" copy_buffer(@AIRb, @AIRa) ' // Update Stored Values in Memory UpdateProp2Data ' // Display Prop1 & Prop2 Data in PropTerm SendDataTerm Pri copy_buffer (buffer,args) bytemove(buffer,@p2p_buff,cptr) ' copy received data to buffer ptr := buffer arg := 0 repeat j from 0 to 45 '78 ' build array of pointers ' I only have 43 Records 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++
When I run the above parsing code, it makes it threw, however, everything is garbled & propterm "dings" alot. Kinda similar to missmatched baudrates or incorrect timing. but i have checked these. multiple times even! I cannot track down were the problem is.
Now i know these are the "expected" problems when adopting someone elses code.
BUT... Can you show me another example that can handle multiple strings with mixed characters that is not adopting someone elses code???
There is not too much info floating around the internet on this one. It would be nice to have a fully working prop2prop comms system.
Can I get a little help?
Thanks,
Zack
Comments
I bet that's not what your want. It's setting Rx to true which will be -1 if Rx is a long or 255 if Rx is byte.
You want to use "<>" instead.
"<=", ">=" and "<>=" all are assignment operators not just comparison operators.
I am aware of the <>=, I will try this still, however, that is what was needed to get it working in the gps parseing module (which works fine & is where i got my template from).
Edit: I believe that in every gps parse .spin that uses readNEMA you will notice that it is preset to "<>=".
The gps data comes in raw, gets parsed, gets other data added to it, then sent to second propeller, which then must reparse the data. Kind of a bit of a mess.
Edit: Just tested without the "=" & returns the same mess of mombo jumbo.
Sorry about the bad advice.
It's been a couple years since I worked on my GPS pedometer but I do remember the GPS objects I could find at the time were very convoluted. There were at least three cogs being used which weren't needed. I ended up moving child objects into the parent object and having a giant sized parent object. The code was still a mess but I was able to trim off the wasted cogs.
I also used a four port serial driver. I used one port to connect to the GPS, one to send debug information to a terminal window and a third line to communicate with a second Propeller being used as a graphics slave (touchscreen).
I've attached a couple of screenshots showing the many methods the parent object ended up with after combining.
I don't like the way my program turned out but it did work. I don't know if you're trying to use the same objects I used, but if you are, it might be easier to combine the objects into one monster object.
Hopefully there are presently more options for using GPS on the Propeller than there were when I experimented with GPS.
Troublshooting ideas. Dump the contents of GPSb, WAPb, LCFb, and AIRb right before calling UpdateProp2Data. Compare the "b" buffers with the raw data state of p2p_buff. For example, write p2p_buff buffer to the terminal before the buffer is modified by rxP2P. Then write the contents of GPSb to the terminal. Are the values expected? Next write the strings pointed to by the "a" buffers. Does the data look right? Do the next comparison.
From there, you can make a decision on what to do next.
I have created a 1 cog gps method using 4 port serial, all the code & waypoint calculations are done in the gps cog, and works like a charm. The expected 2-3 cogs just for gps is ridiculous.
Gonna go try your suggestion real quick, will post back with results...
OK, so here is what I did:
I even tried commenting them out back to #1 with the same issue. Take a look at attached pic of my propterm data, at the bottom you can se it gets a word or two right.
The data is completely garbled & propterm dings even after i close it! and it keeps causing PropTerm to Crash!!!
i have tried sending the data out as a string & as a decimal, both cause same issue.
This happens with all 3 buffers (p2p_buff and ###a / ###b buffers).
so it would seem the problem lies in the memory allocation. When i try to access the values, everything starts to crash.
Ok, so by doing this super simple test, the data still comes back farqued.
What exactly am i doing wrong? Possible causes???
Add code to store the received data in a buffer and send that buffered data to PST. Verify that the data is displayed correctly both times.
Add code to parse the first field of the NEMA sentence and send each character to PST as it is added to the buffer for that field.
Add code to send the stored data for the first field to PST.
Once the first field is parsed and stored properly add the code for the additional fields.
BTW, you can use string compare “STRCOMP (StringAddress1, StringAddress2 )” for strings instead of comparing one character at a time.
Yes, IF i was using FullDuplexSerial, however, i am uing FullDuplexSerial4Port which works a bit different, it uses dio.dec instead of str.dec, and i have tried in both situations. I left it as a str because 1, that works in my other circuit, and 2, the data being displayed is a mixture of decimal & non-decimal.
here you will see i have tried this way as well:
I thought the same way as you, until I tried it & gave satisfactory results. Had some issues with Floating Point numbers that were parsed out of the original gps codes. The data out from the above code on my other project is 100% correct.
The only difference between the two really is i added a second propeller chip & moved the gps to it. so the base code was just copied from the other to this one & updated accordingly.
OK, it took me forever to figure out what you were talking about.
Fixed that, now shows the right count ie 1: 2: 3: etc, however, the data that follows is still garbled or nothing at all.
Yes, i believe that is the original .spin floating around. I had to add a few things to handle the string to floating point conversions and what not.
EDIT: I read up on that link, only thing I really got from it was change 78 to cptr - 1 and it might not do anything.
I have tried giving excessive & excessive under required stack space to no avail.
Parsing data with the propeller chip would have to be one of the most difficult things I have had to deal with.
P2P Comms Rx.zip
Attachment not found.
I have it setup right now for super crude testing, cpu2 sends the same strings over & over to cpu1. cpu1 just displays what it is receiving.
data is garbled.
EDIT: I wish Spin had a way to specify types and do type-checking. That would catch problems like this at compile time.
The other thing is, copy_buffer scans a byte array (where all commas have been replaced with \0) and builds an array of string pointers into said byte array. IOW all ???a[] arrays only hold addresses which get assigned to dedicated long variables in UpdateProp2Data. Finally, in SendDataTerm you print some of them as strings (OK) but convert others from assumed float values (NG). E.g. Here Latitude is still just an address which points to a latitude string. If that function is an indication as to how the data is sent to the second chip then it's no suprise that some data is meaningless.
as for senddataterm, if you try to ser.tx or ser.dec (in my case dio.dec) the floating point value, you will get the wrong result. you have to fs.floattostring the data out to keep it visibly correct for the PC to parse. now mind you, up until now i have only been doing Prop to PC & PC to Prop no problems sending whole decimal numbers from the pc to prop & comma decimated string of floats & decimals & strings from the prop to the pc.
not sure how to read alpha-numeric with the PC to Prop parsing method or i would use it:
Parsing is not my skill, I am more of a math person.
so to use addresses to data instead of the data itself, does that mean to get the actual stored value I would need to put an @ infront of whichever byte array i am trying to obtain data from?
Assuming I am using the standard GPS_mini.spin,you are correct. ser.str(pDBG, latitude) will return the correct human readable, however, you will not be able to do calculations with it as a string. what you dont see, is in my gps_wap.spin i convert it to a Floating Point, do some math with it (waypoint calculations) and then send the data & calculated data (Now Floating Point not String) to prop1 which adjusts flight & relays data via wifi to pc (which in my other project it only has one cpu so it does the math & sends the results to pc via wifi).
You did not see this because i did not post my entire project. instead i posted a stripped down version that only shows what we were discussing.
For example, what I use to convert from string to floating point (on Prop2 which handles the GPS & Waypoint calculations before sending the data to prop1):
Up until now, I didnt know there was a new floatstring out. mine does not include a method for string to float & is why i had to resort to using the above code. Knowing now it is available I will go and update some of my code, if it gives good results.
Also, when i output ***a i used dio.dec, which with FullDuplexSerial4port, dio.dec is equivalent to ser.dec.
Just a thought...
yes, i tried all of them. a few didnt work at all, gps_mini gives good results but they are all strings & unusable in math, one other (i think gps_io) gave float results but was missing 90% of the gps data. I couldnt just get one that worked 100%.
I would post mine, but it is partially unfinished. I will post when finished.