Отправка JSON через серийник на Python в Arduino - PullRequest
0 голосов
/ 16 апреля 2019

Я пытался настроить этот образец фрагмента для связи через 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 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. Я не понимаю, почему эти два знака впереди.

1 Ответ

0 голосов
/ 18 апреля 2019

Через некоторое время выяснения, в чем проблема, возникла пара проблем.

  • Скорость передачи данных была слишком высокой, мне пришлось уменьшить ее до 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);
}

Надеюсь, кто-нибудь найдет это полезным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...