簡體   English   中英

使用 Python 處理來自串口(Arduino)的數據時遇到困難

[英]Struggling when processing data from Serial Port (Arduino) with Python

我正在嘗試通過 Python 腳本通過連接到 Arduino Uno 的操縱桿移動我的 cursor,因為該板沒有像 Arduino Leonardo 那樣的用於移動鼠標的庫。 因此,我需要幫助解決我在下面提出的問題。 您可以看到代碼是如何工作的,問題是我的代碼的注釋。 拜托,我會感謝一個解決方案。

import serial
import pyautogui
import time
#I import the libraries.
arduino_port="/dev/ttyACM0" #Serial port for comunication(ubuntu).
baud=9600#frecuency

ser=serial.Serial(arduino_port, baud)# Connect to /dev/ttyACM0 at 9600 bauds
print("Connected to the arduino port at ", baud, "bauds") # Confirm connection

while True:#I'm using a while because I want it to run while the program is running, forever.
    data=ser.readline().decode('utf-8').rstrip() # Decode the data printed by arduino in the serial port.
    xyValues=data.split(",")# creates an array like this: ['x','y']
    final_xyValues=[]# declaration of a new array
    for i in xyValues:
        final_xyValues.append(int(i))
    #When the loop has finished, I have this array: [x, y], where x and y are integers.
    print(final_xyValues)
    #to check the problem uncomment the code below:
    """
    if len(final_xyValues)==2:
        pyautogui.moveRel(final_xyValues[0], final_xyValues[1])
        time.sleep(0.2)
    """

"""
Here is where I need help. I want to move the cursor with the values that
the program is constantly receiving and converting to an array called
final_xyValues. The array final_xyValues's first value is the x axis and the
second the y axis.

Take in count that the variable data is a string like this: '405,678', which is
transform to an array with two integers as values. Now, you must know that the values
of final_xyValues are from an analog input of a joystick connected to an Arduino Uno
and read in from the serial port. I want to move the cursor with the analog inputs of the
joystick.

ISSUE: when I uncomment the code from line 21 to 25 the first values of the joystick x and y
position in that moment are ok but after that the data continues identical to the first values
read. The values are correctly and constantly been updated if I comment this part of the code,
if I move the joystick the data changes.
"""

您可以在下面 python 代碼的最后評論中看到操縱桿值的問題。 上面寫着“問題”的地方。 幾天來我一直在尋找解決方案,但沒有任何效果。

#define VRX_PIN  A0 // Arduino pin connected to VRX pin
#define VRY_PIN  A1 // Arduino pin connected to VRY pin

void setup() {
  Serial.begin(9600) ;
}

void loop() {
  int xValue = analogRead(VRX_PIN);//Read the analog value of A0 pin, x axis.
  int yValue = analogRead(VRY_PIN);//Read the analog value of A1 pin, y axis.
  // read analog X and Y analog values
  Serial.print(xValue);
  Serial.print(",");
  Serial.println(yValue);
  //Result: 'x,y'
}

@michael-butscher 寫了一個很好的評論:

只是猜測:PC 每秒只讀取五個值(由於睡眠),但 Arduino 發送的更多,因此它們被緩沖,舊的由 PC 處理。 解決方案:在 PC 端創建一個線程,不斷讀取值,並在每次休眠后僅向主線程提供最新的值。 或者你減少 Arduino output 這邊的睡眠。

@michael-butscher 闡明了一個事實,即在短短的一秒鍾內,您可能有一百行0,0511,510 ,或者恰好是模擬電壓讀數的任何一個。 例如,

511,510
511,510
511,510
511,510
511,510
511,510
511,510
511,510
511,510
511,510
511,510
511,510
511,510
...

這是因為 Arduino 循環非常快,並且會很快用相同的值填充您的 pyserial 輸入緩沖區。

另一方面,您的 Python 循環循環非常緩慢(與 Arduino 相比)。 因此,每 0.2 秒一次,一行一行地消耗每一行的時間。 所以它只會卡在串行輸入的開頭,讀取這些重復的初始值。

您不需要刪除time.sleep(0.2)延遲。 我同意,當 Python 循環減慢到可管理的速度時提高可讀性是有幫助的。

在我看來,一個簡單的解決方案是,在 Python 端,當您准備好讀取 Arduino 報告的新測量值時,清除串行輸入緩沖區。

我建議您嘗試以下無限 while 循環:

while True:

    # Clear entire serial input buffer
    ser.reset_input_buffer()

    # Read and ignore the next line.
    # This solves the issue that if you start reading now, you 
    # may be starting in the middle of a line. So we'll discard
    # this possibly incomplete line.
    ser.readline()

    data=ser.readline().decode('utf-8').rstrip()
    print(data)

    # 'data' is now guaranteed to be a most recent, complete
    # line of measurement data from the Arduino.

    time.sleep(0.2)

您應該注意到 output 現在始終顯示 Arduino 報告的最新模擬測量值。一旦確認,您可以執行您之前執行的原始數據行解析(轉換為 int、檢查數組大小等)。

暫無
暫無

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

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