Comunicació entre Arduino i Python fent servir el port sèrie

De binefa.com
Salta a la navegació Salta a la cerca

Codi mínim d'Arduino

#define BOTO 2
#define LED  13

void setup() {
  Serial.begin(9600);
  pinMode(BOTO, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
}

void loop() {
  // Llegeix botó i envia estat ('0' o '1')
  Serial.println(digitalRead(BOTO) == LOW ? '1' : '0');

  // Rep ordre del PC: 'e' encén, 'a' apaga
  if (Serial.available()) {
    char ch = Serial.read();
    if (ch == 'e') digitalWrite(LED, HIGH);
    if (ch == 'a') digitalWrite(LED, LOW);
  }

  delay(200);
}

Codi mínim de Python (v1)

#!/usr/bin/env python3
"""
Mínim bidireccional Arduino ↔ Python
  Arduino → PC : '1' botó premut, '0' no premut
  PC → Arduino : 'e' encén LED, 'a' apaga LED

PORT: Windows → 'COM3'  |  Linux → '/dev/ttyUSB0'
"""
import serial, threading, time

PORT = '/dev/ttyUSB0'

ser = serial.Serial(PORT, 9600, timeout=1)
time.sleep(2)  # espera reset Arduino

def llegir():
    while True:
        linia = ser.readline().decode('ascii', errors='ignore').strip() # strip() treu espais i salts de línia
        if linia:
            print(f"\rBotó: {'PREMUT' if linia == '1' else 'alliberat'}   ", end=)

threading.Thread(target=llegir, daemon=True).start()

print("Escriu 'e' (encén) o 'a' (apaga). Ctrl+C per sortir.\n")
while True:
    cmd = input()
    if cmd in ('e', 'a'):
        ser.write(cmd.encode())

Codi mínim de Python (v2)

#!/usr/bin/env python3
"""
Mínim bidireccional Arduino ↔ Python
  Arduino → PC : '1' botó premut, '0' no premut
  PC → Arduino : 'e' encén LED, 'a' apaga LED

PORT: Windows → 'COM3'  |  Linux → '/dev/ttyUSB0'
Instal·lació: pip install pyserial readchar
A Linux: sudo apt install python3-full

# Crear un entorn virtual i activar-lo
python3 -m venv ~/.venv
source ~/.venv/bin/activate          # Linux
# .venv\Scripts\activate             # Windows 

pip install readchar pyserial

# Per desactivar-lo:
deactivate
"""
import serial, threading, time, readchar

PORT = '/dev/ttyUSB0'

ser = serial.Serial(PORT, 9600, timeout=1)
time.sleep(2)  # espera reset Arduino

def llegir():
    while True:
        linia = ser.readline().decode('ascii', errors='ignore').strip()
        if linia:
            print(f"\rBotó: {'PREMUT' if linia == '1' else 'alliberat'}   ", end=)

threading.Thread(target=llegir, daemon=True).start()

print("Prem 'e' (encén) o 'a' (apaga). Ctrl+C per sortir.\n")
while True:
    cmd = readchar.readchar()
    if cmd == readchar.key.CTRL_C:
        break
    if cmd in ('e', 'a'):
        ser.write(cmd.encode())