通过串口在Arduino和PC之间传递变量的最佳方法?

时间:2015-12-05 22:48:59

标签: c++ arduino serial-port bit-manipulation

我编写了一个Arduino草图,它从遥控接收器读取数据,并为该通道返回0到1023之间的值。我基本上想要将这些数据(通道格式:值,例如,频道1:1023,频道2:511)发送到PC程序(我打算自己编写)。

我能想到的最有效的方法是使用两个字节的数据,前6位表示通道(2 ^ 6 = 64个可能的通道,比我需要的更多),最后10个表示值(2 ^ 10 = 1024,完美)。但是我不确定在C ++中实现它的最佳方法,或者这是否是最理想的方法。所以:

  1. 在C ++中制作单个字节并使用二进制数的最佳方法是什么?优选地将值存储在存储器中(即,没有布尔阵列,其中每个索引占据它自己的字节)。两个字节的数据足以满足我的需要。
  2. 这是实现我想要实现的目标的最简单/最简单/最有效/推荐的方法吗?我基本上想要在程序之间传递变量,有没有其他方法可以做到这一点?

2 个答案:

答案 0 :(得分:1)

这是针对你的。 2个问题。

OSC(OpenSoundControl)是跨不同平台和设备发送消息的便捷方式。大多数平台都存在库。

您可以使用库OSC for Arduino并为specification实施自己的解决方案,或使用适合您上下文的库。

您提到的消息可以作为/ channel / 1 / value / 1023

发送

答案 1 :(得分:1)

您可以声明打包struct来保存这两个值:

struct chan_value_t
{
  uint8_t  channel : 6;
  uint16_t value   : 10;
};

但是要将它作为两个字节发送,你需要(1)将它与一个双字节数组“联合”:

union chan_value_t
{
  struct {
    uint8_t  channel : 6;
    uint16_t value   : 10;
  };
  uint8_t bytes[2];
};

chan_value_t cv;

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

  cv.channel = 2;
  cv.value = 800;
  for (int i=0; i<sizeof(cv.bytes); i++) {
    Serial.print( cv.bytes[i], HEX );
    Serial.print( ' ' );
  }
  Serial.println();
}

void loop() {}

(嵌套在此联合中时struct是匿名的;联合具有名称。)

或者(2)将指向结构的指针强制转换为指向字节的指针:

struct chan_value_t {
  uint8_t  channel : 6;
  uint16_t value   : 10;
};

chan_value_t cv;

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

  cv.channel = 2;
  cv.value = 800;
  uint8_t *bytes = (uint8_t *) &cv; // cast &cv to a pointer to bytes
  for (int i=0; i<sizeof(cv); i++) {
    Serial.print( bytes[i], HEX );
    Serial.print( ' ' );
  }
  Serial.println();
}

void loop() {}

它们都打印字节的十六进制值:0x02和0xC8。 800是0x320,向左移位6位是0xC800。

要将此发送到PC,您可能需要从特殊字符序列开始,并以某种校验和结束(Fletcher校验和很容易)。然后很容易丢弃垃圾字符并知道何时存在传输错误。