#python #arduino #serial-port #pyserial
#python #arduino #последовательный порт #pyserial
Вопрос:
Я пытаюсь прочитать последовательный ввод с Arduino на Python. Я пытаюсь выполнить простую задачу — на моем 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
, который в данном случае является строкой, поскольку я использую .decode()
. Однако я не могу использовать логические операторы, такие как arduinoData=='1'
для выполнения каких-либо действий, даже если они декодируются в строку. Я пытался использовать .decode('ascii')
, .decode('UTF-8')
но безрезультатно.
Как я могу проверить значения или как я могу .decode()
удалить и преобразовать байты в простые целые числа, чтобы затем использовать логические операторы? Я использую python 3.9 с Arduino Uno.
ОБНОВЛЕНИЕ 1
Мне удалось преобразовать его из str
в int
этот способ в Python:
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:Users1132892DesktopSerialSerialButtonPurple.py", line 12, in <module>
if(int(arduinoData) == 1):
ValueError: invalid literal for int() with base 10: ''
Я предполагаю, что это проблема с преобразованием его внутри цикла, однако я понятия не имею, как ее решить.
Ответ №1:
Хорошо, мне удалось решить проблему. Пожалуйста, обратите внимание, что для проверки того, работает ли он в основном цикле, я нажимаю клавишу «a», если кнопка не нажата (считывание сигнала равно 0), и отпускаю ее, если сигнал равен 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.
Ответ №2:
Мой Python не так уж хорош, но, возможно ser.readline()
, также возвращает EOL? Если это так, arduinoData
не содержит только «1».
Если я прав, это должно сработать, если вы удалите EOL.
В качестве альтернативы: попросите Arduino отправить отдельные байты Serial.print(buttonState);
и прочитать отдельные байты в Python ser.read()
. При отправке и чтении отдельных байтов разделитель не требуется.
Комментарии:
1. Привет! Конечно, вы правы — потому что без
decode()
Python читается что-то вродеb'1nr'
. Однако, если бы я должен был использоватьSerial.print(buttonState)
, у меня не было бы делиметра, чтобы отмечать отдельные показания, я думаю2. Вам не нужен разделитель, если вы одновременно отправляете и читаете отдельные байты, а ser.read() считывает отдельные байты. Не забудьте проголосовать и / или принять ответ, чтобы вопрос не оставался открытым. Принимаю только в том случае, если я понимаю, конечно, 8-).
3. Я буду отправлять разные параметры одновременно (несколько кнопок), так что будет проще
4. Ваш отредактированный ответ похож на мой обновленный способ, к сожалению, он также имеет ту же ошибку (я прикрепил ее к исходному вопросу)