在 Python 中通过串行发送 JSON 到 Arduino
Sending JSON over serial in Python to Arduino
我一直在尝试设置此示例片段以通过串行与 Python 进行通信。我打算发送一个简单的 JSON 数据包并在另一端使用 Arduino 对其进行反序列化。
但是取自 here 的 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);
}
这是 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")
出于某种原因,我不明白为什么,当 python 发送数据块时,它似乎无法识别输入。
Is it because of the 'b' added infront of it?
Is it because of the encoding method used?
当我尝试通过终端输入 {"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")
并更改 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);
}
这是 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
如您所见,大小在 "ready..." 之后打印了两次,Arduino 发送了两个值为 240 的字符。不明白为什么前面有这两个字符
经过一段时间弄清楚问题出在哪里,有几个问题。
波特率太快,我不得不将它降低到 9600。
来自 python 的编码应该作为 ASCII 发送。
- 在 Arduino 上读取字符串直到需要 '\n'。
静态分配 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")
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);
}
希望有人觉得这有用。
我一直在尝试设置此示例片段以通过串行与 Python 进行通信。我打算发送一个简单的 JSON 数据包并在另一端使用 Arduino 对其进行反序列化。
但是取自 here 的 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);
}
这是 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")
出于某种原因,我不明白为什么,当 python 发送数据块时,它似乎无法识别输入。
Is it because of the 'b' added infront of it? Is it because of the encoding method used?
当我尝试通过终端输入 {"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")
并更改 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);
}
这是 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
如您所见,大小在 "ready..." 之后打印了两次,Arduino 发送了两个值为 240 的字符。不明白为什么前面有这两个字符
经过一段时间弄清楚问题出在哪里,有几个问题。
波特率太快,我不得不将它降低到 9600。
来自 python 的编码应该作为 ASCII 发送。
- 在 Arduino 上读取字符串直到需要 '\n'。
静态分配 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")
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);
}
希望有人觉得这有用。