我有一个关于 Arduino 和 Raspberry Pi 之间串行通信的问题。事实上,我想使用 Arduino 将 2 个变量发送到 Raspberry Pi,并以不同的方式使用它们。
这是我的 Arduino 草图:
int one = 1;
int two = 2;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print(one);
Serial.print(two);
delay(3000);
这是我的 Raspberry python 脚本:
import serial
import time
ser = serial.Serial('/dev/ttyACM0', 9600)
time.sleep(4)
while True:
data=ser.read()
print data
问题是 python 代码中的“数据”采用 Arduino 发送的两个值(因为 Arduino loop() 中有两个打印)。但我想用两个不同的变量接收 Raspberry Pi 中的数据(之后记录它们)。我尝试了很多技术以两种不同的方式接收这些数据,但它不起作用。
感谢您的帮助。
请您参考如下方法:
Arduino 的 Serial.print以 ASCII 格式发送数据。 因此,您从 Arduino 发出的命令实际上发送了字符串 12。 Python 无法看到第一个值在哪里结束以及第二个值在哪里开始。
一种解决方案是使用 Serial.println而不是 Serial.print。 这将在每次调用后添加一个回车符和一个换行符。 所以字符串将变为 1\r\n2\r\n。
然后在 Python 端,您可以使用 split 方法。 IPython 中的示例:
In [1]: recv = "1\r\n2\r\n"
In [2]: recv.split()
Out[2]: ['1', '2']
然后您可以轻松地将这些值转换为整数。
In [3]: [int(j) for j in recv.split()]
Out[3]: [1, 2]
注意:Python 有可能得到不完整的信息!因此,您可能会在第一次阅读时收到字符串 1,而在第二次阅读时收到 2!因此,您可能需要考虑格式化您的数据,以便您知道您收到了完整的消息。
实现此目的的一种选择是将您的数据格式化为 JSON。在您的示例中,这将是 {"one": 1, "two": 2}。在这个简单的例子中,您可以检查是否收到了完整的消息,因为它以 { 开头并以 } 结尾。但您也可以使用 Python 的内置 JSON 解析器。
In [4]: data = {'one': 1, 'two': 2}
In [5]: import json
In [6]: json.dumps(data)
Out[6]: '{"two": 2, "one": 1}'
In [7]: recv2 = json.dumps(data)
In [8]: json.loads(recv2)
Out[8]: {'one': 1, 'two': 2}
使用 JSON 解析器有一个优势,因为它会在您尝试解析不完整的消息时引发异常:
In [10]: recv2
Out[10]: '{"two": 2, "one": 1}'
In [11]: recv3 = '{"two": 2, "on'
In [12]: json.loads(recv3)
---------------------------------------------------------------------------
JSONDecodeError Traceback (most recent call last)
<ipython-input-12-c1774b41dafa> in <module>()
----> 1 json.loads(recv3)
/usr/local/lib/python3.5/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
317 parse_int is None and parse_float is None and
318 parse_constant is None and object_pairs_hook is None and not kw):
--> 319 return _default_decoder.decode(s)
320 if cls is None:
321 cls = JSONDecoder
/usr/local/lib/python3.5/json/decoder.py in decode(self, s, _w)
337
338 """
--> 339 obj, end = self.raw_decode(s, idx=_w(s, 0).end())
340 end = _w(s, end).end()
341 if end != len(s):
/usr/local/lib/python3.5/json/decoder.py in raw_decode(self, s, idx)
353 """
354 try:
--> 355 obj, end = self.scan_once(s, idx)
356 except StopIteration as err:
357 raise JSONDecodeError("Expecting value", s, err.value) from None
JSONDecodeError: Unterminated string starting at: line 1 column 12 (char 11)
正确的处理方式是不断从串口读取数据,并追加到字符串中,直到解析数据没有失败为止;
import serial
import json
import time
ser = serial.Serial('/dev/ttyACM0', 9600)
buffer = ''
while True:
buffer += ser.read()
try:
data = json.loads(buffer)
print(data)
buffer = ''
except json.JSONDecodeError:
time.sleep(1)
