Struct received over COM port from Arduino has incorrect values in some but not all of its fields

我怕爱的太早我们不能终老 提交于 2020-01-16 11:27:28

问题


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)

  1. an issue with endianness (though both x86 and arduino seem to be little-endian).
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!