This is my first post so please let me know what to do better next time.
I am trying to send data as byte arrays over serial. I have checked several posts but none seemed to work for me. I started to make a quick console app for testing the conversions.
This is the struct I want to receive over serial port:
public struct DataStructSend
{
public UInt32 int1;
public UInt32 int2;
public UInt32 int3;
public float float1;
public float float2;
public float float3;
}
First I start with generating a dummy string that contains the byte[] of my struct for the received data.
Here is the code for generating said string:
//Just generating dummy serial data to "read"
List<byte> data = new List<byte>();
DataStructSend dataStruct = new DataStructSend();
UInt32 int1 = 1;
UInt32 int2 = 2;
UInt32 int3 = 3;
float float1 = 16524.0000003F;
float float2 = 13524.0000002F;
float float3 = 25524.0000001F;
byte[] byteLine = BitConverter.GetBytes(int1);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(int2);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(int3);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(float1);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(float2);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(float3);
data.AddRange(GetByteList(byteLine));
byte[] dataBytes = data.ToArray();
data.Add(0x0A);
Debug.WriteLine(data.Count());
for (int i = dataBytes.Count()-1; i >=0; i--)
{
Debug.Write(dataBytes[i] + " ");
}
Debug.WriteLine("");
string line = System.Text.Encoding.Default.GetString(dataBytes);
//Here we have the Serial "received data"
Debug.Write("The data is -->");
Debug.Write(line);
Debug.WriteLine("<--");
I already checked and understood the struct alignement and padding. This is my I am using uint32 for all variables (except float, but they are 4 bytes too).
Until there everything seems fine. My application returns:
Started...
1 0 0 0
2 0 0 0
3 0 0 0
0 24 129 70
0 80 83 70
0 104 199 70
25
70 199 104 0 70 83 80 0 70 129 24 0 0 0 0 3 0 0 0 2 0 0 0 1
The data is -->*unknown characters*<--
After this I convert it back to my struct:
//Remove the newline (is there when port.Readline())
line = line.Trim();
byte[] recevedBytes = Encoding.ASCII.GetBytes(line);
Debug.Write("Sent Bytes (" + dataBytes.Count() + ")\t\t\t--> ");
for (int i = dataBytes.Count() - 1; i >= 0; i--)
{
Debug.Write(dataBytes[i] + " ");
}
Debug.WriteLine("");
//Issue is here
//Printing the converted byte array, the uint32 values are the same, but not the float. they are somehow random. float2 seems to be correct
Debug.Write("Received Bytes (" + recevedBytes.Count() + ")\t\t--> ");
for (int i = recevedBytes.Count() - 1; i >= 0; i--)
{
Debug.Write(recevedBytes[i] + " ");
}
Debug.WriteLine("");
//Checking the struct is empty and has same size as received data
byte[] dataStructBytes = GetBytes(dataStruct);
dataStruct = FromBytes(recevedBytes);
//Printing the new struct
foreach (var field in typeof(DataStructSend).GetFields(BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public))
{
Debug.WriteLine("{0} = {1}", field.Name, field.GetValue(dataStruct));
}
The result shows that only the uint32 variables were identically matching:
Sent Bytes (24) --> 70 199 104 0 70 83 80 0 70 129 24 0 0 0 0 3 0 0 0 2 0 0 0 1
Received Bytes (24) --> 70 63 104 0 70 83 80 0 70 63 24 0 0 0 0 3 0 0 0 2 0 0 0 1
int1 = 1
int2 = 2
int3 = 3
float1 = 12230
float2 = 13524
float3 = 12250
What could cause the problem for this? Or does anyone has a more efficient solution of transfering a struct based data packet from an 8bit microcontroller to a 64bit word application?
Here is the full code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConverstionTest
{
class Program
{
public static List<byte> GetByteList(byte[] array)
{
List<byte> returnList = new List<byte>();
for (int i = 0; i < array.Count(); i++)
{
Debug.Write(array[i] + " ");
returnList.Add(array[i]);
}
Debug.WriteLine("");
return returnList;
}
public struct DataStructSend
{
public UInt32 int1;
public UInt32 int2;
public UInt32 int3;
public float float1;
public float float2;
public float float3;
}
public static byte[] GetBytes(DataStructSend str)
{
int size = Marshal.SizeOf(str);
byte[] arr = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(str, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
Marshal.FreeHGlobal(ptr);
return arr;
}
public static DataStructSend FromBytes(byte[] arr)
{
DataStructSend str = new DataStructSend();
int size = Marshal.SizeOf(str);
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(arr, 0, ptr, size);
str = (DataStructSend)Marshal.PtrToStructure(ptr, str.GetType());
Marshal.FreeHGlobal(ptr);
return str;
}
static void Main(string[] args)
{
Debug.WriteLine("Started...");
//Just generating dummy serial data to "read"
List<byte> data = new List<byte>();
DataStructSend dataStruct = new DataStructSend();
UInt32 int1 = 1;
UInt32 int2 = 2;
UInt32 int3 = 3;
float float1 = 16524.0000003F;
float float2 = 13524.0000002F;
float float3 = 25524.0000001F;
byte[] byteLine = BitConverter.GetBytes(int1);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(int2);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(int3);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(float1);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(float2);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(float3);
data.AddRange(GetByteList(byteLine));
byte[] dataBytes = data.ToArray();
data.Add(0x0A);
Debug.WriteLine(data.Count());
for (int i = dataBytes.Count()-1; i >=0; i--)
{
Debug.Write(dataBytes[i] + " ");
}
Debug.WriteLine("");
string line = System.Text.Encoding.Default.GetString(dataBytes);
//Here we have the Serial "received data"
Debug.Write("The data is -->");
Debug.Write(line);
Debug.WriteLine("<--");
//Remove the newline (is there when port.Readline())
line = line.Trim();
byte[] recevedBytes = Encoding.ASCII.GetBytes(line);
Debug.Write("Sent Bytes (" + dataBytes.Count() + ")\t\t\t--> ");
for (int i = dataBytes.Count() - 1; i >= 0; i--)
{
Debug.Write(dataBytes[i] + " ");
}
Debug.WriteLine("");
//Issue is here
//Printing the converted byte array, the uint32 values are the same, but not the float. they are somehow random. float2 seems to be correct
Debug.Write("Received Bytes (" + recevedBytes.Count() + ")\t\t--> ");
for (int i = recevedBytes.Count() - 1; i >= 0; i--)
{
Debug.Write(recevedBytes[i] + " ");
}
Debug.WriteLine("");
//Checking the struct is empty and has same size as received data
byte[] dataStructBytes = GetBytes(dataStruct);
dataStruct = FromBytes(recevedBytes);
//Printing the new struct
foreach (var field in typeof(DataStructSend).GetFields(BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public))
{
Debug.WriteLine("{0} = {1}", field.Name, field.GetValue(dataStruct));
}
}
}
}
System.Text.Encoding.DefaultandSystem.Text.Encoding.ASCIIare an unusual way to encode and decode abyte[]to astring. Any reason you're not usingConvert.ToBase64StringandConvert.FromBase64String?