Shop OBEX P1 Docs P2 Docs Learn Events
Prop 2 Prop Serial Communication — Parallax Forums

Prop 2 Prop Serial Communication

zlantzzlantz Posts: 136
edited 2014-01-11 19:59 in Propeller 1
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:
' 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
«1

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-01-07 21:18
    One thing that jumps out is your use of "<>=".

    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.
  • zlantzzlantz Posts: 136
    edited 2014-01-08 00:09
    Duane Degn wrote: »
    One thing that jumps out is your use of "<>=".

    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.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-01-08 01:12
    zlantz wrote: »
    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.
    1024 x 755 - 94K
    1024 x 393 - 49K
  • Mike GMike G Posts: 2,702
    edited 2014-01-08 04:13
    All to often a suspect snippet of code posted in the forum is not the problem. The problem is usually elsewhere in the code base.

    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.
  • zlantzzlantz Posts: 136
    edited 2014-01-08 07:54
    Duane Degn wrote: »
    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.


    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.
  • zlantzzlantz Posts: 136
    edited 2014-01-08 08:14
    hmm, i am going to have to try this. i have stripped out all the other code in my project (made a test platform) so all it is doing is receiving and parsing the data from prop2, so the problem i am facing can only be inside of rxP2P.

    Gonna go try your suggestion real quick, will post back with results...
  • zlantzzlantz Posts: 136
    edited 2014-01-08 08:40
    Mike G wrote: »
    All to often a suspect snippet of code posted in the forum is not the problem. The problem is usually elsewhere in the code base.

    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.

    OK, so here is what I did:
    ' // Prop 2 Prop Communications  (*** Typically Recieving, Bi-Directional) 
    Pub rxP2P
      Null[0] := 0
      repeat
    
        ' // Send "Keep-Alive" Message   ' (GPIO9 = Off, RPi Command = None) 
        'Ser.str(pSer, string("$RST,Test-A,"))
        'Ser.tx (pSer, CR)    
        'Ser.str(pSer, string("$RPI,Test-B,"))    ' Send Data to Propeller 2
        'Ser.tx (pSer, CR)
    
        'ser.tx(pDBG, ser.rx(pSer))  
    
        
        longfill(p2p_buff,20,0)    
    
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)      
        ser.str(pDBG, string("Show Buffers 1:"))    
        ShowBuffers
        
        'repeat while Rx <>= "$"      ' wait for the $ to insure we are starting with
        repeat while Rx <> "$"      ' wait for the $ to insure we are starting with
        'repeat until 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
        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   
    
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)          
        ser.str(pDBG, string("Show Buffers 2:"))
        ShowBuffers
    
        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)
    
                
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)  
        ser.str(pDBG, string("Show Buffers 3:"))
        ShowBuffers        
        
        ' // Update Values
        UpdateProp2Data
    
        ' // Display Prop1 & Prop2 Data in PropTerm   
        'SendDataTerm
        
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)  
        ser.str(pDBG, string("Show Buffers 4:"))
        ShowBuffers
        
    
    Pri ShowBuffers | i
    
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)    
        ser.str(pDBG, string("'B' Buffers:"))    ' GPS
        ser.tx(pDBG, 13)
    
      '  byte GPSb[100], WAPb[100], LCFb[100], AIRb[100]
      '  byte GPSb[100], WAPb[40], LCFb[40], AIRb[40]      
      '  long GPSa[20], WAPa[20], LCFa[20], AIRa[20]
    
        ' // GPSb
        repeat i from 0 to 100
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))                 
          ser.str(pDBG, GPSb[i])     
          ser.tx(pDBG, 13)
    
        ' // WAPb
        repeat i from 0 to 100
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))                 
          ser.str(pDBG, WAPb[i])     
          ser.tx(pDBG, 13)      
    
        ' // LCFb
        repeat i from 0 to 100
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))            
          ser.str(pDBG, LCFb[i])     
          ser.tx(pDBG, 13)      
    
        ' // AIRb
        repeat i from 0 to 100
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))         
          ser.str(pDBG, AIRb[i])     
          ser.tx(pDBG, 13)
    
          
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)    
        ser.str(pDBG, string("'A' Buffers:"))    ' GPS
        ser.tx(pDBG, 13)
    
      '  byte GPSb[100], WAPb[100], LCFb[100], AIRb[100]
      '  byte GPSb[100], WAPb[40], LCFb[40], AIRb[40]      
      '  long GPSa[20], WAPa[20], LCFa[20], AIRa[20]
    
        ' // GPSa
        ser.tx(pDBG, 13)
        repeat i from 0 to 20
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))          
          ser.str(pDBG, GPSa[i])     
          ser.tx(pDBG, 13)
    
        ' // WAPa
        ser.tx(pDBG, 13)
        repeat i from 0 to 20
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))         
          ser.str(pDBG, WAPa[i])     
          ser.tx(pDBG, 13)
    
          ' // LCFa
        ser.tx(pDBG, 13)
        repeat i from 0 to 20
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))         
          ser.str(pDBG, LCFa[i])     
          ser.tx(pDBG, 13)
    
        ' // AIRa
        ser.tx(pDBG, 13)
        repeat i from 0 to 20
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))         
          ser.str(pDBG, AIRa[i])     
          ser.tx(pDBG, 13)
    

    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.

    P2P Issue.jpg
    1024 x 654 - 67K
  • zlantzzlantz Posts: 136
    edited 2014-01-08 09:39
    byte p2p_buff[200]
    
    ' // Prop 2 Prop Communications  (*** Typically Recieving, Bi-Directional) 
    Pub rxP2P | Rx, i
    
      repeat
    
        repeat i from 0 to 100
          p2p_buff[i] := i
    
    
        ShowP2PBuff
    
    
    Pri ShowP2PBuff | i    
    
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)    
        ser.str(pDBG, string("P2P_Buff:"))    ' GPS
        ser.tx(pDBG, 13)
    
        repeat i from 0 to 200
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))      
          dio.dec(pDBG, P2P_Buff[i])     ' Also tried ser.str, same output
          ser.tx(pDBG, 13)
          
    
    



    Ok, so by doing this super simple test, the data still comes back farqued.

    What exactly am i doing wrong? Possible causes???


    P2P Issue 2.jpg
    1024 x 654 - 64K
  • kwinnkwinn Posts: 8,697
    edited 2014-01-08 09:42
    My troubleshooting technique is to start with the simplest possible code by commenting out all code except that needed to receive the entire string and echo that to PST for verification. Sounds like you have already done this, but it is a good idea to start back at this point.

    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.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-01-08 09:50
    ser.str(pDBG, i) should be ser.dec(pDBG, i). The way you have it right now will print garbage characters.
  • zlantzzlantz Posts: 136
    edited 2014-01-08 10:30
    Dave Hein wrote: »
    ser.str(pDBG, i) should be ser.dec(pDBG, i). The way you have it right now will print garbage characters.

    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:
      
    ' // Prop 2 Prop Communications  (*** Typically Recieving, Bi-Directional) 
    Pub rxP2P | i
    
      repeat
    
        ' // Send "Keep-Alive" Message   ' (GPIO9 = Off, RPi Command = None) 
        'Ser.str(pSer, string("$RST,Test-A,"))
        'Ser.tx (pSer, CR)    
        'Ser.str(pSer, string("$RPI,Test-B,"))    ' Send Data to Propeller 2
        'Ser.tx (pSer, CR)
    
        'ser.tx(pDBG, ser.rx(pSer))    
    
        ' Testing buffers now:
    
        repeat i from 0 to 200
          p2p_buff[i] := i
    
    
        ShowP2PBuff
    
      {
      
        'ser.tx(pDBG, 13)
        'ser.tx(pDBG, 13)      
        'ser.str(pDBG, string("Show Buffers 1:"))    
        'ShowBuffers
        
        longfill(p2p_buff,20,0)
    
        'ShowP2PBuff
            
        repeat while Rx <>= "$"      ' wait for the $ to insure we are starting with
        'repeat while Rx <> "$"      ' wait for the $ to insure we are starting with
        'repeat until Rx == "$"      ' wait for the $ to insure we are starting with
        'repeat while ser.rx(pSer)  <> "$"      ' wait for the $ to insure we are starting with
          Rx := ser.rx(pSer)         '   a complete NMEA sentence
          'Rx := sSer.rx              '   a complete NMEA sentence
                
        cptr := 0     
        repeat while Rx <>= CR       '  continue to collect data until the end of the NMEA sentence
        'repeat while Rx <> CR       '  continue to collect data until the end of the NMEA sentence     
          Rx := ser.rx(pSer)         '  get character from Rx Buffer
          'Rx := sSer.rx              '  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   
    
        'ser.tx(pDBG, 13)
        'ser.tx(pDBG, 13)          
        'ser.str(pDBG, string("Show Buffers 2:"))
        'ShowBuffers
    
        'ShowP2PBuff
    
        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)
    
    
        ser.str(pDBG, p2p_buff[0])
        ser.str(pDBG, p2p_buff[1])
        ser.str(pDBG, p2p_buff[2])            
        ser.tx(pDBG, 13)
      
    
                           
        'ser.tx(pDBG, 13)
        'ser.tx(pDBG, 13)  
        'ser.str(pDBG, string("Show Buffers 3:"))
        'ShowBuffers        
        
        ' // Update Values
        UpdateProp2Data
    
        ' // Max Number is 109:
        'ser.tx(pDBG, 13)
        'dio.dec(pDBG, cptr)
        
        ' // Display Prop1 & Prop2 Data in PropTerm   
        'SendDataTerm
        
        'ser.tx(pDBG, 13)
        'ser.tx(pDBG, 13)  
        'ser.str(pDBG, string("Show Buffers 4:"))
        'ShowBuffers
      } 
        
        
    
    Pri ShowP2PBuff | i    
    
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)    
        ser.str(pDBG, string("P2P_Buff:"))    ' GPS
        ser.tx(pDBG, 13)
    
        ' byte p2p_buff[200]
    
        repeat i from 0 to 200
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))      
          ser.str(pDBG, p2p_buff[i])     
          ser.tx(pDBG, 13)
          
    
    Pri ShowBuffers | i
    
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)    
        ser.str(pDBG, string("'B' Buffers:"))    ' GPS
        ser.tx(pDBG, 13)
    
      '  byte GPSb[100], WAPb[100], LCFb[100], AIRb[100]
      '  byte GPSb[100], WAPb[40], LCFb[40], AIRb[40]      
      '  long GPSa[20], WAPa[20], LCFa[20], AIRa[20]
    
        ' // GPSb
        repeat i from 0 to 50
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))      
          dio.dec(pDBG, GPSb[i])     
          ser.tx(pDBG, 13)
    
        ' // WAPb
        repeat i from 0 to 50
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))                 
          dio.dec(pDBG, WAPb[i])     
          ser.tx(pDBG, 13)      
    
        ' // LCFb
        repeat i from 0 to 50
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))            
          dio.dec(pDBG, LCFb[i])     
          ser.tx(pDBG, 13)      
    
        ' // AIRb
        repeat i from 0 to 50
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))         
          dio.dec(pDBG, AIRb[i])     
          ser.tx(pDBG, 13)
    
          
        ser.tx(pDBG, 13)
        ser.tx(pDBG, 13)    
        ser.str(pDBG, string("'A' Buffers:"))    ' GPS
        ser.tx(pDBG, 13)
    
      '  byte GPSb[100], WAPb[100], LCFb[100], AIRb[100]
      '  byte GPSb[100], WAPb[40], LCFb[40], AIRb[40]      
      '  long GPSa[20], WAPa[20], LCFa[20], AIRa[20]
    
        ' // GPSa
        ser.tx(pDBG, 13)
        repeat i from 0 to 20
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))          
          dio.dec(pDBG, GPSa[i])     
          ser.tx(pDBG, 13)
    
        ' // WAPa
        ser.tx(pDBG, 13)
        repeat i from 0 to 20
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))         
          dio.dec(pDBG, WAPa[i])     
          ser.tx(pDBG, 13)
    
          ' // LCFa
        ser.tx(pDBG, 13)
        repeat i from 0 to 20
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))         
          dio.dec(pDBG, LCFa[i])     
          ser.tx(pDBG, 13)
    
        ' // AIRa
        ser.tx(pDBG, 13)
        repeat i from 0 to 20
          ser.str(pDBG, i)
          ser.str(pDBG, string(": "))         
          dio.dec(pDBG, AIRa[i])     
          ser.tx(pDBG, 13)
          
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-01-08 10:35
    I've never used FullDuplexSerial4Port, but it's clear that ser.str(pDBG, i) is not right, and will most likely print garbage characters. You are telling ser.str to us i as a string pointer, which can't be right.
  • zlantzzlantz Posts: 136
    edited 2014-01-08 10:57
    Going to attempt re-writing another code snipplet to see if it will work in place of the modded gps code i have been using:
    ''****************************************
    ''*  QuickStart Communicator V1.0        *
    ''*  Copyright (c) 2011 Parallax, Inc.   *
    ''*  See end of file for terms of use.   *
    ''****************************************
    ''
    '' Communicates with QuickStart Communicator VB.NET application to transfer variables between the Propeller and the PC.
    '' This object serves as a template for building your own applications.  Simply remove the four lines from the demo below.
    
    
    CON
    
      _CLKMODE = XTAL1 + PLL16X                                                     ' Use crystal x 16                                                                             
      _XINFREQ = 5_000_000                                                          ' 5 MHz crystal (system clock = 80 MHz)
    
    
    CON
    
      RX_PIN  = 31                                                                  ' Propeller RX pin
      TX_PIN  = 30                                                                  ' Propeller TX pin
      SDA_PIN = 29                                                                  ' I2C SDA pin
      SCL_PIN = 28                                                                  ' I2C SCL pin
                                                                                    
      LED7    = 23                                                                  ' Highest button on QuickStart Board
      LED0    = 16                                                                  ' Lowest button on QuickStart Board
                                                                                    
    
    CON
    
      PC_BAUD = 38_400                                                              ' Optimum Baud Rate for PC application
      MODE    = %0000                                                               ' Serial Port mode (See FullDuplexSerial.spin)   
    
    
    OBJ
    
      serial  : "FullDuplexSerial"                                                  ' Handles serial communication
      buttons : "Touch Buttons"                                                     ' Reads Touch Pads On QuickStart Board
      
      
    VAR
    
      Byte datain[16]                                                               ' 16 byte array for incoming data
      Byte dataout[16]                                                              ' 16 byte array for outgoing data
      Long stack[32]                                                                ' Stack space reserved for Communicate method
    
      
    PUB Main
     
      cognew(PC_Comms, @stack)                                                      ' Launch Communicate method into a new cog
      buttons.start(CLKFREQ / 100)                                                  ' Launch new cog for button detection (only used by QuickStart Board for Demo) 
    
    '' User code begins here
      
      dira[LED7..LED0] := %1111_1111                                                ' Set LED 0-7 I/O lines to output (required for QuickStart Communicator Demo)
      
      repeat                                                                        ' Loop indefinitely (required for QuickStart Communicator Demo)
        outa[LED7..LED0] := dataout[0] := datain[0]                                 ' Activate LEDs and return confirmation to VB application (required for QuickStart Communicator Demo) 
        dataout[1] := buttons.State                                                 ' Encode touch switches into second byte of array (required for QuickStart Communicator Demo)
      
    
    PRI PC_Comms | iobyte, index                                                    ' Declare private method and 2 local variables
    
      serial.start(RX_PIN, TX_PIN, MODE, PC_BAUD)                                   ' Start UART (FullDuplexSerial) cog
      serial.rxflush                                                                ' Flush receive buffer
    
      repeat                                                                        ' Loop indefinitely
        index := 0
        repeat 
          iobyte := serial.rxtime(10)                                               ' Get character
          if iobyte == byte[@pcheader][index]                                       ' Header match?
            index += 1                                                              ' Yes, try next
          else
            index := 0                                                              ' No, restart
        until index == 4                                                            ' Header complete
            
        repeat index from 0 to 15                                                   ' Get 16-byte packet from PC
          iobyte := serial.rxtime(10) 
          if iobyte => 0            
            datain[index] := iobyte     
          else
            quit                                                                    ' Abort on timeout
    
        serial.str(@myheader)                                                       ' Send header to PC
        repeat index from 0 to 15                                                   ' Send 16-byte packet to PC        
          serial.tx(dataout[index])      
                 
    
    DAT
    
    pcheader                Byte    "!VB", 10 
    myheader                Byte    "!P1", 10, 0
    
        
    DAT
    
    {{
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                                                   TERMS OF USE: MIT License                                                  &#9474;                                                            
    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
    &#9474;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    &#9474; 
    &#9474;files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    &#9474;
    &#9474;modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software&#9474;
    &#9474;is furnished to do so, subject to the following conditions:                                                                   &#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          &#9474;
    &#9474;WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         &#9474;
    &#9474;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   &#9474;
    &#9474;ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    }}
    
  • zlantzzlantz Posts: 136
    edited 2014-01-08 11:05
    seems strange dosent it? This is what i use on my other project. I just copied it over:
        ser.str(pWiFi, string("$GPS"))    ' GPS
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, Valid)    
        ser.str(pWiFi, string(","))      
        ser.str(pWiFi, Date)    
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, fs.floattostring(Altitude))
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, fs.floattostring(Speed))
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, fs.floattostring(Heading))
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, Time)
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, fs.floattostring(Latitude))
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, N_S)    
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, fs.floattostring(Longitude))
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, E_W)
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, Satellites)
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, hdop)
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, fs.floattostring(Heading2))
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, fs.floattostring(SpeedKn))
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, SpeedKm)
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, fs.floattostring(Lat2))
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, N_S2)
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, fs.floattostring(Lon2))
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, E_W2)
        ser.str(pWiFi, string(","))
        ser.str(pWiFi, GPS_Alt)
    

    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.
  • zlantzzlantz Posts: 136
    edited 2014-01-08 11:23
    Dave Hein wrote: »
    I've never used FullDuplexSerial4Port, but it's clear that ser.str(pDBG, i) is not right, and will most likely print garbage characters. You are telling ser.str to us i as a string pointer, which can't be right.


    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.



    P2P Issue 3.jpg
    1024 x 666 - 76K
  • kuronekokuroneko Posts: 3,623
    edited 2014-01-08 17:39
    The code looks like it's been taken from GPS_IO_mini. If so check this [post=1089392]post[/post] and/or thread.
  • zlantzzlantz Posts: 136
    edited 2014-01-08 18:26
    kuroneko wrote: »
    The code looks like it's been taken from GPS_IO_mini. If so check this [post=1089392]post[/post] and/or thread.

    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.
  • kuronekokuroneko Posts: 3,623
    edited 2014-01-08 19:03
    Can you please archive your project and attach it here?
  • zlantzzlantz Posts: 136
    edited 2014-01-09 07:43
    kuroneko wrote: »
    Can you please archive your project and attach it here?

    P2P Comms Rx.zip
  • zlantzzlantz Posts: 136
    edited 2014-01-09 10:35
    I have created a new test project, this one appears more likely to succeed, however, it has issues as well. It will transmit, but not receive.

    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.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-01-09 11:04
    This loop has a problem.
      repeat
    
        ser.str(pDBG, ser.rx(pSer))
    
    If the RX method works like it does in FDS then you are using the received character value as a string pointer. Try using the tx method in place of the str method.

    EDIT: I wish Spin had a way to specify types and do type-checking. That would catch problems like this at compile time.
  • kuronekokuroneko Posts: 3,623
    edited 2014-01-09 18:46
    From CPU 1 Test.spin:
    longfill(p2p_buff,20,0)
    
    It's currently (luckily) doing nothing so either remove it or fix it.

    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.
    ser.str(pDBG, fs.floattostring(Latitude))
    
    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.
  • zlantzzlantz Posts: 136
    edited 2014-01-10 00:48
    Ok, so longfill(buffer, 20, 0) is how it was wrote in the original file. my understanding (according to propeller pdf) is it should be (buffer, 0, 20) from propeller pdf: LONGFILL(StartAddress, Value, Count ). i just left it how it is as that works fine. dont fix it if it aint broken right =).

    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:
    ' // Get Servo Data from PC  
    PRI rxServoData : v | i, ch      ' Receive and parse servo data  *** Runs in Own Cog
      repeat
        rCnt := 0        
        repeat until ser.rx(pWiFi) == "$"
          rCnt++
        repeat i from 0 to 8    
          v := 0
          repeat
            ch := ser.rx(pWiFi) 
            case ch
              "0".."9":  v := v*10 + ch-"0"
              other:     quit
    
          ServoPos[i] := v
    

    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?
  • kuronekokuroneko Posts: 3,623
    edited 2014-01-10 01:22
    zlantz wrote: »
    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.
    That's because it isn't a floating point value, just its ASCII representations (human readable). If you want to print it you'd use e.g. ser.str(pDBG, latitude), in case you actually want a floating point value (32bit) you'll have to convert the string (FloatString 1.2 does that for you). Below an example which hopefully makes things a bit clearer (requires FloatString 1.2):
    CON
      _clkmode = XTAL1|PLL16X
      _xinfreq = 5_000_000
    
    OBJ
      serial: "FullDuplexSerial"
          fs: "FloatString"
    
    VAR
      long  floatValue
      long  GPSa[20]
     
    PUB null
    
      GPSa[5] := string("42.395")                           ' string address as result from copy_buffer
    
      serial.start(31, 30, %0000, 115200)
      waitcnt(clkfreq*3 + cnt)
    
      serial.str(GPSa[5])                                   ' display as string (from address)
      serial.tx(13)
    
      floatValue := fs.StringToFloat(GPSa[5])               ' convert to 32bit FP
    
      serial.hex(floatValue, 8)                             ' print as hex
      serial.tx(32)
      serial.str(fs.FloatToString(floatValue))              ' and as string again
      serial.tx(13)
    
    DAT
    
    So if you just send the whole string to the other chip then no conversion is required unless you add modifications which aren't strings.
  • zlantzzlantz Posts: 136
    edited 2014-01-10 08:46
    kuroneko wrote: »
    That's because it isn't a floating point value, just its ASCII representations (human readable). If you want to print it you'd use e.g. ser.str(pDBG, latitude), in case you actually want a floating point value (32bit) you'll have to convert the string (FloatString 1.2 does that for you). Below an example which hopefully makes things a bit clearer (requires FloatString 1.2)

    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):
    Pri Float_Latitude_Deg : floatVal | p, d, m, mf, fd
    '-------------------------------------------------------------------------
    '--------------------------&#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;-------------------------
    '--------------------------&#9474; Float_Latitude_Deg &#9474;-------------------------
    '--------------------------&#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;-------------------------
    '-------------------------------------------------------------------------
    ''     Action: It returns Latitude in decimal degrees
    '' Parameters: None                                 
    ''    Results: Latitude in signed float as decimal degrees
    ''+Reads/Uses: floatNaN                                               
    ''    +Writes: None                                    
    ''      Calls: GPS_Str_NMEA-------------->NMEA.Str_Latitude
    ''                                        NMEA.Str_Lat_N_S 
    ''             Float32Full--------------->F.FFloat
    ''                                        F.FAdd
    ''                                        F.FDiv
    '-------------------------------------------------------------------------
    
      p := GPGGAa[1]
       
      'Check for not "D", I.e. data received
      IF BYTE[p] == "D"
        RETURN floatNaN
      'Cross check decimal point to be sure
      IF BYTE[p + 4] <> "."
        RETURN floatNaN
        
      d := 10 * BYTE[p] + BYTE[p + 1] - $210
      m := 10 * BYTE[p + 2] + BYTE[p + 3] - $210
       
      CASE STRSIZE(p)
        8:
          mf := 10*(10*BYTE[p+5]+BYTE[p+6])+BYTE[p+7]-$14D0
          fd := 1000.0 
        9:
          mf := 10*(10*(10*BYTE[p+5]+BYTE[p+6])+BYTE[p+7])+BYTE[p+8]-$D050
          fd := 10_000.0
          
      m := F.FAdd(F.FFloat(m),F.FDiv(F.FFloat(mf),fd))
      d := F.Fadd(F.FFloat(d),F.FDiv(m,60.0))
       
      'Check N S hemispheres
      p := ggaN_S
      IF BYTE[p] == "S"
        d ^= $8000_0000           'Negate it
       
      RETURN d
    
    
    Pri Float_Longitude_Deg : floatVal | p, d, m, mf, fd
    '-------------------------------------------------------------------------
    '------------------------&#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;--------------------------
    '------------------------&#9474; Float_Longitude_Deg &#9474;--------------------------
    '------------------------&#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;--------------------------
    '-------------------------------------------------------------------------
    ''     Action: It returns Longitude in decimal degrees
    '' Parameters: None                                 
    ''    Results: Longitude in signed float as decimal degrees
    ''+Reads/Uses: floatNaN                                               
    ''    +Writes: None                                    
    ''      Calls: GPS_Str_NMEA-------------->NMEA.Str_Longitude
    ''                                        NMEA.Str_Lon_E_W
    ''             Float32Full--------------->F.FFloat
    ''                                        F.FAdd
    ''                                        F.FDiv                  
    '-------------------------------------------------------------------------
    
      p := GPGGAa[3]
       
      'Check for not "D", I.e. data received
      IF BYTE[p] == "D"
        RETURN floatNaN
      'Cross check decimal point to be sure
      IF BYTE[p + 5] <> "."
        RETURN floatNaN
        
      d := 10 * ( 10 * BYTE[p] + BYTE[p + 1]) + BYTE[p + 2] - $14D0
      m := 10 * BYTE[p + 3] + BYTE[p + 4] - $210
       
      CASE STRSIZE(p)
        9:
          mf := 10*(10*BYTE[p+6]+BYTE[p+7])+BYTE[p+8]-$14D0
          fd := 1000.0 
        10:
          mf := 10*(10*(10*BYTE[p+6]+BYTE[p+7])+BYTE[p+8])+BYTE[p+9]-$D050
          fd := 10_000.0
          
      m := F.FAdd(F.FFloat(m),F.FDiv(F.FFloat(mf),fd))
      d := F.Fadd(F.FFloat(d),F.FDiv(m,60.0))
       
      'Check E W hemispheres
      p := ggaE_W
      IF BYTE[p] == "W"
        d ^= $8000_0000           'Negate it
       
      RETURN d
    

    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.
  • zlantzzlantz Posts: 136
    edited 2014-01-10 09:05
    So i just tired what you said, and used ser.str(pDBG, ***a). you will see i get garbage data from the picture p2p rx 2. the other picture p2p rx shows what prop1 is receiving a clean data stream when i use ser.tx(pDBG, ser.rx(pSer)).

    p2p rx 2.jpgp2p rx.jpg
    1024 x 657 - 82K
    1024 x 657 - 102K
  • zlantzzlantz Posts: 136
    edited 2014-01-10 10:04
    i changed longfill(buffer,20,0) to longfill(buffer,0,20) like it is suppose to be. now the ***a & ***b buffers are filling with data, however, it is still heavily garbled. and the a's are identical to the b's and no parsing is being done. its just copying the data from one to the next to the next
    p2p closer still random.jpg
    1024 x 650 - 100K
  • HughHugh Posts: 362
    edited 2014-01-10 10:36
    Have you tried "GPS_Float" in the Obex? It has always worked for me, includes navigation calculations and is well commented and structured.
    Just a thought...
  • zlantzzlantz Posts: 136
    edited 2014-01-10 14:57
    Hugh wrote: »
    Have you tried "GPS_Float" in the Obex? It has always worked for me, includes navigation calculations and is well commented and structured.
    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.
  • kuronekokuroneko Posts: 3,623
    edited 2014-01-10 18:01
    zlantz wrote: »
    ... the other picture p2p rx shows what prop1 is receiving a clean data stream when i use ser.tx(pDBG, ser.rx(pSer)).
    This tells me that all data is sent in string format (char by char). The first picture indicates that you call ShowP2PBuff which prints every single character in the p2p_buff array. But - as has been mentioned before - you can't print single characters with the str method. Use something like this instead:
    repeat i from 0 to cptr-1
          ser.str(pDBG, string("p2p_buff:"))
          ser.tx(pDBG, 13)               
          dio.dec(pDBG, i)
          ser.str(pDBG, string(": "))      
    [COLOR="#FFA500"]      if p2p_buff[i] => 32{space}
            ser.tx(pDBG, p2p_buff[i])
          else
            ser.tx(pDBG, "#")
    [/COLOR]      ser.str(pDBG, string("  -  "))
          dio.dec(pDBG, p2p_buff[i])
          ser.tx(pDBG, 13)
          ser.tx(pDBG, 13)            
    
    Also in the fist picture I can see you attempt to print the B arrays elements with the str method. Forget it, the B array is a copy of the incoming string were commas are replaced with \0. Use the same approach as for ShowP2PBuff above. Only the A arrays can be printed with str as they represent the addresses.
    example string: $GPS,1,2,A,45,B<CR>
      $ is not stored in the buffer but CR currently is ([COLOR="#FFA500"]should be stored as 0[/COLOR])
    
                +0  +1  +2  +3  +4  +5  +6  +7  +8  +9 +10 +11 +12 +13 +14
      p2p_buff: "G" "P" "S"  0  "1"  0  "2"  0  "A"  0  "4" "5"  0  "B"  [COLOR="#FFA500"]0[/COLOR]
    
      copy_buffer is called (@GPSb[0] == 1000), now GPSb[] and GPSa[] are filled
    
          GPSb: "G" "P" "S"  0  "1"  0  "2"  0  "A"  0  "4" "5"  0  "B"  [COLOR="#FFA500"]0[/COLOR] (effectively a copy of p2p_buff)
                                 |       |       |       |           |
       GPSa[0]: 1004 ------------+       |       |       |           |
           [1]: 1006 --------------------+       |       |           |
           [2]: 1008 ----------------------------+       |           |
           [3]: 1010 ------------------------------------+           |
           [4]: 1013 ------------------------------------------------+
    
    
    zlantz wrote: »
    i changed longfill(buffer,20,0) to longfill(buffer,0,20) like it is suppose to be.
    So it now reads longfill(p2p_buff, 0, 20)? What's the value of the start address for this function?
Sign In or Register to comment.