anixon Posted August 1, 2011 Posted August 1, 2011 Calculating the checksum is the representation of two hexadecimal characters of an XOR of all characters in the sentence between – but not including – the $ and the * character. Lets assume the following NMEA sentence: $GPGLL,5300.97914,N,00259.98174,E,125926,A*28 In this sentence the checksum is the character representation of the hexadecimal value 28. The string that the checksum is calculated over is GPGLL,5300.97914,N,00259.98174,E,125926,A To calculate the checksum you parse all characters between $ and * from the NMEA sentence into a new string. In the examples below the name of this new string is stringToCalculateTheChecksumOver. Then just XOR the first character with the next character, until the end of the string. Below you find a code example in Java script, VB.Net and C#. In Java script: var checksum = 0; <br style="margin: 0px; padding: 0px; line-height: 1.4em; font-size: 9px;">for(var i = 0; i < stringToCalculateTheChecksumOver.length; i++) { <br style="margin: 0px; padding: 0px; line-height: 1.4em; font-size: 9px;"> checksum = checksum ^ stringToCalculateTheChecksumOver.charCodeAt(i); <br style="margin: 0px; padding: 0px; line-height: 1.4em; font-size: 9px;">} In C#: int checksum = 0; <br style="margin: 0px; padding: 0px; line-height: 1.4em; font-size: 9px;">for (inti = 0; i < stringToCalculateTheChecksumOver.length; i++){ <br style="margin: 0px; padding: 0px; line-height: 1.4em; font-size: 9px;">checksum ^= Convert.ToByte(sentence);} In VB.Net: Dim checksum as Integer = 0 <br style="margin: 0px; padding: 0px; line-height: 1.4em; font-size: 9px;">For Each Character As Char In stringToCalculateTheChecksumOver <br style="margin: 0px; padding: 0px; line-height: 1.4em; font-size: 9px;"> checksum = checksum Xor Convert.ToByte(Character) <br style="margin: 0px; padding: 0px; line-height: 1.4em; font-size: 9px;">Next What is left is to transform the checksum into two hexadecimal characters, and that is it. In VB.Net and C# you can use the ToString function for this, e.g. strChecksum=checksum.ToString(“X2”). Can this calculator be coded in AutoIT and is their an example available? Replies are always appreciated Ant.. )
hannes08 Posted August 1, 2011 Posted August 1, 2011 Hi anxion, sure this can be done. You might want to take a look at Binary(), BitXOR() and StrinSplit() functions. Regards,Hannes[spoiler]If you can't convince them, confuse them![/spoiler]
anixon Posted August 1, 2011 Author Posted August 1, 2011 (edited) Hi anxion,sure this can be done.You might want to take a look at Binary(), BitXOR() and StrinSplit() functions.The Visual basic code converts the character to bytes how is that achieved in AutoIT? Edited August 2, 2011 by anixon
anixon Posted August 2, 2011 Author Posted August 2, 2011 I'm struggling with this one. Based on the NMEA checksum calculator method can anyone confirm that this code produces the correct checksum 'x38' for the string 'a9' $value1 = "a" and $value2 = 9. I have yet to write the loop to xor all the values that would normall make up a string. What this calculates is the checksum on the assumption that their are only two chrs in the string. $value1 = "a" $value2 = 9 Msgbox(0,"",BitXOR(asc($value1), asc($value2))) Msgbox(0,"",StringToBinary(BitXOR(asc($value1), asc($value2)),1)) Help is always appreciated Ant..
whim Posted August 2, 2011 Posted August 2, 2011 Hi Ant, This worked for me (as in: gives the answer you specified) Global $input = "GPGLL,5300.97914,N,00259.98174,E,125926,A" Global $result = NMEA_Checksum($input) MsgBox(0, "NMEA Checksummmer", " input: " & $input & @CR & "output: " & $result) Func NMEA_Checksum($string) Local $ret = 0 For $i = 1 To StringLen($string) $ret = BitXOR($ret, Asc(StringMid($string, $i, 1)) ) Next Return Hex($ret, 2) EndFunc Not knowing WTF an 'NMEA checksum' is, I obviously can't be sure, so over to you ... have fun, whim
anixon Posted August 2, 2011 Author Posted August 2, 2011 (edited) Hi Ant, This worked for me (as in: gives the answer you specified) Global $input = "GPGLL,5300.97914,N,00259.98174,E,125926,A" Global $result = NMEA_Checksum($input) MsgBox(0, "NMEA Checksummmer", " input: " & $input & @CR & "output: " & $result) Func NMEA_Checksum($string) Local $ret = 0 For $i = 1 To StringLen($string) $ret = BitXOR($ret, Asc(StringMid($string, $i, 1)) ) Next Return Hex($ret, 2) EndFunc Not knowing WTF an 'NMEA checksum' is, I obviously can't be sure, so over to you ... have fun, whim Thanks whim that works on the example. I will check it further to make sure that it works on all NMEA sentence types. I would like to confirm that your help is very much appreciated. WTF is a NMEA sentence? Well the short answer is its the standard protocol used by a GPS receiver to create a sentence from data streamed from a GPS Satellite. The checksum is calculated and added to each sentence and is used to confirm that the data contained within each sentence has not been corrupted. Thanks again Ant.. I have tested the code on the following NMEA sentences and it works perfectly ;$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47 ;$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39 ;$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A ;$GPGLL,4916.45,N,12311.12,W,225444,A,*1D Cheers Ant.. Edited August 2, 2011 by anixon
smartee Posted August 2, 2011 Posted August 2, 2011 hi anixon,Try this, a standardized version with documentation that handles NMEA sentences and verifies/calculates checksums according to NMEA specifications NMEAUDFv1.0.zipIf you find any bugs, or would like anything added tell me! Hope this helps,-smartee
anixon Posted August 2, 2011 Author Posted August 2, 2011 hi anixon,Try this, a standardized version with documentation that handles NMEA sentences and verifies/calculates checksums according to NMEA specifications NMEAUDFv1.0.zipIf you find any bugs, or would like anything added tell me! Hope this helps,-smarteeHappy to test your code if you post it here rather than a download. Ant:)
smartee Posted August 2, 2011 Posted August 2, 2011 Ok, I always found a download more convenient Zip has examples and helpfile, here's the bare functionexpandcollapse popup; #FUNCTION# ==================================================================================================================== ; Name...........: _NMEAChecksum ; Description ...: Takes a NMEA sentence, and returns its validity, or calculates its checksum. ; Syntax.........: _NMEAChecksum($sData [, $iVerify = Default]) ; Parameters ....: $sData - The NMEA sentence ; $iVerify - [optional] Numeric value that defines the function's behaviour as follows: ; |0 - Calculate checksum. ; |1 - Verify the sentence's validity by comparing the calculated and embedded checksums. ; Return values .: Success - The sentence's checksum, or True, depending on the value of $iVerify. ; Failure - False, Sets @Error: ; |0 - No error. ; |1 - Invalid input. ; |2 - Verify mode specified for data containing no embedded checksum. ; Author ........: smartee ; Modified.......: ; Remarks .......: ; Related .......: None ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func _NMEAChecksum($sData, $iVerify = Default) Local $vChecksum = 0 If $iVerify = Default Then $iVerify = 0 Local $avData = StringRegExp($sData, "^\$([^\*]*)(?:\*(\w{2}))?(?:\r\n)?$", 1) If @error Then Return SetError(1, 0, False) If $iVerify And UBound($avData) < 2 Then Return SetError(2, 0, False) For $i = 1 To StringLen($avData[0]) If $i = 1 Then $vChecksum = Binary(StringMid($avData[0], $i, 1)) Else $vChecksum = BitXOR($vChecksum, Binary(StringMid($avData[0], $i, 1))) EndIf Next $vChecksum = Hex($vChecksum, 2) If $iVerify Then Return SetError(Number(Not ($vChecksum = $avData[1])), 0, $vChecksum = $avData[1]) Return SetError(0, 0, $vChecksum) EndFunc ;==>_NMEAChecksum
anixon Posted August 2, 2011 Author Posted August 2, 2011 Ok, I always found a download more convenient Zip has examples and helpfile, here's the bare functionexpandcollapse popup; #FUNCTION# ==================================================================================================================== ; Name...........: _NMEAChecksum ; Description ...: Takes a NMEA sentence, and returns its validity, or calculates its checksum. ; Syntax.........: _NMEAChecksum($sData [, $iVerify = Default]) ; Parameters ....: $sData - The NMEA sentence ; $iVerify - [optional] Numeric value that defines the function's behaviour as follows: ; |0 - Calculate checksum. ; |1 - Verify the sentence's validity by comparing the calculated and embedded checksums. ; Return values .: Success - The sentence's checksum, or True, depending on the value of $iVerify. ; Failure - False, Sets @Error: ; |0 - No error. ; |1 - Invalid input. ; |2 - Verify mode specified for data containing no embedded checksum. ; Author ........: smartee ; Modified.......: ; Remarks .......: ; Related .......: None ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func _NMEAChecksum($sData, $iVerify = Default) Local $vChecksum = 0 If $iVerify = Default Then $iVerify = 0 Local $avData = StringRegExp($sData, "^\$([^\*]*)(?:\*(\w{2}))?(?:\r\n)?{:content:}quot;, 1) If @error Then Return SetError(1, 0, False) If $iVerify And UBound($avData) < 2 Then Return SetError(2, 0, False) For $i = 1 To StringLen($avData[0]) If $i = 1 Then $vChecksum = Binary(StringMid($avData[0], $i, 1)) Else $vChecksum = BitXOR($vChecksum, Binary(StringMid($avData[0], $i, 1))) EndIf Next $vChecksum = Hex($vChecksum, 2) If $iVerify Then Return SetError(Number(Not ($vChecksum = $avData[1])), 0, $vChecksum = $avData[1]) Return SetError(0, 0, $vChecksum) EndFunc ;==>_NMEAChecksum Hi smartee Very nice including the elegant method you have used for stripping the $ and *.. checksum from the NMEA sentence. I probably would have approached it stringleft stringright and tested the value probably achieving the same result but to much code. What is interesting with coding is what sometimes appears to be the almost endless possibilities of achieving the same result. Cheers Ant..
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now