Creating Checksum in PBP


Closed Thread
Results 1 to 9 of 9
  1. #1
    Join Date
    Feb 2005
    Location
    Bellevue
    Posts
    125

    Question Creating Checksum in PBP

    I have a need to create a checksum for a NMEA sentence I am creating in PBP. I am sure others have done this, but I have not - has anyone found a way to cycle through variables and compute checksum on a group?

    The situation is this:

    I have the following variables :

    Dec_lat1 var word
    Dec_lat2 var word
    Dec_latD var word
    Dec_long1 var word
    Dec_Long2 var word
    Dec_longD var word
    wpt var word
    Cksum var word - 2 characters

    --------------------------------------------

    I need to construce a '$GPWPL sentence' (waypoint), and to do this need to create a checksum on everything except the '$' and the '*' which comes before the checksum.

    Ultimately, I need to output the following to the GPS:

    serout2 Apin4, 84,[,10,13,"$GPWPL,",#Dec_lat1,".",#Dec_lat2,",#Dec_la tD,"]
    serout2 Apin4, 84,[#Dec_long1,".",#Dec_long2,",#Dec_longD,","wpt"*",# Cksum]

    It will look to the GPS like:

    $GPWPL,119.098,W,47.3456,N,TOMHOME,*34

    BUT

    Problem is, the only code I can find for this is not compatible with PBP and deals with strings..

    Public Function NMEA_Checksum(ByVal sSentence As String) As String
    Dim i&, sum&

    'The "sentence" is from position 1 (the $) to the "*"
    'The checksum calc does NOT include the $ or *

    For i = 2 To Len(sSentence) - 1
    sum = sum Xor Asc(Mid$(sSentence, i, 1))
    Next i

    NMEA_Checksum = Right$("0" & Hex$(sum), 2)

    'The returned value is a 2 character string containing the check sum value

    Thanks,

    Tom

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Deal with string is not as easy as in VB in PBP.

    2 way to deal with string. Store each character in a Array byte.
    Code:
    Myarray var byte[5]
    loop var byte
    
    Myarray[0]="h"
    Myarray[1]="e"
    Myarray[2]="l"
    Myarray[3]="l"
    Myarray[4]="o"
    
    for loop = 0 to 4
         hserout [Myarray[loop]]
    next
    here: goto here
    using the internal EEPROM
    Code:
    loop var byte
    EEPROMData var byte
    
    data @0,"hello"
    
    for loop = 0 to 4
         read loop, eepromdata
         hserout [eepromdata]
    next
    here: goto here
    there's also another way using DB in assembler but...
    Last edited by mister_e; - 1st March 2005 at 05:44.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3
    Join Date
    Feb 2005
    Location
    Bellevue
    Posts
    125


    Did you find this post helpful? Yes | No

    Exclamation RE: Checksum

    What I am most interested in is (even if I did a big loop to read all the data into an array) How would I create the checksum?

    Seems I'd have to read the data character by character - compute the checksum of the character, then add it to the total until I am done?

    sum = var byte ' my checksum handler
    NMEA_sum = var byte ' my final checksum
    myarray = byte(34)

    If I have several variables, why not just read them each in turn:

    For i = 1 to (number of characters in myarray)
    sum=myarray(i)
    - do the checksum routine, which I can't seem to translate to PBP
    *** In VB: it looks like this
    sum = sum Xor Asc(Mid$(sSentence, i, 1))
    Next i

    *** My attempt at PBP: looks like this
    NMEA_sum = (sum ^(character(i))
    Next i

    *** then the VB:

    NMEA_Checksum = Right$("0" & Hex$(sum), 2)

    *** my attempd in PBP: No idea --

    NMEA_sum=$sum (?????)

    THEN:

    NMEA_sum is the answer - a summed up value from all the characters in myarray(i)

    Of course this does not work..

    Help!
    Last edited by Tom Gonser; - 1st March 2005 at 14:38. Reason: clarity

  4. #4
    Join Date
    Feb 2005
    Location
    Bellevue
    Posts
    125


    Did you find this post helpful? Yes | No

    Question Update to GPS Checksum - I think this works, but..

    I *think* this routine generates a Checksum that can be used with NMEA/GPS. While I am not using for that exactly, I think the routine works, but I'd be interested in getting another set of eyes on it...

    The objective in Checksum is to take each character in a sentence to be transmitted - Between the "$" and the "*" in a NMEA sentence, and XOR each one in sequence, creating a 'rolling XOR' through the sentence... (I think).

    Anyway, THIS routine does that, and it generates something that looks like a checksum, and my GPS takes it, BUT.. can anyone help make this better, confirm it works, etc?

    waypoint:
    ' create checksum '************** Checksum
    WPT_array[1]="G"
    WPT_array[2]="P"
    WPT_array[3]="W"
    WPT_array[4]="P"
    WPT_array[5]="L"
    WPT_array[6]=","
    WPT_array[7]=Dec_lat1.byte0
    WPT_array[8]=Dec_lat1.byte1
    WPT_array[9]="."
    WPT_array[10]=Dec_lat2.byte0
    WPT_array[11]=Dec_lat2.byte1
    WPT_array[12]=","
    WPT_array[13]=S_byte
    WPT_array[14]=","
    WPT_array[15]=Dec_long1.byte0
    WPT_array[16]=Dec_long1.byte1
    WPT_array[17]="."
    WPT_array[18]=Dec_lat2.byte0
    WPT_array[19]=Dec_lat2.byte1
    WPT_array[20]="."
    WPT_array[21]=E_byte
    WPT_array[22]=","
    WPT_array[23]=TracID
    WPT_array[24]=","
    ' Implied * not computed
    p=0
    cksum = %00000000
    for p = 1 to 24
    cksum = cksum^(WPT_array[p])
    Next P
    serout2 AGPSout, 16572,["$GPWPL,",#Dec_lat1,".",#Dec_lat2,",",S_Byte," ,"]
    serout2 AGPSout, 16572,[#Dec_long1,".",#Dec_long2,",",E_Byte,",",#TracID," ,*",HEX Cksum,10,13]
    wp=%0
    Return

  5. #5
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Your VB program is calculating the checksum using every single
    ASCII digit. If you want to do this with your PIC, then you'll need
    to work with single ASCII digits also. At least when calculating the
    checksum.
    Code:
    X        VAR BYTE
    SUM      VAR byte
    Dec_lat1 VAR BYTE
    Dec_lat2 VAR BYTE
    C        VAR BYTE [35]
    
    ' Load array string with "$GPWPL,119.98,W,47.3456,N,TOMHOME,*"
    
    ' Note: Dec_Lat1 & Dec_Lat2 ASCII values are computed in Num_To_ASCII
    ' sub-routine. This converts individual DIGits from each byte into ASCII.
    ' Array elements to be converted to ASCII are marked with an x.
    
    C[0]="$"  :C[1]="G"  :C[2]="P"  :C[3]="W"  :C[4]="P"  :C[5]="L"
    C[6]=","  :C[7]="x"  :C[8]="x"  :C[9]="x"  :C[10]="." :C[11]="x"
    C[12]="x" :C[13]="," :C[14]="W" :C[15]="," :C[16]="4" :C[17]="7"
    C[18]="." :C[19]="3" :C[20]="4" :C[21]="5" :C[22]="6" :C[23]=","
    C[24]="N" :C[25]="," :C[26]="T" :C[27]="O" :C[28]="M" :C[29]="H"
    C[30]="O" :C[31]="M" :C[32]="E" :C[33]="," :C[34]="*"
    
    MAIN:
        SUM = 0         ' Clear SUM on entry
        GOSUB Num_To_ASCII ' Convert Lat1 & Lat2 to ASCII for calculation
        GOSUB CheckSum  ' Calculate checksum of array
        HSEROUT [STR C\35,HEX SUM,13,10] ' Now show retult
        PAUSE 2000
        GOTO Main
    
    CheckSum:
        ' 33 bytes from "G" to "," chopping off "$" & "*"
        FOR X = 1 TO 33
          SUM = (SUM ^ C[X])
        NEXT X
        RETURN
        
    Num_To_ASCII:
        Dec_lat1 = 119
        C[7] = Dec_lat1 DIG 2+"0" ' element c[7] = ASCII 1
        C[8] = Dec_lat1 DIG 1+"0" ' element c[8] = ASCII 1
        C[9] = Dec_lat1 DIG 0+"0" ' element c[9] = ASCII 9
        Dec_lat2 = 98
        C[11] = Dec_lat2 DIG 0+"0"
        C[12] = Dec_lat2 DIG 1+"0"    
        RETURN
                
        END
    This returns the same checksum values as your VB program.

    Just modify the Num_To_ASCII routine to work on whatever byte
    (or word) variables you have your longitude/latitude data in. Convert
    each digit to ASCII, and stuff them into the appropriate array element
    spaces.

    The output captured in a terminal program from the above is
    $GPWPL,119.89,W,47.3456,N,TOMHOME,*23

    A slightly modified version of your VB program outputs the same.
    Code:
    Private Sub Command1_Click()
    Dim sText As String
    Dim NMEAChecksum As String
    Dim i&, sum&
    
    sText = "$GPWPL,119.98,W,47.3456,N,TOMHOME,*"
    
    For i = 2 To Len(sText) - 1
        sum = sum Xor Asc(Mid$(sText, i, 1))
    Next i
    
    NMEAChecksum = Right$("0" & Hex$(sum), 2)
    
    Debug.Print sText & NMEAChecksum
    
    End Sub
    Last edited by Bruce; - 14th March 2005 at 01:03.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  6. #6
    Join Date
    Feb 2005
    Location
    Bellevue
    Posts
    125


    Did you find this post helpful? Yes | No

    Red face

    WOW! That is some good thinking, thanks! I did not know I needed to convert to digits before XORing.

    If I read this right, I only need to convert the #s into ASCII, which is why you marked them with X. The variable #s for a WPT sentence are:

    dec_lat1
    dec_lat2
    dec_long1
    dec_long2

    the "N,S,E,W' are ascii anyway...

    I am not sure I follow the structure of the routine tho:

    Num_To_ASCII:
    Dec_lat1 = 119
    C[7] = Dec_lat1 DIG 2+"0" ' element c[7] = ASCII 1
    C[8] = Dec_lat1 DIG 1+"0" ' element c[8] = ASCII 1
    C[9] = Dec_lat1 DIG 0+"0" ' element c[9] = ASCII 9
    Dec_lat2 = 98
    C[11] = Dec_lat2 DIG 0+"0"
    C[12] = Dec_lat2 DIG 1+"0"
    RETURN

    I see we are assinging specific digits to an array for computing the cksum from the variable Dec_Lat1.. but I don't know why there is a "+0" after the DIG X portion....

    I also assume you are assigning Dec_lat2/Declat1 a specific number because in your example there is no value for these variables. In my case, I have values, so I will be calling them out of my array...

    I think I will have to do this for Dec_lat and Dec_long too.

    Thanks!

    Tom

  7. #7
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Tom,

    I have dealt with NMEA a few times in the past.

    The checksum is optional, and you do not really need it
    (as long as your wires aren't too long and the environment isn't too "noisy")

    What the example does is pretty simple:

    -----
    Num_To_ASCII:
    Dec_lat1 = 119
    C[7] = Dec_lat1 DIG 2+"0" ' element c[7] = ASCII 1
    -----

    DIG2 of Dec_lat1 in this example is decimal 1 (or $01)
    the ASCII value for the character "1" is 31, so you need to add 30
    (which equals the the decimal value of the ASCII character "0")
    to get the ASCII value for this character

    You could also use this:
    -----
    C[7] = Dec_lat1 DIG 2+30 ' element c[7] = ASCII 1
    -----

    (hope it is not too confusing)
    Last edited by NavMicroSystems; - 14th March 2005 at 16:10.
    regards

    Ralph

    _______________________________________________
    There are only 10 types of people:
    Those who understand binary, and those who don't ...
    _______________________________________________



  8. #8
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Just look at any ASCII chart to understand what's happening.

    With PBP most people assume sending serial data goes something like this;
    Code:
    X VAR BYTE
    X = 123
    
    Main
        SEROUT2 0,16468,[DEC X]
        PAUSEUS 200
        GOTO Main
    You would assume you're sending a single byte, but PBP is first converting your three decimal digits in X into three separate ASCII characters, and sending a total of three bytes. "1" then "2" then "3". That's what the DEC modifier does.

    So your PC isn't receiving a single byte value of 123. It's receiving three separate bytes. ASCII characters 1 then 2 then 3. This is what it's using to calculate the checksum.

    Since your PC checksum program runs a cumulative checksum calculated from each separate ASCII digit, you just need to do the same with your PIC-based cheksum program before sending the final checksum result to the PC.

    Try running this with a PIC connected to your PC serial port, and see what displays in a terminal window.
    Code:
    X = 123
    
    Main
        HSEROUT [DEC X,13,10]
        HSEROUT [X,13,10]    
        PAUSEUS 2000
        GOTO Main
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  9. #9


    Did you find this post helpful? Yes | No

    Post

    Hi,

    The attached file may be of some help.

    Cheers.
    Attached Images Attached Images
    ---> picnaut

Similar Threads

  1. PBP Book
    By Bruce in forum Off Topic
    Replies: 83
    Last Post: - 4th October 2021, 12:55
  2. Checksum
    By retepsnikrep in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 24th October 2009, 04:09
  3. Calculate Byte Value Checksum in PBP Pro
    By Pedro Pinto in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 8th July 2009, 22:50
  4. Replies: 1
    Last Post: - 10th May 2006, 15:17
  5. Checksum problem!
    By atomski in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 3rd November 2004, 07:21

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts