Bueno, pues llevamos ya unos cuatro artículos dedicados a explorar las posibilidades de Open CV, todos ellos con la perspectiva de acabar programando un robot que responda de modo inteligente a una imagen registrada por una webcam. Sin embargo, aún no hemos acometido una fase muy importante de nuestro aprendizaje, y es el modo en que nuestro ordenador (o nuestra Raspberry, o donde sea que estemos ejecutando nuestro programa en Python) interactuará con Arduino. Para ello, necesitaremos utilizar la librería PySerial:
https://pythonhosted.org/pyserial/
Como en otras ocasiones, ya te digo que nosotros estamos trabajando en Windows, con Python 2.7, y que la instalación de librerías no entra en el objetivo de estos artículos. Los más avezados ya sabéis que un
python -m pip install pyserial
os sacará del apuro. Si no sabéis cómo hacerlo, también podéis consultar directamente el readme.rst del github donde se aloja todo el software: https://github.com/pyserial/pyserial
Y si no, pues como siempre, a bucear y buscar información por la red.
Ya tengo PySerial instalado. ¿Cómo empezamos?.
Ok. Lo primero es averiguar en qué puerto serie vamos a trabajar. Conectaremos la Arduino al cable USB, y arrancaremos la interface. En Herramientas->Puerto, tomaremos buena nota de dicho puerto. En Windows, el nombre será algo del tipo COM6 ó COM11, mientras que en GNU/Linux será más bien algo del tipo /dev/tty/ACM0 o /dev/ttyUSB0:
En el ordenador en el que estoy redactando este artículo, el puerto en cuestión es el COM14. Como este artículo ha nacido con vocación de ser uno de los más cortos que he redactado al respecto, te explico qué queremos hacer, y a continuación te paso el código:
- Crearemos un programa en Python que va a ir leyendo el carácter que el usuario teclee seguido de la tecla ENTER (el valor en el programa se asigna a la variable tecla mediante un raw_input().
- Dicho programa escribirá dicho valor (en binario) a través del puerto COM especificado que habrá abierto antes utilizando la librería serial (pyserial).
- Arduino se va a programar para abrir el puerto Serial mediante la instrucción Serial.begin(9600) y va a estar pendiente de los datos que le lleguen por dicho canal.
- El programa de Arduino tiene una variable de tipo int (entera) denominada teclaLeida. Cada vez que haya datos disponibles en el canal serie se asignará a dicho valor.
- Si dicho valor corresponde en ASCII a la tecla 'a' (apagado) pondrá a cero la salida 13 (suelo utilizar ésta en estos tutoriales porque la Arduino ya lleva un LED incorporado asociado a esta salida; así no es necesario montar LEDs en la protoboard).
- Si en cambio, tecleamos 'e' (encender), pondrá a uno la salida 13, encendiendo el led asociado.
- Cuando tecleemos 'q', se cerrará el programa en Python. No así en Arduino, que se mantiene mientras la tarjeta tenga alimentación eléctrica.
- De momento no nos preocuparemos por la característica de número entero de la variable teclaLeida. Como vamos carácter a carácter, lo que se está enviando por el puerto serie es un único valor en binario, un byte, que Arduino lee sin problemas y cuya programación asocia con el código ASCII de la tecla leída. Es por eso por lo que puede distinguir las teclas 'a' y 'e' (no así las mayúsculas 'A' y 'E', por cierto).
Vale, de acuerdo, llevas prisa y el tutorial es sencillito.. Pero me darás los códigos, ¿no?.
¡Hombre!, ¡hombre!. ¡La duda ofende!.
Ahí va el código en Python (adáptalo al puerto COM en el que tengas tu Arduino conectada, eso sí):
import serial
arduino=serial.Serial("COM14",9600)
tecla=raw_input("Pulsa una tecla")
#La tecla 'q' parará el programa
while(tecla!='q'):
arduino.write(tecla)
tecla=raw_input()
print ("Gracias")
Aquí tienes el código para Arduino:
//Declaramos el valor que leerá las teclas enviadas desde Python
int teclaLeida=0;
void setup() {
//Preparamos el puerto Serial y el pin 13
Serial.begin(9600);
pinMode(13,OUTPUT);
}
void loop() {
//Esperamos a que haya valores en el puerto serie
if (Serial.available()>0){
//Leemos la tecla enviada y se asigna a teclaLeida
teclaLeida=Serial.read();
if (teclaLeida=='e'){
//Si tecleamos 'e', encendemos
digitalWrite(13,HIGH);
}
if (teclaLeida=='a'){
//Si tecleamos 'a', apagamos
digitalWrite(13,LOW);
}
}
}
Es más, me pillas en un momento generoso: ¡hasta te paso el montaje de un diodo LED en protoboard conectado a la salida 13!. ¡Con una resistencia de 220 Ω de regalo, para proteger el LED!:
Si haces la prueba, verás que al ejecutar el programa en Python, éste espera que vayas pulsando teclas (seguidas de ENTER). Si tecleas 'e'e, el LED se encenderá. Si tecleamos 'a', éste se apagará.
Otra cosa será cuando queramos enviar varios valores a la vez, como es el caso de controlar varios servos, o cualquier otro tipo de actuador. En ese caso necesitaremos complicar un poco el programa, como veremos en el artículo final de esta serie, ayudándonos de la librería struct. Pero eso, como decía Michael Ende, es otra historia y deberá contarse en otro momento. Yo he cumplido mi objetivo con este artículo y me retiro a cenar con la alegría del deber cumplido. Hasta entonces, ya sabéis. ¡Sed felices! ¡Seguid aprendiendo!. ¡Seguid creando!. ¡Hasta la próxima!.