python - 在 Python 中通过串行方式将 JSON 发送到 Arduino

标签 python c++ json arduino pyserial

我一直在尝试设置此示例代码段以通过 Serial 与 Python 进行通信。我打算发送一个简单的 JSON 数据包,并在另一端使用 Arduino 对其进行反序列化。

但是 JSON 库取自 here抛出无效输入错误。

#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 发送 block 时,它似乎无法识别输入。

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

如您所见,尺寸在“就绪...”之后打印了两次,并且从 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 - 在 Python 中通过串行方式将 JSON 发送到 Arduino,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55698070/

相关文章:

python - 行级操作有时仅在 Numpy 中有效

python - 在 x、y 和 z 中具有不同间隔的定期采样 3D 数据的快速插值

python - 使用多个预测变量的逻辑回归

C++ 错误 "invalid constructor; your probably meant ' 帐户(常量帐户&)

c# - 如何在c sharp中循环json对象内部的json对象

javascript - 根据 CSA 法规迁移 Stripe checkout

C++ dynamic_cast 异常

c++ - 尝试在 Win32 OpenGL 中使用着色器,但顶点着色器不绘制任何内容

java - 生成的 JSON 中缺少 JPA 实体属性名称

mysql - 为什么带有 LIKE% 或 %LIKE 的 JSON_EXTRACT 通配符在 MySQL 数据库中不起作用?