如何读取从arduino串行发送的数据结构?

2024-06-25 22:33:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在努力读取从Arduino Mega 2560串行发送的Python3二进制数据结构

Arduino代码:

char userInput;
bool ledState = false;

typedef struct 
{
  unsigned long  logTimeStart;
  unsigned long  frequencyOne;
  unsigned long  frequencyTwo;
  unsigned long  frequencyThree;
  unsigned long  frequencyFour;
  unsigned short int  revPowerOne;
  unsigned short int  revPowerTwo;
  unsigned short int  revPowerThree;
  unsigned short int  revPowerFour;
  unsigned short int  tempSensor; 
} SDLogger;

SDLogger dataLog;

void setup() 
{

  Serial.begin(9600);
  bitWrite(DDRB, 7, HIGH); // Set LED DDR high on port B, pin 7

  dataLog.logTimeStart = millis();
  dataLog.frequencyOne = 4000000000;       // PREDEFINED VALUES FOR TESTING
  dataLog.frequencyTwo = 4000000000;      
  dataLog.frequencyThree = 4000000000;
  dataLog.frequencyFour = 4000000000;
  dataLog.revPowerOne = 65000;             // PREDEFINED VALUES FOR TESTING
  dataLog.revPowerTwo = 65000;
  dataLog.revPowerThree = 65000;
  dataLog.revPowerFour = 65000;
  dataLog.tempSensor = 65000;

  Serial.println("<Arduino is ready>");
}

void loop() 
{
  checkForSerialMessage();
  delay(1000);
}

void checkForSerialMessage()
{
  Serial.println("checking serial...");
  if (Serial.available() > 0) 
  {
     userInput = Serial.read();

     if (userInput == 'a')
     {
      ledState = !ledState;
      bitWrite(PORTB, 7, ledState);
      Serial.println("led");    
     } 

     if (userInput == 'b')
     {
        Serial.write((byte*)&dataLog, sizeof(dataLog));
     }
  }
}

我相信结构的大小是30字节。我的目标是让Arduino间歇性地检查缓冲区中的特定字符。当接收到该字符时,Arduino会向我的python接口发送一个定义好的数据结构,然后将其解包并解码为人类可读的内容。我编写了另一个命令,用于切换Arduino的内置LED。这样做是为了理解软件之间的简单串行接口。LED开关似乎按预期工作,但不是struct命令

Python代码

from tkinter import *
from struct import *
import serial
import time

ser = serial.Serial('COM5', baudrate=9600, timeout=1)
root = Tk() # root widget, this has to be first before any other widgets.

BINARY_STRFORMAT = "LLLLLHHHHH"         # Format to match arduino struct
print(calcsize(BINARY_STRFORMAT))       # RESULT IS 30

def toggleLED():
    ser.write(b'a')
    arduinoData = ser.readline().decode('ascii')  # readline functions will read until it sees a newline \n
                                                  #  .decode('ascii')
    print(arduinoData)

def toggleSerial():
    ser.write(b'b')
    arduinoData = ser.readline()
    print(arduinoData)
    unpacked = unpack(BINARY_STRFORMAT, arduinoData)


# in tkinter, everything is a widget:
header = Label(root, text="Read data from Arduino")
led_on = Button(root, text="led on", command=toggleLED)
read_serial = Button(root, text="enable data stream", command=toggleSerial)

# showing Label widget onto screen
header.pack()
led_on.pack()
read_serial.pack()


root.mainloop()

当我运行python代码时,我可以使用我的基本tkinter GUI切换Arduino的LED。但是当我试图请求数据结构时,我得到一个结构错误:

struct.error: unpack requires a buffer of 30 bytes

我试图通读pySerial文档,看看是否可以改进串行数据的接收方式,但找不到struct引用。我无法理解如何发送/接收结构,以及如何在python中读取结构

我对软件工程和串行通信比较陌生,所以如果我需要澄清任何问题,请告诉我


Tags: ledserialrootstructarduinolongserint
1条回答
网友
1楼 · 发布于 2024-06-25 22:33:12

更新:多亏了@martineau和@Edward,我们了解到Serial.println()正在向试图发送/接收数据结构的同一端口写入数据。这种重叠干扰了python GUI解析和解码二进制结构的能力。删除Serial.println()时,python GUI收到预期的30字节结构

相关问题 更多 >