使用Python从Arduino阅读字节

uxhixvfz  于 2022-12-21  发布在  Python
关注(0)|答案(2)|浏览(127)

我正在尝试用Python从Arduino读取串行输入。我正在尝试做一个简单的任务-我的Arduino有一个按钮写入串行状态。这是Arduino的代码:

const int ledPin = 7;
const int buttonPin = 2;
int buttonState= 0;
void setup() {
  Serial.begin(9600); 
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
 buttonState = digitalRead(buttonPin);
 if(buttonState == LOW){ digitalWrite(ledPin, HIGH);} else digitalWrite(ledPin, LOW);
  Serial.println(buttonState); 
  delay(50);
}

使用Arduino 1.8.13软件中的串行监视器,我可以看到它打印0或1。
我试着用下面的Python代码来读取它:

import serial

ser = serial.Serial('COM10', baudrate = 9600, timeout = 1)
 
t = 0
while t<10:
    arduinoData = ser.readline().decode()
    print(arduinoData)
    t+=1
print(type(arduinoData))
ser.close()

我读取了前10个输入,并打印了arduinoData的类型,在本例中是string,因为我使用的是.decode()。但是,我不能使用诸如arduinoData=='1'之类的布尔运算符来做任何事情,即使它被解码为string。我尝试使用.decode('ascii').decode('UTF-8'),但无济于事。
我如何检查值,或者我如何废弃.decode()并将字节转换为简单的整数,然后使用布尔运算符?我使用的是带有Arduino Uno的python 3.9。
更新1
我已经设法用Python把它从str转换成int了:

import serial

ser = serial.Serial('COM10', baudrate = 9600, timeout = 1)

t=0
while t<10:
    arduinoData = ser.readline().decode()
    print(arduinoData)
    t+=1
if(int(arduinoData) == 1):
    print("Input is 1")
ser.close()

这样,我就可以看到串行输入确实等于1,但是如果它不等于1,我希望做些什么,所以我将检查放在循环中,如下所示:

import serial

ser = serial.Serial('COM10', baudrate = 9600, timeout = 1)

t=0
while t<10:
    arduinoData = ser.readline().decode()
    print(arduinoData)
    if(int(arduinoData) == 1):
        print("Input is 1")
    t+=1

ser.close()

并得到以下错误:

Traceback (most recent call last):
  File "C:\Users\01132892\Desktop\Serial\SerialButtonPurple.py", line 12, in <module>
    if(int(arduinoData) == 1):
ValueError: invalid literal for int() with base 10: ''

我假设这是一个在循环内部转换它的问题,但是我不知道如何解决它。

iecba09b

iecba09b1#

好的,我已经设法解决了这个问题。请注意,为了检查它是否在主循环中工作,如果按钮没有被按下(信号读取为0),我将按下“a”键,如果信号读取为1,我将释放它。

import serial
import pynput

ser = serial.Serial('COM10', baudrate = 9600, timeout = 1)

from pynput.keyboard import Key, Controller
keyboard = Controller()
while 1:
    arduinoData = ser.readline().rstrip()
    print(arduinoData)
    if(arduinoData==b'0'):
        keyboard.press('a')
    else:
        keyboard.release('a')
ser.close()

我要感谢ocrdu建议使用rstrip()来消除EOL。

wn9m85ua

wn9m85ua2#

我的Python并不是很好,但是也许ser.readline()也会返回EOL,如果是这样,arduinoData就不仅仅包含"1"。
如果我是对的,* 它应该工作,如果你剥离EOL *。
或者:让Arduino用Serial.print(buttonState);发送单字节,用ser.read()读取Python中的单字节,发送和读取单字节时不需要分隔符。

相关问题