pra*_*rat 3 c++ python json arduino pyserial
我一直在尝试设置此示例片段以通过串行方式与 Python 进行通信。我打算发送一个简单的 JSON 数据包,并在另一端使用 Arduino 对其进行反序列化。
但是从这里获取的 JSON 库会抛出无效输入的错误。
#include <ArduinoJson.h>
void setup() {
Serial.begin(115200);
while(!Serial) {
}
}
void loop() {
int size_ = 0;
char payload[256];
String string = "";
if (size_ = Serial.available()) {
for(int i =0; i < size_; i++) {
payload[i] = Serial.read();
string += payload[i];
}
const size_t capacity = 1024;
DynamicJsonDocument doc(capacity);
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.println(error.c_str());
return;
}
if(doc["operation"] == "ACK") {
Serial.println("ACK has been received");
}
else {
Serial.println("Error!");
}
}
while (!Serial.available()) {
}
delay(20);
}
Run Code Online (Sandbox Code Playgroud)
这是 python 片段。
import time
import json
import serial
import pprint
if __name__ == "__main__":
print ("Ready...")
data = {}
data["operation"] = "ACK"
ser = serial.Serial("COM3", baudrate= 115200, timeout=0.5)
data = json.dumps(data)
if ser.isOpen():
(ser.write(bytes(data, "utf-8"), ))
try:
incoming = ser.readline().decode("utf-8")
print ((incoming))
except Exception as e:
print (e)
ser.close()
else:
print ("opening error")
Run Code Online (Sandbox Code Playgroud)
由于某种原因,我不明白为什么,当 python 发送块时,它似乎无法识别输入。
是因为前面加了“b”吗?是因为使用的编码方式吗?
当我尝试{"operation":"ACK"}通过终端输入时,它可以完美识别它,并发送回成功消息。
为什么它不能通过 python 运行?[我正在使用Python 3]
[更新] 我尝试更改一些 python 代码来进行一些调试。
if __name__ == "__main__":
print ("Ready...")
data = {}
data["operation"] = "ACK"
ser = serial.Serial("COM3", baudrate= 115200, timeout=1)
data = json.dumps(data)
buf = []
if ser.isOpen():
for x in (data):
buf.append(ord(x))
ser.write(bytearray(buf))
try:
incoming = ser.readline()
for x in incoming:
print ((x))
except Exception as e:
print (e)
ser.close()
else:
print ("opening error")
Run Code Online (Sandbox Code Playgroud)
并更改 Arduino 脚本以发回收到的字符串。
#include <ArduinoJson.h>
void setup() {
Serial.begin(115200);
while(!Serial) {
}
}
void loop() {
int size_ = 0;
char payload[256];
String string = "";
while (size_ = Serial.available()) {
for(int i =0; i < size_; i++) {
payload[i] = Serial.read();
string += payload[i];
}
const size_t capacity = 1024;
DynamicJsonDocument doc(capacity);
DeserializationError error = deserializeJson(doc, payload);
if (error) {
//Serial.println(error.c_str());
Serial.print(string.length());
for (int i = 0; i < string.length() ; i++) {
Serial.write(string[i]);
}
return;
}
if(doc["operation"] == "ACK") {
Serial.println("ACK has been received");
}
else {
Serial.println("Error!");
}
}
while (!Serial.available()) {
}
delay(20);
}
Run Code Online (Sandbox Code Playgroud)
这是Python 的输出。
Ready...
50
50
240
240
123
34
111
112
101
114
97
116
105
111
110
34
58
32
34
65
67
75
34
125
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,在“ready...”之后,尺寸被打印了两次,并且有两个值 240 的字符从 Arduino 发送。我不明白为什么前面有这两个字符。
经过一段时间的找出问题所在后,发现有几个问题。
波特率太快了,我不得不将其降低到9600。
来自 python 的编码应该以 ASCII 形式发送。
将 JsonDocument 静态分配给 512 字节是有效的。
arduino JSON- Assistant有一种方法可以找出所使用的架构所需的分配。
下面的Python代码。
import time
import json
import serial
from pprint import pprint
import random
if __name__ == "__main__":
print ("Ready...")
ser = serial.Serial("COM3", baudrate= 9600,
timeout=2.5,
parity=serial.PARITY_NONE,
bytesize=serial.EIGHTBITS,
stopbits=serial.STOPBITS_ONE
)
data = {}
data["operation"] = "sequence"
data=json.dumps(data)
print (data)
if ser.isOpen():
ser.write(data.encode('ascii'))
ser.flush()
try:
incoming = ser.readline().decode("utf-8")
print (incoming)
except Exception as e:
print (e)
pass
ser.close()
else:
print ("opening error")
Run Code Online (Sandbox Code Playgroud)
Arduino代码。
#include <ArduinoJson.h>
void setup() {
Serial.begin(9600);
while(!Serial) {
}
}
void loop() {
int size_ = 0;
String payload;
while ( !Serial.available() ){}
if ( Serial.available() )
payload = Serial.readStringUntil( '\n' );
StaticJsonDocument<512> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.println(error.c_str());
return;
}
if (doc["operation"] == "sequence") {
Serial.println("{\"Success\":\"True\"}");
}
else {
Serial.println("{\"Success\":\"False\"}");
}
delay(20);
}
Run Code Online (Sandbox Code Playgroud)
希望有人觉得这很有用。