Convert string to bytes

961 views Asked by At

I have a J1939 CAN raw string in the following format:

CAN:0B00FEE99CF002000CEF02000B00FEE81A9A9F60FFFFB8570B00FEE042522500425225000B00FEE5E0530100C89F0400

This string contains a few CAN messages that are broken up into 3 parts, for example

0B 00FEE99 CF002000CEF0200

1) PGN data length in bytes 0B

2) PGN number (3 bytes in length) 0FEE99

3) PGN data CF002000CEF0200

Currently, I am using substrings in order to parse the 3 parts but I am not getting the correct values. I am thinking that I might be making a mistake because I didn't convert the string into a byte array. This is the part of my code:

int CANStrLength = 24;
int CANIndex = CANDataIndex(rawDataElements);
int CANStrIndex = rawDataElements[CANIndex].IndexOf("CAN:");
string CANmessage = rawDataElements[CANIndex].Substring(CANStrIndex + 4).Split(',').First();
Console.WriteLine("\nIn rawDataElements[{0}]: {1}\nLength of CAN data: {2}", CANIndex, CANmessage, CANmessage.Length);

int numberOfCANMessages = CANmessage.Length / CANStrLength;
Console.WriteLine("There are {0} CAN messages", numberOfCANMessages);

List<string> CANMessages = SplitIntoParts(CANmessage, CANStrLength);
for (int i = 0; i < numberOfCANMessages; i++)
{
    int pgnDataLength = Convert.ToInt32(CANMessages[i].Substring(0, 2), 16);
    int pgnNumber = Convert.ToInt32(CANMessages[i].Substring(2, 6), 16);
    long CANData = Convert.ToInt64(CANMessages[i].Substring(8), 16);
    Console.WriteLine();
    Console.WriteLine(CANMessages[i]);

    switch (pgnNumber)
    {
        // fuel consumption */
        case 65257:
            string totalFuelUsedStr = CANMessages[i].Substring(8).Substring(8, 4);
            double totalFuelUsed = Convert.ToInt32(totalFuelUsedStr, 16) * 0.5;
            Console.WriteLine("Total Fuel Used: {0}L, {1}gal", totalFuelUsed, (int)(totalFuelUsed* 0.26));
            break;
2

There are 2 answers

0
jdweng On

You are correct that you need to convert to bytes. Your indexing is off since a byte is two nibbles. See code below

            string input = "0B00FEE99CF002000CEF02000B00FEE81A9A9F60FFFFB8570B00FEE042522500425225000B00FEE5E0530100C89F0400";
            List<byte> bytes = new List<byte>();
            for (int i = 0; i < input.Length; i += 2)
            {
                byte newByte = byte.Parse(input.Substring(i,2), System.Globalization.NumberStyles.HexNumber);
                bytes.Add(newByte);

            }
6
Jeroen van Langen On

You might want to check here to convert the hex string into a byte array: How can I convert a hex string to a byte array?

Then you should use a MemoryStream/BinaryReader. (Converting a hex string with an int saved as LSB, does not result in the same value as converting the hex directly into an integer, because then you'll parse it like MSB). See wiki on Endianness.

So Either you use a BinaryReader to convert the bytes into an int, or you could use the BitConverter.

You could try something like: (PSEUDO)

int pgnDataLength;
int pgnNumber;
long CANData;

// this function is found on the stackoverflow link above
byte[] data = StringToByteArray(hex);

using(memStream = new MemoryStream(data))
{
    var reader = new BinaryReader(memStream);

    pgnDataLength = reader.ReadInt32();
    pgnNumber = reader.ReadInt32();
    CANData = reader.ReadInt64();
}