简体   繁体   English

串行通信:将数据从C ++发送到Arduino

[英]Serial communication: Sending data from C++ to Arduino

i'm trying to send data from a C++ program over serial communication to an Arduino. 我正在尝试通过串行通信从C ++程序向Arduino发送数据。 I formed a struct for sending the data as an object: 我形成了一个将数据作为对象发送的结构:

typedef struct
{
   double width;
   double height;
   bool passBoard;
} MachineParameters;

I'm using this Serial library: http://wjwwood.github.com/serial/ for sending the data like this: 我正在使用此串行库: http : //wjwwood.github.com/serial/用于发送数据,如下所示:

    MachineParameters mp;
    mp.width = 100;
    mp.height = 200;
    mp.passBoard = true;

    ser.write((const uint8_t *)&mp, sizeof(mp));

The library makes it possible to send the data as uint8_t , std::vector or std::string . 该库可以将数据作为uint8_tstd :: vectorstd :: string发送

The Arduino does receive data, but i don't know how to parse the data into the struct. Arduino确实接收数据,但我不知道如何将数据解析为结构。 I'm using the same struct as in the cpp code. 我正在使用与cpp代码中相同的结构。

// In Arduio

MachineParameters mp;
int byte_size = 24;

loop() {
   if(Serial.available() >= 24) {
     Serial.readBytes((char*) &mp , 24);
   } 
}

// Goal: Read received mp data just like
// mp.width or mp.height

After hours of trying, i still cannot figure it out, how to send this struct to the arduino successfully. 经过数小时的尝试,我仍然无法弄清楚如何将该结构成功发送到arduino。 Is there another way of sending this data to the arduino? 还有另一种发送此数据到arduino的方法吗? It worked sending the data as string, but that did not seem right. 它可以将数据作为字符串发送,但似乎不正确。

I am pretty new to programming with C++, so please excuse any obvious questions... 我对使用C ++编程非常陌生,所以请原谅任何明显的问题...

Thank you for helping! 感谢您的帮助!


UPDATE: Working solution below 更新:下面的工作解决方案

After a view more tries and thanks to your tips, i figured it out. 经过一番尝试,并感谢您的提示,我弄清楚了。 Here is the code, which worked for me. 这是为我工作的代码。 I found out that my problem was the wrong byte size, used for parsing the buffer. 我发现我的问题是用于解析缓冲区的字节大小错误。 The size of the struct in C++ is 12 , whereas on the arduino it's 9 . C ++中该结构的大小为12 ,而在arduino上为9 Using the original size (12) for parsing the buffer on the Arduino, the struct was parsed correctly. 使用原始大小(12)在Arduino上解析缓冲区,该结构已正确解析。

/* --- C++ CODE --- */
typedef struct
{
   double width;
   double height;
   bool passBoard;
} MachineParameters;
// sizeof(MachineParameters) returns 12.


MachineParameters mp;
mp.width = 11.1;
mp.passBoard = false;
mp.height = 22.2;

ser.write((uint8_t *)&mp, sizeof(mp));
/* --- END OF C++ --- */



/* --- Arduino Code --- */
#define   BYTE_SIZE   12
char messageBuffer[BYTE_SIZE];

typedef struct
{
   double width;
   double height;
   bool passBoard;
} MachineParameters;

MachineParameters mp;

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

void loop() {

  if (Serial.available() >= BYTE_SIZE) {
    Serial.readBytes(messageBuffer , BYTE_SIZE);
    memcpy(&mp, &messageBuffer, BYTE_SIZE);

    // mp.width returns 11.1
    // Success :)
  }
}
/* --- END OF ARDUINO --- */

on the arduino you receive the data in a buffer as raw bytes 在arduino上,您以原始字节的形式在缓冲区中接收数据

now you have to parse this, you can do this using memcpy to copy the data in the struct 现在您必须解析它,您可以使用memcpy进行操作以将数据复制到struct

however for doing this the data has to be aligned meaning that you have to know exactly where it begins. 但是,为此必须对数据进行对齐,这意味着您必须确切地知道它从哪里开始。 so you should send a synchronization byte ( start / stop bytes ) to be able to fix where the data begins 因此,您应该发送一个同步字节(开始/停止字节)以固定数据的开始位置

then you can use the code in parsing buffer data into struct : 那么您可以使用代码将缓冲区数据解析为struct

struct abc {
    char a;
    char b;
    char c;
    char d[2];
};

int main() {

    char arr[5] = { 'a', 'b', 'c', 'd', 'e' };
    struct abc sa;
    memcpy(&sa, arr, 5);


    return 0;
}

here arr is incoming buffer, and with memcpy all the contents are copied appropriately. 这里arr是传入缓冲区,并且使用memcpy适当地复制了所有内容。

ser.write((const uint8_t *)&mp, sizeof(mp)); is correct 是正确的

you can create an identical structure mp_arduino on the arduino and copy the content of the receive buffer into this structure with 您可以在arduino上创建相同的结构mp_arduino ,然后使用以下命令将接收缓冲区的内容复制到该结构中:

memcpy ( &mp_arduino, receive_buffer+n, sizeof(mp_arduino) ); where n indicates the position / byte in receive_buffer where your data begins and receive_buffer is defined as uint8_t receive_buffer[] ( or uint8_t* receive_buffer is the same... ) 其中n表示在位置/字节receive_buffer您的数据开始,并且receive_buffer被定义为uint8_t receive_buffer[]uint8_t* receive_buffer是相同的...)

( http://www.cplusplus.com/reference/cstring/memcpy/ ) http://www.cplusplus.com/reference/cstring/memcpy/

this is how a struct is stored in memory : How is a struct stored in memory? 这是将struct存储在内存中的方式: 如何将结构存储在内存中?

on both systems a float should be 32 bit https://www.arduino.cc/reference/en/language/variables/data-types/float/ 在两个系统上,浮点数都应为32位https://www.arduino.cc/reference/en/language/variables/data-types/float/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM