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
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
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
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
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
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
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)
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)