Sign in to follow this  
Followers 0
iamtheky

NMEA Decoder (position report)

4 posts in this topic

#1 ·  Posted (edited)

This function decodes the NMEA position reports (e.g. type 1,2,3) from a ships AIS system and returns a 2D array with labels.

;~ nmea
#include<array.au3>
#include<file.au3>

$sData = "100NtTwP00JVkTPFit5irww@2>`<"
_ArrayDisplay(_NMEA_Position_Decoder($sData) , $sData)



Func _NMEA_Position_Decoder($sEncString)

$aAsc = StringToASCIIArray($sData)  ; any ASCII over 119 is invalid , ascii 64-87 and 88-95 are not used

for $i = 0 to ubound($aAsc) - 1
    If $aAsc[$i] < 48 Then
        msgbox(0, $aAsc[$i] , $aAsc[$i] & " asc less than 48" & @LF & chrw($aAsc[$i]) & " is not a valid char" )
        exit
    EndIF
    If $aAsc[$i] > 88 And $aAsc[$i] < 95 Then
        msgbox(0, $aAsc[$i] , $aAsc[$i] & " asc in invalid range 88-95")
        exit
    EndIF
    If $aAsc[$i] > 119 Then
        msgbox(0, $aAsc[$i] , $aAsc[$i] & " asc above 119")
        exit
    EndIF
next

;~ _ArrayDisplay($aAsc , 'ASCII values') ;check ASCII conversion
;subtract 48 from each

for $i = 0 to ubound($aAsc) - 1
    $aAsc[$i] = number($aAsc[$i] - 48)
    $aAsc[$i] = $aAsc[$i] > 40 ? $aAsc[$i] - 8 : $aAsc[$i] ; if still over 40 subtract 8
Next

;~ _ArrayDisplay($aAsc, 'armored payload') ;check armored payload

for $i = 0 to UBound($aAsc) - 1

    If $aAsc[$i] = "0" Then $aAsc[$i] = "000000"
    If $aAsc[$i] = "1" Then $aAsc[$i] = "000001"
    If $aAsc[$i] = "2" Then $aAsc[$i] = "000010"
    If $aAsc[$i] = "3" Then $aAsc[$i] = "000011"
    If $aAsc[$i] = "4" Then $aAsc[$i] = "000100"
    If $aAsc[$i] = "5" Then $aAsc[$i] = "000101"
    If $aAsc[$i] = "6" Then $aAsc[$i] = "000110"
    If $aAsc[$i] = "7" Then $aAsc[$i] = "000111"
    If $aAsc[$i] = "8" Then $aAsc[$i] = "001000"
    If $aAsc[$i] = "9" Then $aAsc[$i] = "001001"
    If $aAsc[$i] = "10" Then $aAsc[$i] = "001010"
    If $aAsc[$i] = "11" Then $aAsc[$i] = "001011"
    If $aAsc[$i] = "12" Then $aAsc[$i] = "001100"
    If $aAsc[$i] = "13" Then $aAsc[$i] = "001101"
    If $aAsc[$i] = "14" Then $aAsc[$i] = "001110"
    If $aAsc[$i] = "15" Then $aAsc[$i] = "001111"
    If $aAsc[$i] = "16" Then $aAsc[$i] = "010000"
    If $aAsc[$i] = "17" Then $aAsc[$i] = "010001"
    If $aAsc[$i] = "18" Then $aAsc[$i] = "010010"
    If $aAsc[$i] = "19" Then $aAsc[$i] = "010011"
    If $aAsc[$i] = "20" Then $aAsc[$i] = "010100"
    If $aAsc[$i] = "21" Then $aAsc[$i] = "010101"
    If $aAsc[$i] = "22" Then $aAsc[$i] = "010110"
    If $aAsc[$i] = "23" Then $aAsc[$i] = "010111"
    If $aAsc[$i] = "24" Then $aAsc[$i] = "011000"
    If $aAsc[$i] = "25" Then $aAsc[$i] = "011001"
    If $aAsc[$i] = "26" Then $aAsc[$i] = "011010"
    If $aAsc[$i] = "27" Then $aAsc[$i] = "011011"
    If $aAsc[$i] = "28" Then $aAsc[$i] = "011100"
    If $aAsc[$i] = "29" Then $aAsc[$i] = "011101"
    If $aAsc[$i] = "30" Then $aAsc[$i] = "011110"
    If $aAsc[$i] = "31" Then $aAsc[$i] = "011111"
    If $aAsc[$i] = "32" Then $aAsc[$i] = "100000"
    If $aAsc[$i] = "33" Then $aAsc[$i] = "100001"
    If $aAsc[$i] = "34" Then $aAsc[$i] = "100010"
    If $aAsc[$i] = "35" Then $aAsc[$i] = "100011"
    If $aAsc[$i] = "36" Then $aAsc[$i] = "100100"
    If $aAsc[$i] = "37" Then $aAsc[$i] = "100101"
    If $aAsc[$i] = "38" Then $aAsc[$i] = "100110"
    If $aAsc[$i] = "39" Then $aAsc[$i] = "100111"
    If $aAsc[$i] = "40" Then $aAsc[$i] = "101000"
    If $aAsc[$i] = "41" Then $aAsc[$i] = "101001"
    If $aAsc[$i] = "42" Then $aAsc[$i] = "101010"
    If $aAsc[$i] = "43" Then $aAsc[$i] = "101011"
    If $aAsc[$i] = "44" Then $aAsc[$i] = "101100"
    If $aAsc[$i] = "45" Then $aAsc[$i] = "101101"
    If $aAsc[$i] = "46" Then $aAsc[$i] = "101110"
    If $aAsc[$i] = "47" Then $aAsc[$i] = "101111"
    If $aAsc[$i] = "48" Then $aAsc[$i] = "110000"
    If $aAsc[$i] = "49" Then $aAsc[$i] = "110001"
    If $aAsc[$i] = "50" Then $aAsc[$i] = "110010"
    If $aAsc[$i] = "51" Then $aAsc[$i] = "110011"
    If $aAsc[$i] = "52" Then $aAsc[$i] = "110100"
    If $aAsc[$i] = "53" Then $aAsc[$i] = "110101"
    If $aAsc[$i] = "54" Then $aAsc[$i] = "110110"
    If $aAsc[$i] = "55" Then $aAsc[$i] = "110111"
    If $aAsc[$i] = "56" Then $aAsc[$i] = "111000"
    If $aAsc[$i] = "57" Then $aAsc[$i] = "111001"
    If $aAsc[$i] = "58" Then $aAsc[$i] = "111010"
    If $aAsc[$i] = "59" Then $aAsc[$i] = "111001"
    If $aAsc[$i] = "60" Then $aAsc[$i] = "111100"
    If $aAsc[$i] = "61" Then $aAsc[$i] = "111101"
    If $aAsc[$i] = "62" Then $aAsc[$i] = "111110"
    If $aAsc[$i] = "63" Then $aAsc[$i] = "111111"

next

;~ _ArrayDisplay($aAsc , 'bitstream') ;check bit stream

$sBitStream = _ArrayToString($aAsc , "")

$sMsgType = stringleft($sBitStream , 6)
$sRptIndicator = stringmid($sBitStream , 7 , 2)
$sMMSI = StringMid($sBitStream , 9 , 30)
$sNavStatus   = StringMid($sBitStream , 39 , 4)
$sRateOfTurn = StringMid($sBitStream , 43 , 8)
$sSpeedOverGrnd = StringMid($sBitStream , 51 , 10)
$sPositionAccuracy = StringMid($sBitStream , 61 , 1)
$slongitude = StringMid($sBitStream , 62 , 28)
$slatitude = StringMid($sBitStream , 90 , 27)
$sCourseOverGround = StringMid($sBitStream , 117 , 12)
$sHeading = StringMid($sBitStream , 129 , 9)
$sTimeStamp = StringMid($sBitStream , 138 , 6)
$sManeuverIndicator = StringMid($sBitStream , 144 , 2)
$sSpare = StringMid($sBitStream , 146 , 3) ;unused
$sRAIMflag = StringMid($sBitStream , 149 , 1)
$sRadioStatus = StringMid($sBitStream , 150 , 19) ;ending at 168 (or 28 blocks of 6)

;~ local $aBitStream[1][2] = [["message" , $sMsgType]]

local $aBitStream[16][2] = [["msg_type" , _BinaryToDec($sMsgType)] , ["Repeat Ind" , _BinaryToDec($sRptIndicator)] , ["MMSI" , _BinaryToDec($sMMSI)] , ["Nav Status" , _BinaryToDec($sNavStatus)] , ["Turn Rate" , _BinaryToDec($sRateOfTurn) / 10] , _
["Speed" , _BinaryToDec($sSpeedOverGrnd) / 10] , ["Accuracy" , _BinaryToDec($sPositionAccuracy)] , ["longitude" , $slongitude] , ["latitude" , $slatitude], ["Course" , _BinaryToDec($sCourseOverGround) / 10] , ["Heading" , _BinaryToDec($sHeading)] , ["TimeStamp" , _BinaryToDec($sTimeStamp)] , _
["Maneuver Ind" , _BinaryToDec($sManeuverIndicator)] , ["Spare" , $sSpare] , ["RAIM flag" , _BinaryToDec($sRAIMflag)] , ["Radio Status" , _BinaryToDec($sRadioStatus)]]

Return $aBitStream

EndFunc ;NMEA Position Decoder



;~ ;-------------Binary To Dec-----------------


Func _BinaryToDec($strBin)
Local $Return
Local $lngResult
Local $intIndex

    If StringRegExp($strBin,'[0-1]') then
    $lngResult = 0
    For $intIndex = StringLen($strBin) to 1 step -1
    $strDigit = StringMid($strBin, $intIndex, 1)
    Select
    case $strDigit="0"
    ; do nothing
    case $strDigit="1"
    $lngResult = $lngResult + (2 ^ (StringLen($strBin)-$intIndex))
    case else
    ; invalid binary digit, so the whole thing is invalid
    $lngResult = 0
    $intIndex = 0 ; stop the loop
    EndSelect
    Next

    $Return = $lngResult
        Return $Return
    Else
        MsgBox(0,"Error","Wrong input, try again ...")
        Return
    EndIf
EndFunc

 

Edited by iamtheky
1 person likes this

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

You could simplify and optimize the code - something like this.

for $i = 0 to UBound($aAsc) - 1

    $aAsc[$i] = StringFormat('%06i', DecToBase($aAsc[$i], 2))

    #cs
    If $aAsc[$i] = "0" Then $aAsc[$i] = "000000"
    If $aAsc[$i] = "1" Then $aAsc[$i] = "000001"
    If $aAsc[$i] = "2" Then $aAsc[$i] = "000010"
    If $aAsc[$i] = "3" Then $aAsc[$i] = "000011"
    If $aAsc[$i] = "4" Then $aAsc[$i] = "000100"
    If $aAsc[$i] = "5" Then $aAsc[$i] = "000101"
    If $aAsc[$i] = "6" Then $aAsc[$i] = "000110"
    If $aAsc[$i] = "7" Then $aAsc[$i] = "000111"
    If $aAsc[$i] = "8" Then $aAsc[$i] = "001000"
    If $aAsc[$i] = "9" Then $aAsc[$i] = "001001"
    If $aAsc[$i] = "10" Then $aAsc[$i] = "001010"
    If $aAsc[$i] = "11" Then $aAsc[$i] = "001011"
    If $aAsc[$i] = "12" Then $aAsc[$i] = "001100"
    If $aAsc[$i] = "13" Then $aAsc[$i] = "001101"
    If $aAsc[$i] = "14" Then $aAsc[$i] = "001110"
    If $aAsc[$i] = "15" Then $aAsc[$i] = "001111"
    If $aAsc[$i] = "16" Then $aAsc[$i] = "010000"
    If $aAsc[$i] = "17" Then $aAsc[$i] = "010001"
    If $aAsc[$i] = "18" Then $aAsc[$i] = "010010"
    If $aAsc[$i] = "19" Then $aAsc[$i] = "010011"
    If $aAsc[$i] = "20" Then $aAsc[$i] = "010100"
    If $aAsc[$i] = "21" Then $aAsc[$i] = "010101"
    If $aAsc[$i] = "22" Then $aAsc[$i] = "010110"
    If $aAsc[$i] = "23" Then $aAsc[$i] = "010111"
    If $aAsc[$i] = "24" Then $aAsc[$i] = "011000"
    If $aAsc[$i] = "25" Then $aAsc[$i] = "011001"
    If $aAsc[$i] = "26" Then $aAsc[$i] = "011010"
    If $aAsc[$i] = "27" Then $aAsc[$i] = "011011"
    If $aAsc[$i] = "28" Then $aAsc[$i] = "011100"
    If $aAsc[$i] = "29" Then $aAsc[$i] = "011101"
    If $aAsc[$i] = "30" Then $aAsc[$i] = "011110"
    If $aAsc[$i] = "31" Then $aAsc[$i] = "011111"
    If $aAsc[$i] = "32" Then $aAsc[$i] = "100000"
    If $aAsc[$i] = "33" Then $aAsc[$i] = "100001"
    If $aAsc[$i] = "34" Then $aAsc[$i] = "100010"
    If $aAsc[$i] = "35" Then $aAsc[$i] = "100011"
    If $aAsc[$i] = "36" Then $aAsc[$i] = "100100"
    If $aAsc[$i] = "37" Then $aAsc[$i] = "100101"
    If $aAsc[$i] = "38" Then $aAsc[$i] = "100110"
    If $aAsc[$i] = "39" Then $aAsc[$i] = "100111"
    If $aAsc[$i] = "40" Then $aAsc[$i] = "101000"
    If $aAsc[$i] = "41" Then $aAsc[$i] = "101001"
    If $aAsc[$i] = "42" Then $aAsc[$i] = "101010"
    If $aAsc[$i] = "43" Then $aAsc[$i] = "101011"
    If $aAsc[$i] = "44" Then $aAsc[$i] = "101100"
    If $aAsc[$i] = "45" Then $aAsc[$i] = "101101"
    If $aAsc[$i] = "46" Then $aAsc[$i] = "101110"
    If $aAsc[$i] = "47" Then $aAsc[$i] = "101111"
    If $aAsc[$i] = "48" Then $aAsc[$i] = "110000"
    If $aAsc[$i] = "49" Then $aAsc[$i] = "110001"
    If $aAsc[$i] = "50" Then $aAsc[$i] = "110010"
    If $aAsc[$i] = "51" Then $aAsc[$i] = "110011"
    If $aAsc[$i] = "52" Then $aAsc[$i] = "110100"
    If $aAsc[$i] = "53" Then $aAsc[$i] = "110101"
    If $aAsc[$i] = "54" Then $aAsc[$i] = "110110"
    If $aAsc[$i] = "55" Then $aAsc[$i] = "110111"
    If $aAsc[$i] = "56" Then $aAsc[$i] = "111000"
    If $aAsc[$i] = "57" Then $aAsc[$i] = "111001"
    If $aAsc[$i] = "58" Then $aAsc[$i] = "111010"
    If $aAsc[$i] = "59" Then $aAsc[$i] = "111001"
    If $aAsc[$i] = "60" Then $aAsc[$i] = "111100"
    If $aAsc[$i] = "61" Then $aAsc[$i] = "111101"
    If $aAsc[$i] = "62" Then $aAsc[$i] = "111110"
    If $aAsc[$i] = "63" Then $aAsc[$i] = "111111"
    #ce
next


Obviously you need to include the missing function:

Func DecToBase($iInt, $iBase) ; for bases 2 to 9
    Local $iRem, $sRet = ''
    While $iInt > $iBase -1
        $iRem = Mod($iInt, $iBase)
        $sRet = $iRem & $sRet
        $iInt = Int(($iInt - $iRem) /$iBase)
    WEnd
    Return $iInt & $sRet
EndFunc ;==> DecToBase


I always find it interesting to see miscellaneous real world applications of encoded binary information. Thanks for sharing.

Edited by czardas
1 person likes this

Share this post


Link to post
Share on other sites

sonofabitch that would have saved many minutes of typing all that out.  


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • iamtheky
      By iamtheky
      I am participating in a DoD sponsored event this weekend to glean anomalous events from standard maritime radio traffic.  In preparation I have been tearing open the payload to make sure I understand what parts should go where.  In the next few hours I will be putting in all the If statements to make sure each field is within the expected range of values (like the radio channel being something other than A,B,1 or 2). And then later I expect I will be checking those values against relative data (like if a ship stays on  the same 12 digit latitude for any length of time without vary, or the vice and a  heading changes drastically).  Also I need to do the lat/long math, from Bin to Seconds.
      Heres a link all about AIS messages:      http://www.it-digin.com/blog/?p=20
      Here's about the encoded AIVDM sentences:  http://catb.org/gpsd/AIVDM.html
      Here is the parsing of the AIS report.  I used a JSON with known good values that also contained the payload so I could unpack that and check my work.  If you see anything that can be improved upon do it, I will post more data as I get it.
      #include<array.au3> $sPositionReport = '{"mmsi":565835000,"heading":42,"latitude":39.1834333333,"nmea":"!AIVDM,1,1,0,B,18KWlv001qrRko0FJt;1WiDN0H8b,0*2A","course":41.5,"type":1,"speed":12.1,"timestamp":"2017-01-01T11:10:044+00:00","longitude":-76.2816533333}' msgbox(0, '' , $sPositionReport) $aSplit = stringsplit(stringtrimleft(StringTrimRight($sPositionReport , 1) , 2) , ',"' , 3) local $aFrmtValue[ubound($aSplit)] local $aFrmtKey[ubound($aSplit)] local $aOut[ubound($aSplit)][2] For $i = 0 to ubound($aSplit) - 1 $aFrmtValue[$i] = stringtrimleft($aSplit[$i] , stringinstr($aSplit[$i] , ":")) $aFrmtValue[$i] = stringreplace($aFrmtValue[$i] , '"' , "") ;~ msgbox(0, '' , $aSplit[$i]) $aFrmtKey[$i] = stringleft($aSplit[$i] , stringinstr($aSplit[$i] , ":") - 2) $aOut[$i][0] = $aFrmtKey[$i] $aOut[$i][1] = $aFrmtValue[$i] Next ;~ _ArrayDisplay($aFrmtKey , "Key") ;~ _ArrayDisplay($aFrmtValue , "Value") _ArrayDisplay($aOut , "OUT") ;course [4] = 0-3599 with 3600 as a default, 3601-4095 should not be used ;heading [1] = 0-359, 511 is the default ;speed [6] = 0 - 102.2 , 1023 speed is unavailable , 1022 speed is 102.2 or higher ;AIVDM - bang is not technically required to lead off ;~ [1] = !AIVDM ;~ [2] = Number of fragments - (82 character max in the AIVDM packet) ;~ [3] = fragment number of this sentence - (shouldnt be larger than field 2) ;~ [4] = sequential message ID for multi sentence msgs ;~ [5] = radio channel code (A,B or 1,2) - IF A or B exists the msg should be AIVDM ;~ [6] = payload (88-95 are not used) ;~ [7] = number of fill bits required. data integrity checksum is the * separated suffix. ;PAYLOAD_TEST $aPayload = stringsplit($aOut[3][1] , "," , 2) _ArrayDisplay($aPayload , "Payload") ;~ $sData = "18KWlv001qrRko0FJt;1WiDN0H8b" $sData = $aPayload[5] $aAsc = StringToASCIIArray($sData) ; any ASCII over 119 is invalid , ascii 64-87 and 88-95 are not used for $i = 0 to ubound($aAsc) - 1 If $aAsc[$i] < 48 Then msgbox(0, '' , "asc less than 48") If $aAsc[$i] > 88 And $aAsc[$i] < 95 Then msgbox(0, '' , "asc in invalid range 88-95") If $aAsc[$i] > 119 Then msgbox(0, '' , "asc above 119") next _ArrayDisplay($aAsc) ;subtract 48 from each for $i = 0 to ubound($aAsc) - 1 $aAsc[$i] = number($aAsc[$i] - 48) $aAsc[$i] = $aAsc[$i] > 40 ? $aAsc[$i] - 8 : $aAsc[$i] ; if still over 40 subtract 8 Next _ArrayDisplay($aAsc) ; armored payload for $i = 0 to UBound($aAsc) - 1 If $aAsc[$i] = "0" Then $aAsc[$i] = "000000" If $aAsc[$i] = "1" Then $aAsc[$i] = "000001" If $aAsc[$i] = "8" Then $aAsc[$i] = "001000" If $aAsc[$i] = "27" Then $aAsc[$i] = "011011" If $aAsc[$i] = "39" Then $aAsc[$i] = "100111" If $aAsc[$i] = "62" Then $aAsc[$i] = "111110" If $aAsc[$i] = "57" Then $aAsc[$i] = "111001" If $aAsc[$i] = "58" Then $aAsc[$i] = "111010" If $aAsc[$i] = "51" Then $aAsc[$i] = "110011" If $aAsc[$i] = "55" Then $aAsc[$i] = "110111" If $aAsc[$i] = "34" Then $aAsc[$i] = "100010" If $aAsc[$i] = "22" Then $aAsc[$i] = "010110" If $aAsc[$i] = "26" Then $aAsc[$i] = "011010" If $aAsc[$i] = "60" Then $aAsc[$i] = "111100" If $aAsc[$i] = "11" Then $aAsc[$i] = "001011" If $aAsc[$i] = "49" Then $aAsc[$i] = "110001" If $aAsc[$i] = "20" Then $aAsc[$i] = "010100" If $aAsc[$i] = "30" Then $aAsc[$i] = "011110" If $aAsc[$i] = "24" Then $aAsc[$i] = "011000" If $aAsc[$i] = "42" Then $aAsc[$i] = "101010" If $aAsc[$i] = "52" Then $aAsc[$i] = "110100" next _ArrayDisplay($aAsc) ;bit stream $sBitStream = _ArrayToString($aAsc , "") $sMsgType = stringleft($sBitStream , 6) $sRptIndicator = stringmid($sBitStream , 7 , 2) $sMMSI = StringMid($sBitStream , 9 , 30) $sNavStatus = StringMid($sBitStream , 39 , 4) $sRateOfTurn = StringMid($sBitStream , 43 , 8) $sSpeedOverGrnd = StringMid($sBitStream , 51 , 10) $sPositionAccuracy = StringMid($sBitStream , 61 , 1) $slongitude = StringMid($sBitStream , 62 , 28) $slatitude = StringMid($sBitStream , 90 , 27) $sCourseOverGround = StringMid($sBitStream , 117 , 12) $sHeading = StringMid($sBitStream , 129 , 9) $sTimeStamp = StringMid($sBitStream , 138 , 6) $sManeuverIndicator = StringMid($sBitStream , 144 , 2) $sSpare = StringMid($sBitStream , 146 , 3) ;unused $sRAIMflag = StringMid($sBitStream , 149 , 1) $sRadioStatus = StringMid($sBitStream , 150 , 19) ;ending at 168 (or 28 blocks of 6) local $aBitStream[16] = [$sMsgType , $sRptIndicator , $sMMSI , $sNavStatus , $sRateOfTurn , $sSpeedOverGrnd , $sPositionAccuracy , $slongitude , _ $slatitude, $sCourseOverGround , $sHeading , $sTimeStamp , $sManeuverIndicator , $sSpare , $sRAIMflag , $sRadioStatus] _ArrayDisplay($aBitStream) ;checking my work msgbox(0, 'MMSI_CHECK' , "Payload: " & _BinaryToDec($sMMSI) & @LF & "JSON : " & $aOut[0][1]) msgbox(0, 'course_check' ,"Payload: " & _BinaryToDec($sCourseOverGround) / 10 & @LF & "JSON : " & $aOut[4][1]) ;------------------------------ Func _BinaryToDec($strBin) Local $Return Local $lngResult Local $intIndex If StringRegExp($strBin,'[0-1]') then $lngResult = 0 For $intIndex = StringLen($strBin) to 1 step -1 $strDigit = StringMid($strBin, $intIndex, 1) Select case $strDigit="0" ; do nothing case $strDigit="1" $lngResult = $lngResult + (2 ^ (StringLen($strBin)-$intIndex)) case else ; invalid binary digit, so the whole thing is invalid $lngResult = 0 $intIndex = 0 ; stop the loop EndSelect Next $Return = $lngResult Return $Return Else MsgBox(0,"Error","Wrong input, try again ...") Return EndIf EndFunc