C# Receive struct over Serial Comp Port from Leonardo

Hi all,

Please help me with a complete example of C# for reading a struct,
i can receive serial information but i can not receive struct maybe someone else has a bigger experience in c# or a working example

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));
}

the C# code that i use, but with it i am not receiving correct data is

using System;
using System.Text;
using System.Data;
using System.IO.Ports;
using System.Threading;
using System.IO;


using System.Collections.Generic;
using System.ComponentModel;

using System.Drawing;
using System.Windows;


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);

                 }
            }

        }

    }
}

You can read serial information?
I have no idea what that means.

yes i can read information but i do not know how to decompile it, the information are not completely, if you look at the arduino code i am sending one character

Serial.write('/');

,

and this one i use it to receive it in C# using:

char someText = (char)_serialPort.ReadChar();

but i want to store 6 variables in one structure and send it once, additionally i had added 2 characters one at the start and one at the end in order to confirm me the values received are correct:

_writeAnything(0, payload);

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

on the c# side i try to read every character and put the information back in the structure

                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();
                         }

i do not have any experience in C# and i was thinking maybe someone else can help me because for one week i read values not randomly 3.54846E-38 ..... or E-40

I think there’s two problems at play here,

  1. You need to determine the struct struct packing on each side. Read up in both languages about byte packing and make sure they are set the same. Usually you’d set byte packing to 1 or 2 at both sides in this case.

  2. You need to determine the endianness of both sides and make sure they are set to the same. IE are multi byte words in the same byte order on each platform.

  3. You need to make sure both floating point values are actually bit compatible. Do you need to send floats. Could fix point whole and fraction values be used? Does the protocol need to be binary?

Make things easy for yourself by putting your complex struct to one side and start with a simple struct that contains a single byte with a bit pattern that will allow you to deduce the bit order. Work your way through the datatypes you are planning to use then make a 2 field struct. Gradually increase the complexity until you end up with your original 6 field struct.