簡體   English   中英

通過Python將串行JSON發送到Arduino

[英]Sending JSON over serial in Python to Arduino

我一直在嘗試設置此示例代碼段,以便通過Serial與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);
}

這是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發送超過塊時,它似乎無法識別輸入。

是因為在它前面增加了'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")

並更改了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);
}

希望有人覺得這很有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM