Cómo enviar números a Arduino UNO a través de Python 3 y el módulo serial


9

Soy nuevo en Arduino (y en la programación de computadoras en general), así que me disculpo si esta pregunta parece tonta.

Una vez que configuré una conexión básica de arduino-LED, tengo problemas para enviar INTEGERS a arduino a través del puerto serie. Puedo enviar fácilmente caracteres como 'm', 'o', etc. Sin embargo, si envío un número, parece que simplemente no lo obtiene.

Aquí está el código Arduino, idealmente debería obtener un valor del puerto usb a través de python o el monitor en serie y luego ajustar el brillo del LED de acuerdo con el valor. (el valor debe estar en el rango [0,255]).

NOTA: Estoy usando ARDUINO UNO y PYTHON 3

// --------------------------

int LED = 10;
int number;

void setup(){

pinMode(LED,OUTPUT);
Serial.begin(9600);
}

void loop(){

number = Serial.read();
Serial.print(number);
Serial.print('\n');
if(number == -1){
number = 0;
}

else if(number > 255){

number = 255;

}

else if(number < 0){

number = 0;
}

analogWrite(LED,number);
delay(1000);
}

Sin embargo, cuando ingreso un valor en el puerto serie o a través de Python, por ejemplo 0, me da 48 como respuesta (¡lo que es interesante es el código ASCII para 0!) E ilumina el LED, que no es lo que debería suceder desde entonces. ¡a 0 el LED debería estar apagado! Me falta algo pero no puedo encontrar qué ... ¿Podrías decirme qué está mal?

Aquí está el código que uso en Python:

import serial
import time
try:
    arduino = serial.Serial(port,speed)
    time.sleep(2)
    print("Connection to " + port + " established succesfully!\n")
except Exception as e:
    print(e)

#Note: for characters such as 'a' I set data = b'a' to convert the data in bytes
#However the same thing does not work with numbers...
data = 0
data = arduino.write(valueToWrite)
time.sleep(2)
arduino.close()

¿Qué estoy haciendo mal o malentendido? Gracias.


1
Pruebaarduino.write(chr(valueToWrite))
Gerben

Esta solución no funciona incluso para los caracteres. Además, en lo que respecta a los caracteres, funciona bien simplemente enviándolos como bytes como: b'm '. De todos modos, gracias por la respuesta.
mickkk

Respuestas:


6

El análisis en Arduino puede ser lento y lento (lo cual es malo si usa la preescala del reloj o tiene tareas de tiempo crítico), así que hagámoslo en Python.

El problema es que está enviando los números como ASCII, mientras que debe enviarlos como binarios sin formato. Aquí es donde structentra.

3>> import struct
3>> print(struct.pack('>B', 0))
b'\x00'
3>> print(struct.pack('>B', 255))
b'\xff'
3>> print(struct.pack('>2B', 255, 0))
b'\xff\x00'
3>> print(struct.pack('>H', 9000))
b'#('

Entonces, lo que realmente quieres es:

data = arduino.write(struct.pack('>B', valueToWrite))

O algo por el estilo.


¡Muchas gracias! ¡Esto es exactamente lo que estaba buscando!
mickkk

A pesar de lo que dice el texto en blanco del cuadro de comentarios vacío, ¡voy a decir gracias! Estaba tratando de escribir un flujo de bits (archivo de programa FPGA .bin) en un chip flash SPI usando un Teensy 3.2 con Arduino como PC -> interfaz flash, y esta fue la clave para que funcione en el PC.
KyranF

1

Serial.read()lee solo UN carácter del puerto serie y devuelve su valor ASCII, lo que explica lo 48que obtuvo.

Para leer un número completo, tiene 2 opciones:

  1. Use Serial.parseInt()que lea tantos caracteres como sea necesario y realice la conversión antes de devolver el número leído como an int. Por favor, consulte la referencia aquí.
  2. Usted lee cada carácter en un bucle (con Serial.read()) hasta el último, coloca cada carácter de lectura en un búfer ( charmatriz) y luego convierte la cadena resultante en un número con la función C estándar atoi.

Por supuesto, la primera opción es la más fácil, pero regresará 0si no se lee nada después de un tiempo de espera (configurable con Serial.setTimeout()).


Esta respuesta no fue exactamente lo que estaba pidiendo, sin embargo, ha sido muy útil y la usaré. ¡Muchas gracias por la ayuda!
mickkk
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.