Forum Index
HomeZBasic Home   Forum RulesForum Rules   Forum FAQForum FAQ   MemberlistMemberlist   UsergroupsUsergroups   RSS FeedRSS Feed
Site SearchSite Search   LinksLinks   DownloadDownload   Digests and SubscriptionsDigests and Subscriptions
ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in   RegisterRegister
NMEA Checksum Code

 
Post new topic   Reply to topic    Forum Index -> ZBasic Language
Author Message
mdown



Joined: 03 Feb 2006
Posts: 62
Location: Dallas, Texas

Posted: 09 October 2006, 18:13 PM    Post subject: NMEA Checksum Code Reply with quote

The NMEA checksum is the 8-bit exclusive OR (no start or stop bits) of all characters in the sentence, including the "," delimiters, between -- but not including -- the "$" and "*" delimiters.

The hexadecimal value of the most significant and least significant 4 bits of the result are converted to two ASCII characters (0-9, A-F) for transmission. The most significant character is transmitted first.

Code:

Function NMEA_Checksum(sentence as String) As String
  Dim i as integer
  dim sum as integer
  sum=0
 
  For i = 2 To Len(trim(sentence)) - 2
    sum = sum Xor cint(Asc(Mid(sentence, i, 1)))
  Next i
 
  NMEA_Checksum = mid(cstrHex(sum),3,2)
   
End Function


This seems to be correct, am I missing anything?

-Mike
Back to top
stevech



Joined: 23 Feb 2006
Posts: 656

Posted: 09 October 2006, 18:33 PM    Post subject: Reply with quote

You might want to use a byte for the checksum since the standard specifies this. I don't think it would change your results, just the efficiency
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2493
Location: Portland, OR

Posted: 09 October 2006, 20:09 PM    Post subject: Reply with quote

The code below incorporates Steve's suggestion and additional changes.

Firstly, since sentence is passed by reference in your code that precludes calling the function with a constant string parameter. That may or may not be an important limitation.

Secondly, the upper limit of the For loop was computed as the length of the trimmed input string but the bytes being added to the checksum were being retrieved from the untrimmed input string. This would only be important if the input string had leading space characters.

Thirdly, the optional second parameter to the Asc() function can be used to eliminate the need to generate intermediate 1-byte strings.

Another issue that is not addressed is the assumption that the input string has the correct format. If the caller checks the format before calling this function then that is not an issue.
Code:
Function NMEA_Checksum(ByVal sentence as String) As String
  Dim s as String
  Dim i as Integer
  Dim sum as Byte

  s = Trim(sentence)
  sum=0
  For i = 2 To Len(s) - 2
    sum = sum Xor Asc(s, i)
  Next i
 
  NMEA_Checksum = CStrHex(sum)
End Function


As a side note, one characteristic of the Xor function is that performing the operation a second time with the same value reverses the effect of the initial operation, i.e. A Xor B Xor A equals B. The operation is commutative so the order of operations is unimportant. The upshot of this is that you needn't skip the first and last characters if you initialize the checksum to the Xor of those two characters. The inner code block would then be:

Code:
  sum = Asc("$") Xor Asc("*")  ' negate the effect of the first and last characters
  For i = 1 To Len(s)
    sum = sum Xor Asc(s, i)
  Next i
Back to top
FFMan



Joined: 09 Jan 2010
Posts: 217

Posted: 27 February 2010, 20:46 PM    Post subject: Reply with quote

I've used the code in this post to check my nmea checksum and the received checksum and the calculated one agree when the checksum does ot include letters. When it does, the received one is uppercase, the calculated on lower case - can anyone suggest a reason why ?

$GPGLL,5153.4516,N,00111.4612,W,204149.400,A,A*41
Calc=41
Mine=41
Valid

Count=51
$GPGLL,5153.4520,N,00111.4609,W,204149.600,A,A*4C
Calc=4c
Mine=4C
Bad Checksum
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 661

Posted: 27 February 2010, 21:47 PM    Post subject: Reply with quote

you are returning a STRING that has the characters "4" and "C". It is being compared to the characters "4" and "c". Since the "C" characters are not identical, the comparison is untrue.

You can convert the case of one all upper or the other to all lower, them make the comparison.

Alternatively, you can return the actual numerical value of the checksum as a byte, and compare that to the the value of the checksum in the sentence.

-Tony
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2493
Location: Portland, OR

Posted: 27 February 2010, 22:02 PM    Post subject: Reply with quote

FFMan wrote:
[T]he calculated on lower case - can anyone suggest a reason why ?
Both A-F and a-f are valid hexadecimal characters in most contexts; alphabetic case is usually a matter of preference. The function CStrHex() happens to produce lower case characters. If you need upper case, use this modified version of the checksum function:
Code:
Function NMEA_Checksum(ByVal sentence as String, ByVal upper as Boolean = True) As String
  Dim s as String
  Dim i as Integer
  Dim sum as Byte

  s = Trim(sentence)
  sum=0
  For i = 2 To Len(s) - 2
    sum = sum Xor Asc(s, i)
  Next i
 
  NMEA_Checksum = CStrHex(sum)
  If (upper) Then
    NMEA_Checksum = UCase(NMEA_Checksum)
  End If
End Function
Back to top
FFMan



Joined: 09 Jan 2010
Posts: 217

Posted: 27 February 2010, 22:52 PM    Post subject: Reply with quote

ok - i thought the print of the checksum was the actual checksum but you're saying its the value printed as hex and therefore 4c=4C naturally.

It all working now thanks
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Forum Index -> ZBasic Language Time synchro. with the server - Timezone/DST with your computer
Page 1 of 1

 


All content Copyright © 2005-2012 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group