Question

I have a raspberry Pi and my environment is C#. Basically I am sending GPS (GPRMC) data across a wireless device. The Rx wireless device reads the data and strips out unnecessary info. The Tx side is sending a GPRMC message (I am using bray terminal)

$24GPRMC,123123.00,A,2753.13285,N,08232.29411,W,0.021,,011113,,,D*6D

When I use CuteCom on the RPi I get this:

\0xaa\0x02G\0xf0y\0x7fE,\0x12 \0xc6\0x00\0xa1-\0xcfU

regular (hex output box unchecked)

or this in hex (when the hex output box IS checked):

aa 02 47 f0 79 7f 45 2c   12 20 c6 00 a1 2d cf 55 

The hex is the expected message, as it has all the relevant data I need (start, id, date, lat, long, lrc, end).

I have set up my C# code to read the serial data, but cannot seem to get it to display data in that fashion.

This is what I have so far in C#:

        public static void Main ()
    {
        SerialPort serial = new SerialPort ("/dev/ttyUSB0", 115200);
        serial.Open ();


        while (true) 
        {
            string data = ReadData(serial);

            if(!string.IsNullOrEmpty(data))
            {
                Console.WriteLine(data);

            }
        }
    }

    public static string ReadData (SerialPort serial)
    {
        string rxString = "";

        rxString += serial.ReadExisting();

        return rxString;
    }

for the output I get:

?G?yE, ??-?U

I have also tried stream reader, but that doesn't work:

    public static string ReadData2 (System.IO.Stream s)
    {

        StreamReader sr = new StreamReader (s);
        DataString = sr.ReadLine ();

        return DataString;
    }

and I have also tried using Bit Converter I found in another post.

    private static string ReadData3 (SerialPort serial)
    {
        GPSrxString += serial.ReadExisting();
        string GPSrxStringhex = BitConverter.ToString(Encoding.ASCII.GetBytes(GPSrxString));

        return GPSrxString;
    }

So after all of that, I'm stuck. Where have I gone wrong. What do I need to do to get that proper/desired hex output?

EDIT: I used strings here, but I ended up finding out that strings aren't the way to go, it's unnecessary. Use an array to hold all the values and go from there. You can calculate needed numbers like UTC in the answers below.

Was it helpful?

Solution

Looks like the data is binary, but your ReadData implementation treats it as an ASCII string (hence the weird characters). Try reading in the binary data, then converting that into a string representation of the values in hex:

public static string ReadData(SerialPort serial)
{
    byte[] buffer = new byte[serial.BytesToRead];
    serial.Read(buffer, 0, buffer.Length);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < buffer.Length; i++)
        sb.AppendFormat("{0:X2} ", buffer[i]);

    return sb.ToString();
}

OTHER TIPS

To answer the second part of your question, as per comments on my first answer:

Assuming you have this data:

byte[] data = new byte[] {0xAA, 0x02, 0x47, 0xF0, 0x79, 0x7F};

We need to skip the first two bytes, then take the remaining four bytes. We also need to reverse the order of bytes before we can convert to floating point:

byte[] data2 = data.Skip(2).Take(4).Reverse().ToArray();

Now we can convert:

float val = System.BitConverter.ToSingle(data2, 0);

I've always used this type of code:

public static string ReadData (SerialPort s)
{
    string DataString = "";
    int nByte = s.BytesToRead;
    for (i=0;i<nByte;i++)
    {
        int byteTemp = s.ReadByte();
        DataString += (char)(byteTemp);
    }
    return DataString;
}

This is a direct translation from VB.Net, I'm not sure if the sintax is 100% correct.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top