Shop OBEX P1 Docs P2 Docs Learn Events
Creating Driver In Spin For LS20031 GPS Module, Driver Good But Object Testing Driver Acting Weird.. — Parallax Forums

Creating Driver In Spin For LS20031 GPS Module, Driver Good But Object Testing Driver Acting Weird..

So I'm trying to create a driver (library) object for my LS20031 GPS Module. I use Parallax_Serial_Terminal to communicate with my PC and I am using a second instance to communicate with my GPS. Those two things are good so no problems there. The problem is arising when I call methods in the driver object from the top (main) object. It goes about halfway thru the tests I set up and then things stop. Heres what I have going on so far:

Test_Object - Initial code loaded in 1st cog, loads 2nd cog with Parallax_Serial_Terminal for PC Comms, then calls a method in LS20031_MT3329_GPS_Driver (what I'm writing for my larger program) to load a 2nd instance of Parallax_Serial_Terminal to handle GPS communication in a 3rd cog, then starts calling methods in driver object for tests set up in test object.

I've gone thru the code and I can't see any problems. All I can think is a memory collision somehow that I can't see. I tried all sorts of things to try to fix it with no luck at all. But I did find a temporary fix so I could run my tests with no problem to make sure it wasn't my code. Instead of having Test_Object.spin and LS20031_MT3329_GPS_Driver.spin seperate, I copied everything in the driver object and added it at the end of the code in my Test_Object2 (renamed and calls to driver object fixed since now local) and everything ran exactly how I intended. So good for testing now but wont work as a driver if having memory issues.

I attached Test_Object which uses LS20031_MT3329_GPS_Driver and Parallax_Serial_Terminal (these are the ones having trouble).

Test_Object2 has LS20031_MT3329_GPS_Driver copied to the end of it (the one that works for now for testing purposes).

Test_Data2 is from Test_Object2 which is exactly what it should be, and Test_Data which is where the problem is showing.

Any suggestions would help greatly! Too many sleepless nights here lately trying to figure this one out...

Thanks

Comments

  • ElectrodudeElectrodude Posts: 1,657
    edited 2016-12-08 05:30
    I think the problem is in GPS.Get_Acknowledgement. You don't seem to be understanding how strings work.

    First, you do "message := GPS.CharIn". This reads a single character into the local variable "message". Once you find "$P", you break out of the loop and do "GPS.StrIn(message)". This is invalid - it treats whatever value is in "message", which is always the letter "P" at that point, as a *pointer* in memory where it should store the string, and not as an actual string. However, address $50 (ASCII "P") is part of your code, which is why it crashes.

    You need to give it somewhere to put the string. In your GPS object, try adding a VAR byte array long enough to hold the acknowledgement string to your GPS object. It can't be local, since locals aren't valid after the function returns. Pass a pointer to this variable ("@variable_name") to GPS.StrIn, and then also return this pointer.


    When you merge your two objects together and it works, you're still corrupting memory, it's just that in that case the memory you corrupt doesn't matter anymore. It's probably the assembly code for "Parallax Serial Terminal.spin" that was already loaded into the cog.
  • JamesWJamesW Posts: 3
    edited 2016-12-09 02:33
    Just got off work and read your comment Electrodude. GPS.Get_Acknowledgment is where I thought the problem was arising since the trouble always started when the Test_Object would try to display the string on the Parallax Serial Terminal running on my PC.

    You explained that pretty good for me and I can't wait to give it a shot when I get home.

    Do you think this may work:

    VAR
    Byte NMEA_Sentence [256]

    PUB Get_Acknowledgment | index

    index := 1
    REPEAT
    NMEA_Sentence [index] := GPS.CharIn
    IF NMEA_Sentence[index] == "$"
    index++
    quit
    GPS.StringIn(@NMEA_Sentence [index])
    RETURN NMEA_Sentence

    Is this what you meant for the GPS Object for the Test Object to call and receive address of sentence?
  • ElectrodudeElectrodude Posts: 1,657
    edited 2016-12-09 03:25
    That's almost correct. The index needs to start at 0, and the last line should read "return @NMEA_Sentence".

    Also, in the unlikely event that your GPS unit should decide to send a line more than 256 bytes long, it will overrun your buffer and clobber whatever came after your buffer. From the little I know of NMEA strings, this won't happen in normal operation; however, if the GPS gets disconnected and just noise comes in, 256 bytes without a newline is not unlikely. To get around this, you need to CharIn the whole string yourself until you get a newline. But you can also (possibly) just ignore the problem.

    When you post code on these forums, and most any other forum, you can wrap it in [ code]code tags[/code ] (but without the spaces inside the brackets) to preserve indentation. Below is your code inside code brackets, and with the two changes you need to make applied:
    VAR
         Byte NMEA_Sentence [256]
    
    PUB Get_Acknowledgment | index
    
      index := 0
      REPEAT
         NMEA_Sentence [index] := GPS.CharIn
         IF NMEA_Sentence[index] == "$"
           index++
           quit
       GPS.StringIn(@NMEA_Sentence [index])
       RETURN @NMEA_Sentence
    

    P. S. These stupid forums think every pointer is a username. Can it somehow be made to ignore @mentions inside of code tags?
  • JamesWJamesW Posts: 3
    edited 2016-12-09 06:04
    Well I finally got home and got to try what you mentioned. Things are now working the way I want them too. Thanks for explaining how to pass the string between objects using "RETURN" and an address pointer properly. This is what I ended up with:

    I changed/added the below code to LS20031_MT3329_GPS_Driver
    VAR
    
      byte  NMEA_String[256]
      
    
    PUB Get_Acknowledgment | index
    
      ''  Get Acknowledgment Message From GPS
      ''                           
      ''  RETURN message
    
      index := 0
      REPEAT
        NMEA_String[index] := GPS.CharIn
        IF NMEA_String[index] == "$"
          index++
          quit
      GPS.StrInMax(@NMEA_String[index], 255)       
      RETURN @NMEA_String
    
    I then changed this code in Test_Object
    PRI Display_Acknowledgment | NMEA_String
    
      NMEA_String := GPS.Get_Acknowledgment
      USB.Str(string("  GPS Response: "))
      USB.Str(NMEA_String)
      USB.Str(string(13))
      RETURN
    
    Thanks again Electrodude for the help and explaining how to do the code on the forum! I'll be sure to update my GPS driver to this discussion when I am further along and to OBEX.
Sign In or Register to comment.