Our full technical support staff does not monitor this forum. If you need assistance from a member of our staff, please submit your question from the Ask a Question page.


Log in or register to post/reply in the forum.

Does anyone have 3-Byte ASCII to Decimal Conversion program for Linux?


JeffDonovan Jun 1, 2016 06:22 PM

Hello,

We receive our data via the GOES satellite in the Campbell 3-Byte ASCII (TOB3) format. I need to convert this data to Decimal on a Linux system. I have the BASIC code from Appendix B. of the TX312 manual, but I cannot get that to run on my Linux server. Has anyone converted this code to a Linux friendly language that they would be willing to share?

Thank you,

Jeff Donovan


doughardy Aug 18, 2016 02:46 PM

Jeff, did you find a solution? We have been receiving data from GOES since 2003 and just now looking to make a change to conversion in Linux.

Thanks,

dhardy@geo.umass.edu


JDavis Aug 18, 2016 03:05 PM

Here is a function in VB.Net for converting a 3 byte string form a GOES transmission in our FP2 format to a floating point number. I used this in part of a Windows program, but it should compile without any problem in .NET core for Linux. You would just need to add code to read in the file and break out pieces to feed through the function.

Function PseudoToFP2(ByVal InputPseudo As String) As Single
Dim localSingle As Single
Dim localCharArray() As Char = InputPseudo.ToCharArray
Dim localByteArray(2) As Integer
Dim scaleFactor As Single

For i As Integer = 0 To 2
localByteArray(i) = Asc(localCharArray(i))
Next
localByteArray(0) = localByteArray(0) And 15
localByteArray(1) = localByteArray(1) And 63
localByteArray(2) = localByteArray(2) And 63

If localByteArray(0) * 64 + localByteArray(1) >= 1008 Then
localSingle = (localByteArray(1) - 48) * 64 + localByteArray(2) + 9000
Else
If localByteArray(0) And 8 Then
scaleFactor = -1
Else
scaleFactor = 1
End If
If localByteArray(0) And 4 Then scaleFactor *= 0.01
If localByteArray(0) And 2 Then scaleFactor *= 0.1
If localByteArray(0) And 1 Then localSingle = 4096
localSingle = (localSingle + (localByteArray(1) * 64) + localByteArray(2)) * scaleFactor
End If

Return localSingle
End Function


JDavis Aug 18, 2016 03:08 PM

In case you need it, here also is a function to handle the unsigned 18 bit Pseudo binary integers which is a common format chosen.

Function PseudoTo18(ByVal InputPseudo As String) As Integer
Dim localInt As Integer
Dim localCharArray() As Char = InputPseudo.ToCharArray
Dim localByteArray(2) As Integer

For i As Integer = 0 To 2
localByteArray(i) = Asc(localCharArray(i))
Next

localInt = ((localByteArray(0) And 63) << 12) Or ((localByteArray(1) And 63) << 6) Or ((localByteArray(2) And 63))

Return localInt
End Function


JeffDonovan Aug 18, 2016 05:04 PM

Doug,

I did not get a response until the two that came in today. I no longer need this as we chose to modify the way we send the data back. Hope the two replies that came in today will work for you. If you do use these posts to create some code, I would appreciate it if you would share your experience.

Jeff

Jdonovan@usf.edu


doughardy Aug 18, 2016 07:23 PM

Thanks Jeff and JDavis. My colleague will try and get things working better. For years my download guy was a Fortran wizard and did everything that way... but then he retired.

Doug


dmcgraw Dec 5, 2018 09:50 PM

For reference's sake, and for anyone else who came to this page via googling, we translated the example program in BASIC in the TX312 GOES satellite transmitter manual (Appendix B) into Python. You may need to remove the first 38 characters from your download string, depending on how you grab the data.

 

"""
Code to convert 3-byte ascii data into decimal.
Translated from Appendix B in the Instruction Manual
for the TX312 GOES satellite transmitter.

The variable <data> should look similar to either:
'BttCRtF@@FeCFvwGCWLNbBM^GShF@@DrUI... and lots more characters',
or 'XXXXXXXX18339011816G45+0NN210WXW00488 BttCRtF@@FeCFvwGCWLNbBM^GShF@@DrUI... and lots more characters'
where XXXXXXXX is the DCS address. """ data = # your string here
# if data contains xx characters of metadata, set data = data[xx:] num_vals = int(len(data)/3.0) for i in range(num_vals): DV = 0 SF = 1 A = ord(data[(3*i):(3*i+3)][0]) & 15 B = ord(data[(3*i):(3*i+3)][1]) & 63 C = ord(data[(3*i):(3*i+3)][2]) & 63 if ((A * 64) + B) >= 1008: DV = (B - 48) * 64 + C + 900 else: if (A & 8) > 0: SF = -1 if (A & 4) > 0: SF = SF * 0.01 if (A & 2) > 0: SF = SF * 0.1 if (A & 1) > 0: DV = 4096 DV = (DV + ((B & 63) * 64) + (C & 63)) * SF print(DV)

 


dmcgraw Jan 22, 2020 11:50 PM

Found a typo in the code above (900 should be 9000). Updated code below:

 

"""
Code to convert 3-byte ascii data into decimal.
Translated from Appendix B in the Instruction Manual
for the TX312 GOES satellite transmitter.

The variable  should look similar to either:
'BttCRtF@@FeCFvwGCWLNbBM^GShF@@DrUI... and lots more characters',
or 'XXXXXXXX18339011816G45+0NN210WXW00488 BttCRtF@@FeCFvwGCWLNbBM^GShF@@DrUI... and lots more characters'
where XXXXXXXX is the DCS address.
"""

data =  # your string here
# if data contains xx characters of metadata, set data = data[xx:]

num_vals = int(len(data)/3.0)

for i in range(num_vals):
    DV = 0
    SF = 1
    
    A = ord(data[(3*i):(3*i+3)][0]) & 15
    B = ord(data[(3*i):(3*i+3)][1]) & 63
    C = ord(data[(3*i):(3*i+3)][2]) & 63
    
    if ((A * 64) + B) >= 1008:
        DV = (B - 48) * 64 + C + 9000
    else:
        if (A & 8) > 0:
            SF = -1
        if (A & 4) > 0:
            SF = SF * 0.01
        if (A & 2) > 0:
            SF = SF * 0.1
        if (A & 1) > 0:
            DV = 4096
        DV = (DV + ((B & 63) * 64) + (C & 63)) * SF
    
    print(DV)

 

Log in or register to post/reply in the forum.