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.

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

JeffDonovan Jun 1, 2016 12: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 08:46 AM

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 09:05 AM

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 09:08 AM

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 11:04 AM

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 01: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 02: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)```