在Arduino上将int转换为两个字节

时间:2013-10-10 10:53:51

标签: c serial-port char arduino uart

我正在高频采样,需要通过UART从我的Arduino传输10位ADC值。

默认情况下,每个字符使用一个字节。因此,如果执行analogRead将产生值“612”,它将通过UART“6”作为一个字节发送,“1”作为一个字节发送,“2”作为一个字节发送,并将行终止符作为最后一个字节发送。 / p>

鉴于我的采样率被此通信截断,重要的是它尽可能高效且统一,因此我试图强制它使用两个字节来传输该数据,无论数据实际是什么(默认情况下,它将使用三个字节来传输“23”,四个字节用于传输“883”,五个字节用于传输“1001”)。

目前,我正在做这样的事情,这是我找到的最佳方式:

int a = 600; //Just an example
char high = (char)highByte(a);
char low = (char)lowByte(a);
Serial.print(high);
Serial.println(low);

目前,无论值是多少,它都使用三个字节(包括\ n)。有更有效的方法吗?

只需用

之类的东西打印即可
Serial.print(foo, BIN);

根本不起作用。它实际上每foo二进制表示的每一位使用一个字节,这是非常愚蠢的。

2 个答案:

答案 0 :(得分:8)

我可能会遗漏某些内容,但为什么不使用Serial.write(byte)

你可以使用像这样的方法:

void writeIntAsBinary(int value){
    Serial.write(lowByte(value));
    Serial.write(highByte(value));
}

您打算如何处理计算机上的数据?

答案 1 :(得分:5)

如果您通过串行线路发送二进制数据,则实际上不应该使用文本样式的换行分隔符来混淆所有内容。

另一方面,如果没有某种同步帮助,知道哪个字节是哪一个很难(另一方面)。

但是,由于您只有10位有效负载,但发送16位数据,您可以“执行UTF-8”并使用空闲位来发出“值的开始”信号。这将要求你的有效载荷只使用每个8位字节的7位,但这很好,因为7 + 7 = 14超过10.我们可以让第8位表示“这是新对的高字节字节“:

const int a = 600;
const unsigned char high = ((a >> 7) & 0x7f) | 0x80;
const unsigned char low  = (a & 0x7f);

Serial.print(high);
Serial.print(low);

在上面,传输的两个字节将是:

high == ((600 >> 7) & 0x7f) | 0x80 == 4 | 0x80 == 0x84
low  == (600 & 0x7f)               == 88       == 0x58

接收方必须反向执行上述操作:

const int value = ((high & 0x7f) << 7) | low;

这应该工作,并使用首先发送的高字节的最高有效位来表示确实是高字节。低字节永远不会设置MSB。