我编写了一个Arduino草图,它从遥控接收器读取数据,并为该通道返回0到1023之间的值。我基本上想要将这些数据(通道格式:值,例如,频道1:1023,频道2:511)发送到PC程序(我打算自己编写)。
我能想到的最有效的方法是使用两个字节的数据,前6位表示通道(2 ^ 6 = 64个可能的通道,比我需要的更多),最后10个表示值(2 ^ 10 = 1024,完美)。但是我不确定在C ++中实现它的最佳方法,或者这是否是最理想的方法。所以:
答案 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校验和很容易)。然后很容易丢弃垃圾字符并知道何时存在传输错误。