为什么我不接收字节数组中的数据?

时间:2012-04-09 20:23:12

标签: c++ pointers arduino

我是C ++的初学者,并试图为我的Arduino创建一个程序。下面的代码编译得很好,但结果与我的预期不同。

我希望在PC上收到的是:0x04,0x61,0x62,0x63。

我在电脑上收到的是:0xff 0x00 0xb1 0x00。

我试图以这样的方式最小化代码,它只能解决我遇到的问题。

byte *assembleFrame() {
  byte frame[] = { 4 , 'a' , 'b' , 'c' , 'd' };
  return frame;
}

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

void loop() {
  byte *frame = assembleFrame();
  Serial.write( frame , 4 );
  // should send 0x04 0x61 0x62 0x63, leaving out 0x64 being 5th element.
  while ( 1 ) {
  }
}

我认为它与指针有关,但无法弄明白。

供参考:

Serial.write( buf , len ) arguments:    
  buf: an array to send as a series of bytes
  len: the length of the buffer

修改 解决方案到目前为止:

int assembleFrame( byte *frame ) {
  int octetCounter = 0;
  frame[ octetCounter++ ] = 'A'; // preamble
  frame[ octetCounter++ ] = 'B'; // preamble
  frame[ octetCounter++ ] = 0;   // frame length set at end of function
  frame[ octetCounter++ ] = h;
  frame[ octetCounter++ ] = m;
  frame[ octetCounter++ ] = s;
  frame[ 2 ] = octetCounter;  // frame length

  return frame[ 2 ];
}

void loop() {
  int bytes_in_frame = assembleFrame( frame );
  Serial.write( frame, bytes_in_frame ); // assuming ptr + bytes to send
  delay( 1000 );
}

它给出了期望的结果。

3 个答案:

答案 0 :(得分:3)

+ Krister的答案很好,如果可能的话,建议你将缓冲区传递给汇编函数,我会改进它。

/* Takes in an array of bytes with at least the given size, returns
 * the number of bytes written into the frame.
 */
int assembleFrame(byte *frame, int frame_size) {
  frame[0] =  4;
  frame[1] = 'a';
  frame[2] = 'b';
  frame[3] = 'c';
  frame[4] = 'd';
  return 5; // only used five bytes in the frame
}

  /* then in loop() */
  byte frame[10];
  bytes_in_frame = assembleFrame(frame, 10);
  someDataSendingFunction(frame, bytes_in_frame); // assuming ptr + bytes to send

这样你以后就不会产生内存泄漏的可能性。

答案 1 :(得分:1)

您的assembleFrame()函数返回一个局部变量,该函数在函数返回时将超出范围。你可以这样做:

 byte* assembleFrame() {
      byte* frame = new byte[5];
      frame[0] = 4;
      frame[1] = 'a';
      frame[2] = 'b';
      frame[3] = 'c';
      frame[4] = 'd';
      return frame;
 }

注意然后应使用以下命令释放assembleFrame()返回的内存:

void loop() {
   byte* frame = assembleFrame();
   Serial.write( frame , frame[ 0 ] );
   // release the memory allocated by assembleFrame()
   delete [] frame;
   while ( 1 ) {
   }
}

答案 2 :(得分:0)

首先,正如所说的,你现在有悬垂的指针和不明确的行为。如果您要启用警告(-Wall),您将获得

  

警告:返回局部变量'frame'的地址

到目前为止,由于资源限制,Arduino嵌入并使用动态动态内存管理对嵌入式(you cannot even call new by default,hehe)感到不愉快,您可能需要使用以下灵魂:

  1. make frame static:

    char *assembleFrame() {
        static char frame[] = { 'a' , 'b' , 'c' , 'd', 0 };
        return frame;
    }
    

    原因是,如果您在assembleFrame调用后更改了代码中的数组,则此更改将保持不变。

  2. make frame const指针并返回字符串

    const char *assembleFrame() {
        const char* frame = "abcd\0";
        return frame;
    }