问题
I want to send some serial values to my PC.
Arduino with sensors (master) >> via Bluetooth >> Arduino (slave) >> via serial com port >> PC with C# app
Serial transmission works well from master to slave, but how can I receive and convert the values received to floats on the PC side using C#?
Slave code is:
Struct definition
typedef struct {
char bt1;
float bt2;
float bt3;
float bt4;
float bt5;
float bt6;
float bt7;
char bt8;
} PayloadBT;
PayloadBT payloadBT;
Struct sent to pc
BT_writeAnything(0, payloadBT);
template <class T> long int BT_writeAnything(int ee, T& valuebt)
{
Serial.write('/');
Serial.write((char *) &valuebt, sizeof(valuebt));
}
On PC app:
using System;
using System.IO.Ports;
using System.Threading;
public struct PayloadSerial
{
public char bt1;
public float bt2;
public float bt3;
public float bt4;
public float bt5;
public float bt6;
public float bt7;
public char bt8;
}
namespace ConsoleApp1
{
class Program
{
static SerialPort _serialPort;
static char rc;
public static void Main()
{
_serialPort = new SerialPort();
_serialPort.PortName = "COM7";//Set your board COM
_serialPort.BaudRate = 9600;
_serialPort.Open();
PayloadSerial payloadSerial;
while (true)
{
someText = (byte)_serialPort.ReadChar();
rc = someText;
if (rc == '/')
{
byte* p = (byte*)&payloadSerial;
int i;
for (i = 0; i < 26; i++)
{
*p++ = (byte)_serialPort.ReadChar();
}
if (payloadSerial.bt1 == '<' && payloadSerial.bt8 == '>') {
Console.WriteLine(payloadSerial.bt2);
Console.WriteLine(payloadSerial.bt3);
Console.WriteLine(payloadSerial.bt4);
Console.WriteLine(payloadSerial.bt1);
Console.WriteLine(payloadSerial.bt8);
Console.WriteLine(payloadSerial.bt5);
Console.WriteLine(payloadSerial.bt6);
Console.WriteLine(payloadSerial.bt7);
Thread.Sleep(10);
}
}
}
}
}
}
What I receive is : Error CS0214 Pointers and fixed size buffers may only be used in an unsafe context. If I declare as unsafe I receive strange values ended with E-39
4.408201E-39
5.785725E-39
7.255092E-39
# this char value is correct
W this char value is correct
5.785725E-39
5.785725E-39
7.347765E-40
I am using Visual Studio as my IDE.
回答1:
The problem probably stems from the fact that you use default SerialPort.Encoding. And it is
An Encoding object. The default is ASCIIEncoding.
That means that each byte will get its highest bit set to 0, as explained in SerialPort encoding - how do I get 8 bit ASCII?
The solution proposed there is to use
_serialPort.Encoding = System.Text.Encoding.GetEncoding(1252);
It would probably work, but I'd rather recommend you to use the ReadByte method instead as it does exactly what it says
someText = _serialPort.ReadByte();
rc = someText;
if (rc == '/')
{
byte* p = (byte*)&payloadSerial;
int i;
for (i = 0; i < 26; i++)
{
*p++ = _serialPort.ReadByte();
There may also be (additionally)
- an issue with endianness (though both x86 and arduino seem to be little-endian).
- or an issue with incompatible struct layout/padding (probably not, but still a possibility)
P.S. Also, as it has been already pointed in the comment it may be better to read all bytes into an array and create the structure from it with Reading a C/C++ data structure in C# from a byte array
来源:https://stackoverflow.com/questions/59076362/struct-received-over-com-port-from-arduino-has-incorrect-values-in-some-but-not