HUNT333R Ответов: 1

Получите структуру через последовательный com порт с помощью C#


Всем привет,
Я пытаюсь отправить 1 символ и 8 переменных (26 байт) из arduino в качестве структуры через com-порт, я получаю что-то, но моя неопытность в C# не помогает,

Я использую этот код для отправки данных из arduino в приложение через com-порт. первый отправленный символ
Serial.write('/');
это значит знать когда начать читать структуру
Typedef struct {
  char 1start;
  float 2a;
  float 3a;
  float 4a;
  float 5a;
  float 6a;
  float 7a; 
  char 8end;
  } Payload;
  Payload payload; 

void setup() {
  Serial.begin(9600);

  }

void loop() {

  payload.2a=2.22;
  payload.3a=3.33;
  payload.4a=4.44;
  payload.1start='#';
  payload.8end='&';
  payload.5a=5.55;
  payload.6a=6.66;
  payload.7a=7.77;

_writeAnything(0, payload);
}

template <class T> long int _writeAnything(int ee, T& valuebt)
{
  Serial.write('/');
  Serial.write((byte *) &valuebt, sizeof(valuebt));
}


На стороне приложения c# есть проблема здесь я получаю что-то, но далеко не все, что я посылаю, я знаю, что первый отправленный символ получен
Serial.write('/');
проблема заключается в том, чтобы поместить информацию обратно в одну структуру

namespace ConsoleApp1
{
    class Program
    {
        public struct PayloadSerial
        {
            public char 1start;
            public float 2b;
            public float 3b;
            public float 4b;
            public float 5b;
            public float 6b;
            public float 7b;
            public char 8tend;
        }



        static SerialPort _serialPort;
        static char rc;
 


        public static unsafe void Main()
        {
            _serialPort = new SerialPort();
            _serialPort.PortName = "COM7";//Set your board COM
            _serialPort.BaudRate = 9600;
            _serialPort.DataBits = 8;
            _serialPort.Parity = Parity.None;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Handshake = Handshake.None;
            _serialPort.DtrEnable = true;
            _serialPort.RtsEnable = true;
            _serialPort.Open();

           
            PayloadSerial payloadSerial;
            while (true)
            {
     
                char someText = (char)_serialPort.ReadChar();
                rc = someText;
                if (rc == '/')
                {

                    byte* p = (byte*)&payloadSerial;
                         int i;
                         for (i = 0; i < 26; i++)
                         {
                             *p++ = (byte)_serialPort.ReadByte();
                         }




                    //-------------------
                    //  if (payloadSerial.1start == '#' && payloadSerial.8end == '&') {

                    Console.WriteLine(payloadSerial.2b);
                     Console.WriteLine(payloadSerial.3b);
                     Console.WriteLine(payloadSerial.4b);
                     Console.WriteLine(payloadSerial.1tstart);
                     Console.WriteLine(payloadSerial.8tend);
                     Console.WriteLine(payloadSerial.5b);
                     Console.WriteLine(payloadSerial.6b);
                     Console.WriteLine(payloadSerial.7b);
                         Console.WriteLine(" ");
                         Console.WriteLine(" ");

               
                    Thread.Sleep(50);

                 }
            }

        }

    }
}




то, что я получаю,-это значения не случайно 3.54846 E-38 ... или E-40, но они постоянны

Что я уже пробовал:

Поскольку у меня нет опыта работы в C#, я перепробовал все вещи через google, но ничего не было полезно, потому что все время я нахожу куски кода и не знаю, что включить или куда его поместить.
попробуйте изменить символ / байт
*p++ = (byte)_serialPort.ReadByte();

попробуйте изменить чтение байтов
for (i = 0; i < 26; i++)

Richard MacCutchan

Тип char в C# имеет ширину 16 бит, вы уверены, что Arduino-это то же самое?

1 Ответов

Рейтинг:
1

OriginalGriff

Первое, что следует отметить, это то, что вы не можете определить эти структуры в C, C++ или C# - имена переменных не могут начинаться с числовой цифры ни в одном из этих языков.
Поэтому вполне вероятно, что то, что вы отправляете / получаете, совсем не похоже на то, что вы ожидали, потому что этот код не будет компилироваться, и вы, вероятно, используете старые EXE-файлы.

Но... даже если вы исправите это, когда вы определяете такую структуру, как эта:

Typedef struct {
  char c1;
  float f;
  char c2;
  } Payload;
Вы не получите 6 - байтовую структуру-поплавки должны быть выровнены по границе адреса 4 байта, поэтому ваш первый символ будет "дополнен", чтобы занять 4 байта. Кроме того, конечный символ также будет дополнен границей в 4 байта, поэтому здесь показано 12 байт:
#include <stdio.h>

typedef struct {
  char c1;
  float f;
  char c2;
  } Payload;
int main()
{
    printf("%lu\n", sizeof(Payload));

    return 0;
}
Точно то же самое произойдет и с C#, по тем же причинам.

Следующая вещь, которую следует учитывать, - это "endianness" - в этом случае вы, вероятно, в порядке, потому что и ПК, и Arduino являются "little endian", что означает, что числа хранятся с наименее значимым байтом значения в самом низком байтовом адресе памяти. Но имейте в виду, что это не относится ко всем системам!


HUNT333R

Во-первых, tahnk вы очень благодарны за ответ, в моем коде переменные структуры не включают числа, я просто изменил их здесь для лучшего понимания.

В этом случае определение переменных не является проблемой.
Теперь данные отправлены, я думаю, что отправляю 26 байт данных ... Откуда мне знать ? На стороне arduino я поставил строку SerialPrint(sizeof(полезная нагрузка)) и всегда возвращаю 26
Не могли бы вы помочь мне с примером того, как читать структуру? Я нахожу только несколько примеров.