阿杜诺的Serial.print https://www.arduino.cc/en/Serial/Print以 ASCII 形式发送数据。
所以你的 Arduino 命令实际上发送了字符串12
。
Python 无法看到第一个值在哪里结束以及第二个值在哪里开始。
一种解决方案是使用Serial.println https://www.arduino.cc/en/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]
Note:Python 可能会收到不完整的消息!所以你可能会收到字符串1
当你第一次阅读并且2
在第二次阅读时!因此,您可能需要考虑格式化数据,以便know您已收到完整的消息。
一种选择是将数据格式化为 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)