向Arduino发送缓冲区,损坏数据

时间:2013-10-16 17:10:54

标签: serial-port arduino boost-asio

我正在使用Boost Librarys通过串口与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:aaaaaaaaa 填写OutputBuffer后的inhoud:bbbbbbbbbbaaaaaaaaaa

我的第一个问题是Outputbuffer alsow包含了什么?

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

while(1){

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

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

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

}

问题是循环在发送操作后几次挂起,并且输出缓冲区还包含bbbbbbbb,它应该用bin覆盖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端发送和接收后挂起。我认为它阻止了接收功能。任何人都可以帮我解决这些问题吗?

非常感谢提前

1 个答案:

答案 0 :(得分:0)

你的第一个问题是std :: cout如何尝试打印出你的数据: 它正在考虑一个以0结尾的字符串。但是,您的缓冲区InputBufferOutputBuffer不会以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)赋值 - &gt;这通常也会导致段错/崩溃。在你的幸运案例中,这将在OutputBuffer的第一个位置写入0。你甚至没有这里的赋值,写函数不关心0终止。

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

Upate: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) {