0

我正在使用 Boost 库通过串行端口与 Arduno 进行通信。我在 te PC 和 Arduino 上都做了交流课。现在,Arduino 只是接收缓冲区并回显它。

发送和接收函数如下:

void CommunicationModuleSerial::SendBuffer(char* Buffer, int Size){

    Serial.write((uint8_t*)Buffer, Size);
}

void CommunicationModuleSerial::RecieveBuffer(char *Buffer, int Size){

   for(int i=0;i <sizeof(Size); i++){
       Buffer[i] = Serial.read();
 };

并且在 Ardunio 草图中调用函数(CM 是类实例):

CommunicationModuleSerial CM;
char Input[10]; 
char Output[10];


  while(1){

   if (Serial.available() == 10) {

     CM.RecieveBuffer(Input, 10);   
     CM.SendBuffer(Output, 10);
   };

   //delay(1000);
   Serial.flush();
};

在 PC 端我使用 boost,第一个问题是当我用 a 和 b 填充缓冲区时。第二个缓冲区保存 a 和 b,但应该只保存 b。

    char InputBuffer[10];
char OutputBuffer[10];

for(unsigned int i=0; i < sizeof(InputBuffer); i++){
    InputBuffer[i] = 'a';
}

for(unsigned int i=0; i < sizeof(OutputBuffer); i++){
        OutputBuffer[i] = 'b';
}

cout << "inhoud after filling InputBuffer: " << InputBuffer << endl;
cout << "inhoud after filling OutputBuffer: " << OutputBuffer << endl;;

输出内容如下: 填充 InputBuffer 后的 inhoud: aaaaaaaaaa 填充 OutputBuffer 后的 inhoud: bbbbbbbbbbaaaaaaaaaa

我的第一个问题是Outputbuffer怎么可能包含a?

接下来是一个简单的 while 循环,其中包含一个发送和接收函数。

while(1){

    // Send buffer
    Serial.SendBuffer(InputBuffer, 10);

    // Recieve buffer       
    Serial.RecieveBuffer(OutputBuffer, 10);

    cout << "inhoud OutputBuffer: " << OutputBuffer << endl;;

}

问题是在发送操作后循环在几次后挂起,并且输出缓冲区还保存 bbbbbbbb,它应该用 a 覆盖 bin。

PC端的发送和接收操作如下:

int CommunicationModuleSerial::SendBuffer(char* Buffer, int Size){

Buffer[Size+1] = '\0';

write(*Port,buffer(Buffer, Size));


return COMMSUCCES;
}

int CommunicationModuleSerial::RecieveBuffer(char *Buffer, int Size){


read(*Port,buffer(Buffer, Size));

return COMMSUCCES;
}

谁能帮我解决这些问题?提前谢谢了。

更新:

感谢 Matthias247,我解决了一些问题。非常感谢 Matthias247。我仍然有数据损坏问题。在 Ardunio 方面,我将接收到的缓冲区发送回去。但是当我这样做时,前两个字符具有正确的值(a),但其余的则没有。当我在 Adruino 端使用不同的输出缓冲区并将其发回时,我得到了所有正确的值。

此外,在 PC 端进行了几次发送和接收后,循环似乎挂起。我认为它会阻止接收功能。谁能帮我解决这些问题?

提前谢谢了

4

1 回答 1

0

您的第一个问题是 std::cout 如何尝试打印出您的数据:它期待一个以 0 结尾的字符串。InputBuffer但是,您的缓冲区OutputBuffer不是 0 终止的。因此 std::cout 会进一步打印(直到它找到任何其他 0 或由于分段错误而崩溃)。因此,您的 b 在 a 之后打印。

如果您真的只想打印缓冲区的内容,请像他一样使用:

cout << "inhoud after filling InputBuffer: ";
for (int i = 0 ; i < sizeof(InputBuffer) ; i++) cout << InputBuffer[i] << " ";
cout << endl;

您的 while 循环中存在完全相同的问题。

而且您的 CommunicationModuleSerial::SendBuffer 还包含一个严重错误:

Buffer[Size+1] = '\0';

您正在尝试将值分配给无效的索引 (11) --> 这通常也会导致段错误/崩溃。在幸运的情况下,这会将 0 写入 OutputBuffer 的第一个位置。你甚至不在这里赋值,写函数不关心 0 终止。

或者,您可以为两个缓冲区使用 11 个字符的数组,使用最后一个字符作为 0 终止并仅发送/接收前 10 个字节(如当前)。这样直接将缓冲区分配给 cout 也可以。

更新:Arduino方面还有一些错误:

void CommunicationModuleSerial::RecieveBuffer(char *Buffer, int Size) {
for(int i=0;i <sizeof(Size); i++){
   Buffer[i] = Serial.read();
 };

在这里,您尝试读取 sizeof(int) 字节 - 因此您只读取 4 个字节(或者在 Arduino 上甚至可能是 2 个字节)而不是 10 个。i < Size这是正确的。

另外在你的while循环中:

if (Serial.available() == 10) {
 CM.RecieveBuffer(Input, 10);   
 CM.SendBuffer(Output, 10);
}

如果 PC 一次发送数据包,这将不起作用,而是永远阻塞。你应该更好地使用if (Serial.available() >= 10) {

于 2013-10-16T20:35:38.437 回答