Shop OBEX P1 Docs P2 Docs Learn Events
spin variable types and manipulation — Parallax Forums

spin variable types and manipulation

JazzDJazzD Posts: 13
edited 2008-12-25 17:59 in Propeller 1
hi, this is my first post on these forums. im quite new to the propeller also. Im not new to microcontrollers and definately not to programming. I have some knowledge in C and it is my favourite programming language. that is where my problem begins.

About one week ago i started working with the propeller and im amazed by the technology! But im not yet amazed by SPIN. I mean i always get the stuff that i want to work but i find it kind of ugly. You have the "types" and they dont really make sense to me. Im too deep into C where variable types make like 40% of the whole biz.

Okay to get down to the point. I have a problem with string manipulation, or to say it like this im not really sure if my variable is a string hehe it just doesnt make much sense to me. I interfaced an RGM-2000 GPS receiver and it works great. To parse the NMEA code i use an object from the object exchange. Search for gps or gps vga. Basically the code is short and straight forward. It does exactly what i need, well almost.

There is this part:

VAR
long GPGGAa[noparse][[/noparse]20]

that long is filled in the readNMEA function and the time is returned here

pub time
return GPGGAa[noparse][[/noparse]0]

now in my main object i call time
and print it to my screen directly using a print function

it prints out something like that:

225510.313

that means the time is 22 hours, 55 minutes and 10 seconds and some miliseconds i dont care about.

Thats great but kind of unreadable! It's almost sad to me that i have to ask for help about this. In C it would be so easy to put some ":" or whatever between the digits but i dont get the spin code. I tried to find out in the code reference and the wiki but im stuck.

Is the time saved as a number (a long) or a string there?! since i can directly print it it must be a string. but then again why GPGGAa[noparse][[/noparse]0]? that makes no sense to me.

Thanks for any help. I hope i get to understand this soon. BTW im developing a "trip computer" for cars using the propeller.

Comments

  • John AbshierJohn Abshier Posts: 1,116
    edited 2008-12-23 23:32
    Without looking at the source code but looking at the code you posted, the time is returned as a zero terminated string. I don't think that anyone has written a string library for Spin. You could do something like this (just typing off the top of my head.
    VAR
    long myTime[noparse][[/noparse]8]
    
    myTime[noparse][[/noparse]0] := GPGGAa[noparse][[/noparse]0]
    myTime[noparse][[/noparse]1]  := GPGGAa[noparse][[/noparse]1]
    myTime[noparse][[/noparse]2] := ":"
    myTime[noparse][[/noparse]3] := GPGGAa[noparse][[/noparse]2]
    ......
    myTime[noparse][[/noparse]8] := 0
    
    
    

    There is a C for the Prop ($100). I have no experience with it.

    John Abshier
  • JazzDJazzD Posts: 13
    edited 2008-12-24 13:56
    thanks for your reply but obviously that doesnt work! look at the definition i posted:

    long GPGAa[noparse][[/noparse]20] an array of 20 longs

    the time seems to be one long in that array, so the time function returns GPGAa[noparse][[/noparse]0], it returns one long value, basically a number. so now i print it using my printstr function BASICALLY now it should print only garble since its a long in terms of a number but it prints a number again, wth?! In C that simply would throw an error because a long is a number and a string is a string. You simply convert those and its done.

    So I've got one long with the value 123544.388 for example, its just a floating point value BUT this time its the time in digits. I just need a function to convert this long to a character string and then i would get the elements from that array but right now its a number :/. I need an implementation of ftoa or sprintf, that would be great
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-24 14:42
    Have you looked in the Object Exchange (obex.parallax.com/objects/category/6/)? There's an object for floating point to string conversions.
  • John AbshierJohn Abshier Posts: 1,116
    edited 2008-12-24 14:53
    We really need to see what the GPS object code is doing. 225510.313 is too many digits for the precision of a single precision floating point number. I am not sure what object you are using, but I think it is storing digits not a floating point number. The fact that it prints with printstr says that it is a string not a number. Right now I am having a brain cramp on the syntax for addressing the bytes of a long and need to leave to visit family for Christmas. But I bet that the digits are stored in the array, probably 4 to a long with a null byte terminating the data.

    John Abshier
  • kwinnkwinn Posts: 8,697
    edited 2008-12-24 14:59
    Hard to tell from the code you have posted, but I am sure that the time stored in GPGGAa[noparse][[/noparse]0] is not stored as a string. A long on the prop is 32 bits or 4 bytes, which would not hold "225510.313" as a 0 terminated string. That would require 11 bytes, so either "Time" or the print function is converting it to a text string. You need to store the returned string and insert the colons where you want them.
  • Harrison.Harrison. Posts: 484
    edited 2008-12-24 16:47
    Sounds like the GPGGAa array is an array of string pointers. In other words, GPGGAa[noparse][[/noparse]0] is the starting memory location in the HUB where a zero-terminated string lives. Whenever you do something like vga.str(GPGGAa[noparse][[/noparse]0]) you are just passing the string's memory address (which is the way it is supposed to work).

    In ANSI C it would look something like:
    #include <stdio.h>
    
    int main(void) {
            char *myStr = "225510.313";                     // test string (NMEA time)
            unsigned long GPGGAa[noparse][[/noparse]20];                       // the array of pointers (as a long to show how it 'works' in the Propeller)
    
            GPGGAa[noparse][[/noparse]0] = (unsigned long)myStr;               // store 'pointer' to the string in the first array element
    
            printf("%ul %s\n", myStr, myStr);               // print out the original string's address and string data
            printf("%ul %s\n", GPGGAa[noparse][[/noparse]0], GPGGAa[noparse][[/noparse]0]);       // print out the data using just the address stored in the array
    
            return 0;
    }
    
    



    Which prints:
    134513856 225510.313
    134513856 225510.313
    
    



    This works similarly in SPIN. The program just stores the address of the string in the first element of the long array, much like how you would do it in SPIN. Of course C has much better ways of doing it (explicit pointer types, etc), but we are forcing the char pointer to fit in a long by casting it for this example. Notice how printing both the original string and the address work the same. You can even print out the pointer address (which shows that it doesn't really know about the variable type at this point).

    To answer your question:

    John Abshier's solution is almost exactly what you need. The only difference is you need to 'dereference' the pointer one more time. That is, you need to get the actual string that is located at that pointer before you can start forming the new string.

    Something like this should work:
    VAR
      byte myTime[noparse][[/noparse]9 ]  ' 8 character long string (+ 1 zero terminator)
    
    ...
    
    myTime[noparse][[/noparse]0 ] := byte[noparse][[/noparse]GPGGAa[noparse][[/noparse]0 ]][noparse][[/noparse]0 ]
    myTime[noparse][[/noparse]1 ]  := byte[noparse][[/noparse]GPGGAa[noparse][[/noparse]0 ]][noparse][[/noparse]1 ]
    myTime[noparse][[/noparse]2 ] := ":"
    myTime[noparse][[/noparse]3 ] := byte[noparse][[/noparse]GPGGAa[noparse][[/noparse]0 ]][noparse][[/noparse]2 ]
    ...
    myTime[noparse][[/noparse]8 ] := 0
    
    

    Post Edited (Harrison.) : 12/24/2008 4:59:55 PM GMT
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-12-24 19:30
    Hello JazzD,

    consider that the whole SPIN-interpreter fits into ONLY 496 longs !!
    I wanna see that C-dialect that is small like this

    Any C on a PC just the typecasting routines will take more memory than zhe whole
    SPIN-interpreter

    If you want to have the comfort of C switch over to imagecraft C-compiler for propeller (100$)
    or a PC104-module with a 486-processor for about 400$

    OK back to SPIN.

    GPGGAa[noparse][[/noparse]0] contains the POINTER to the time

    I'm not sure but I guess the pointer points to a zero-terminated string.

    In this case you can build a new formatted string out of the original string
    For doing this take a look into the method str of FullDuplexSerial


    PUB str(stringptr)
    
    '' Send string                    
    
      repeat strsize(stringptr)
        tx(byte[noparse][[/noparse]stringptr++])
    
    
    




    you have to code something like

    
    VAR
      byte myTime [noparse][[/noparse]10]
    
    PUB FormatTime(StrPointer,GPGGAaPtr) 
    
    byte[noparse][[/noparse]StrPointer + 0 ] := byte[noparse][[/noparse]GPGGAaPtr[noparse][[/noparse]0 ]][noparse][[/noparse]0 ]
    byte[noparse][[/noparse]StrPointer + 1 ]  := byte[noparse][[/noparse]GPGGAaPtr[noparse][[/noparse]0 ]][noparse][[/noparse]1 ]
    byte[noparse][[/noparse]StrPointer + 2 ] := ":"
    byte[noparse][[/noparse]StrPointer + 3 ] := byte[noparse][[/noparse]GPGGAaPtr[noparse][[/noparse]0 ]][noparse][[/noparse]2 ]
    ...
    byte[noparse][[/noparse]StrPointer + 9 ] := 0 ' zero to terminate string
    
    'and call this function
    
    FormatTime(@myTime,GPGGAa[noparse][[/noparse]0])
    
    
    



    another suggestion:

    in the obex there is an object format wich can format strings in the printf-style

    best regards

    Stefan
  • JazzDJazzD Posts: 13
    edited 2008-12-24 21:32
    hey again, thanks for the many replies! I dont have my board handy atm so i can only thereotically try what you are saying but yea that makes sense! For you guys to have a closer look: http://obex.parallax.com/objects/225/

    that is the gps object im using. I need to have a look at that formatting object.
  • Carl HayesCarl Hayes Posts: 841
    edited 2008-12-25 17:59
    kwinn said...
    Hard to tell from the code you have posted, but I am sure that the time stored in GPGGAa[noparse][[/noparse]0] is not stored as a string. A long on the prop is 32 bits or 4 bytes, which would not hold "225510.313" as a 0 terminated string.
    True, but it is· possible to store a time-of-day in hours, minutes, seconds and milliseconds as BCD in 32 bits, as long as you don't waste any bits, as follows:

    Ten-hour digit goes from 0 to 2················· ·-- 2 bits
    One-hour digit goes from 0 to 9····················· 4
    Ten-minute digit goes from 0 to 5················· ·3
    One-minute digit goes from 0 to 9·················· 4
    Ten-second digit goes from 0 to 5················· 3
    One-second digit goes from 0 to 9················· 4
    1/10 second digit goes from 0 to 9················ 4
    1/100 second digit goes from 0 to 9··········· ····4
    1/1000 second digit goes from 0 to 9········· ····4

    Total, 32 bits.· This is not a common way of storing BCD, but it is most economical in a machine that suffers from storage poverty, and especially in one that serializes access to common memory in (a maximum of) 4-byte chunks.· Might the object have stored it that way?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    · -- Carl, nn5i@arrl.net
Sign In or Register to comment.