51

Tutorial de Arduino y Python con Pyserial

(Última actualización 21/8/2019)

¡Hola, seguidores! A petición de uno de mis contactos humanos, hoy haré un breve tutorial sobre interacción entre Arduino y Python utilizando pySerial.

En la primera parte intentaremos controlar un LED mediante comandos que enviaremos de nuestro ordenador a Arduino utilizando un sencillo programa en Python. En la segunda parte moveremos un pequeño servo enviando un números entre 0-180 por Serial.

El concepto

Conceptualmente, el tutorial de hoy es muy sencillo. Tenemos un código en python ejecutándose dentro de nuestro ordenador que envía mensajes (carácteres) a la placa Arduino.

En el primer ejemplo, la placa Arduino estará cargada con un programa leerá estos mensajes y encenderá el LED 13 si recibe el carácter ‘e’, y lo apagará si recibe el carácter ‘a’. ¿Fácil, no?

 esquema_tutorial_serial

En el segundo ejemplo, Arduino convertirá el mensaje que le llegue a un número entero y lo pasará como parámetro a la función serial.write().


Material

  • Un ordenador con python, pySerial y Arduino IDE
  • Cable USB
  • Placa Arduino
  • Díodo LED (si no queremos utilizar el que lleva la placa Arduino)
  • Servo
  • Batería

1. Controlar un LED con Python

Primero escribiremos el código en python que deberemos ejecutar en nuestro ordenador. Éste código lee un carácter introducido por el usuario y lo envía por Serial a Arduino. Si se escribe una ‘s’, salimos del programa. Recuerda cambiar el ‘/dev/ttyACM0’ de la línea 4 por el puerto de tu Arduino.

"""
    PROGRAMA DE PYTHON
    Pide un caracter al usuario y lo envia por Serial.

"""


import serial

#Inicializamos el puerto de serie a 9600 baud
ser = serial.Serial('/dev/ttyUSB0', 9600)

#Mostramos una chuleta con todos los comandos
print("Lista de comandos: \n 'e' - Encender led \n 'a' - Apagar led \n 's' - Salir del programa\n")

#Pedimos un caracter al usuario
print("Introduce un caracter: ")

#Guardamos este caracter en una variable
entrada = raw_input()

#Introduciendo 's' salimos del bucle
while entrada != 's':

   #Enviamos el caracter por serial, codificado en Unicode
   ser.write(str(entrada).encode())

   #Mostramos el caracter enviado por pantalla
   print("He enviado: " + str(entrada))

   #Y pedimos un nuevo caracter al usuario
   print("Introduce un caracter: ")
   entrada = raw_input()

Guardamos este código en un fichero con extensión ‘.py’ . Ahora habrá que escribir el código para Arduino, que sencillamente encenderá un LED al recibir ‘e’ por Serial y lo apagará al recibir ‘a’.

/*
    CODIGO PARA ARDUINO
    Enciende el LED 13 al recibir el caracter 'e' por Serial, y lo apaga
    al recibir el caracter 'a'
*/

#define LED 13

int mssg = 0; //variable para guardar el mensaje
 
void setup()
{
   pinMode(LED, OUTPUT); //establecemos el pin D13 como salida
   Serial.begin(9600); //inicializamos Serial
}
 
void loop()
{
   if (Serial.available() > 0)
   {
      mssg = Serial.read(); //leemos el serial
 
      if(mssg == 'e')
      {
         digitalWrite(13, HIGH); //si entra una 'e' encendemos el LED
      }
      else if(mssg == 'a')
      {
         digitalWrite(13, LOW); //si entra una 'a' apagamos el LED
      }
   }
}

Y si habéis seguido todos los pasos debería funcionar correctamente. Ahora ya estamos preparados para controlar algo más complejo como puede ser un Servo o un actuador por el estilo.


2. Controlar un Servo

En esta segunda parte aprenderemos a mover un servo con Pyserial. El programa de Python enviará números enteros entre 0 y 180 (correspondientes al ángulo de giro) y la placa Arduino los leerá y moverá el servo.

Tendremos que hacer estas conexiones entre el Servo y Arduino. Además, recomiendo alimentar la placa Arduino con una batería.

  • Arduino Vin → Servo +
  • Arduino GND → Servo –
  • Arduino D3 → Servo Sig.

En primer lugar modificaremos el código de Python para que sólo acepte números entre 0-180 y el carácter ‘s’ para salir.

"""
    PROGRAMA DE PYTHON
    Pide un entero entre 0-180 al usuario y lo envia por Serial.

"""


import serial

#Inicializamos el puerto de serie a 9600 baud
ser = serial.Serial('/dev/ttyUSB0', 9600)

#Mostramos una chuleta con todos los comandos
print("Introduce un numero entre 0-180, o 's' para salir del programa\n")

#Pedimos un caracter al usuario
print("Introduce un numero entre 0-180: ")

#Guardamos este caracter en una variable
entrada = raw_input()

#Introduciendo 's' salimos del bucle
while entrada != 's':

   #Si el numero es valido, se envia por serial
   if(int(entrada) >= 0 and int(entrada) <= 180):

      #Enviamos el numero por serial, codificado en Unicode
      ser.write(str(entrada).encode())

      #Mostramos el caracter enviado por pantalla
      print("He enviado: " + str(entrada))

   #Si el numero no es valido, mostramos un mensaje de error
   else:
      print("Error: introduce un numero entre 0-180, o 's' para salir")
   

   #Y pedimos un nuevo numero al usuario
   print("Introduce un numero entre 0-180: ")
   entrada = raw_input()

 

En este pequeño código de Arduino conectamos el servo al pin D3 y utilizamos la instrucción Serial.parseInt() para convertir el mensaje que llega por Serial directamente a un número entero.

/*
    CODIGO PARA ARDUINO
    Mueve un servo segun el valor recibido por Serial
*/
#include <Servo.h>

#define SER 3 //Pin para el servo

Servo servo; //Objeto servo

int mssg; //Variable para guardar el mensaje recibido por serial
 
void setup()
{
   //Inicializamos el servo y el Serial:
   servo.attach(SER);
   Serial.begin(9600);
}
 
void loop()
{
   if (Serial.available() > 0)
   {
     mssg = Serial.parseInt(); //Leemos el serial
     servo.write(mssg); //Mover el servo
     delay(500);
   }
}

¡Y ya está! Ahora podemos controlar el servo a través de nuestro ordenador, enviando la posición por Serial.


Relacionados

N4n0

Creado para cuidar de los sistemas de laboratorios tan secretos que ni él tiene la seguridad de estar trabajando en ellos, a Nano le gusta dedicar los ciclos que no gasta en tapar agujeros de Firewall para dedicarse al hobby de la electrónica o a ver películas de ciencia ficción. Entre su filmoteca de culto, ocupan un lugar destacado Tron, The Matrix y Johnny Mnemonic.

guest
51 Comments
más nuevos primero
más antiguos primero
Inline Feedbacks
Ver todos los comentarios
Roberto
Roberto
2 meses

Hola
Soy nuevo en programación y quiero saber cuál es el mejor para usar

¿Cual es la diferencia entre el lenguaje arduino y el lenguaje python? ¿Cuales son las ventajas y desventajas que tienen ambos tipos de lenguaje de programación?

Franco
Franco
2 meses

hola, quiero comunicar mi robot por medio del protocolo standarfirmata usando el sensor HCSR04 pero python es muy lento para interpretar a tiempo el sensor, quería saber si podría darme una mano para solucionar este problema por favor, gracias.

wilder
wilder
5 meses

hola

ayuda me sale este error

Traceback (most recent call last):
File “led.py”, line 4, in
ser = serial.Serial(‘COM3’, 9600)
AttributeError: module ‘serial’ has no attribute ‘Serial’

***Repl Closed***

Gl4r3
Admin
5 meses
En respuesta a  wilder

¡Hola, Wilder! ¿No habrás instalado el paquete ‘serial’ en vez de ‘pyserial’?

rodrigo
rodrigo
10 meses

hola disculpa quiero hacer el juego de la batalla naval con el uso de puerto serie , y asi contyrolar por cordenadas una matriz de leds me puedes dar una idea de como hacerlo , ya tengo mi codigo de la batalla , solo quiero saber el metodo de que interactuen y que el arduino al meter en pantalla de mi pc una cordenada el led seleccionado se prenda o apague

Gl4r3
Admin
10 meses
En respuesta a  rodrigo

¡Hola, rodrigo! Disculpa la tardanza.
Podrías enviar un string de la forma XXYY a tu placa Arduino, dónde XX es la coordenada x e YY es la coordenada y.
Después puedes leer este mensaje con Serial.parseInt(), que lo convertirá en un entero, y lo guardas en una variable “mensaje”.
Por último calculas ‘mensaje/100’ para tener la coordenada X, y ‘mensaje%100’ para obtener la coordenada Y.

Estrella Gmc
Estrella Gmc
1 año

Hola
Me podrían ayudar estoy tratando de controlar unos motores con Arduino dependiendo de los valores que me dé pyton pero no puedo hacer el enlace

cubits
cubits
1 año

super interesante o sea que con python se puede crear un robot que reciba ordenes enviandolas por serial y que reciba sensores de arduino para quiza montar con alguna otra libreria de inteligencia artificial unas neuronas para que los sensores del robot vayan mejor segun los datos que nos va enviando :/ ???

RaiRayo
RaiRayo
2 años

hola amigo una pregunta , si mi idea es recibir una lectura desde cierto controlador y analizarla con una lectura teoria y mostrar en pantalla (interfaz usuario) como haria eso? es posible comunicar esto por ejemplo con un formulario aparte? y muestre eso en la pantalla del pc

Irving
3 años

Hola amigo y como seria para que la comunicacion sea en ambos sentidos, es decir, usar sensores y mandar el valor captado por el sensor a python y dependiendo de ese valo se envie un valor a arduino, es decir, que la comunicacion sea para ambos lados.

anthony
anthony
3 años

como lo aria para que me corra en blender .!!!

Gl4r3
Admin
3 años
En respuesta a  anthony
enrique
enrique
3 años

Hola gracias por el tutorial esta muy bien explicado.

tengo una duda se pudiera enviar el código de arduino por medio de python y grabarlo en la placa? sin usar el ide de arduino

Gl4r3
Admin
3 años
En respuesta a  enrique

No, Arduino no se puede programar directamente en Python.

juan
juan
3 años

me da este error =(

karen
karen
3 años

hola me gustaria saber como le podria acer para de python enviar una señal al arduino pero que en este caso encienda o apague un servo

Gl4r3
Admin
3 años
En respuesta a  karen

¡Hola! Puedes enviar un string de números por Serial que se corresponda al ángulo del Servo. Arduino lo puede convertir a entero con Serial.parseInt() y lo después lo pasa como parámetro a la función Serial.write().

¡Un saludo!

Bernie
Bernie
3 años

Hola! Quería saber si puedes ayudarme con una duda! Necesito hacer una interacción entre varios botones y leds y no sé como hacerlo! Me imagino que con Python pero no lo se….
Lo que necesito es que, a modo de ejemplo, si tengo 6 botones y 6 leds, y aprieto el boton #1 y el boton#2 (al mismo tiempo) que se prenda cierto led (asumo que para que el arduino decida qué led prender necesito un programa en python, no?)… No se si me entiendes 🙁

Bernie
Bernie
3 años
En respuesta a  N4n0

Ya gracias!! Y tengo otro problema!! Necesito usar 9 botones y 15 leds, es mucho y no se que hacer (por el numero limitado de pines) me podrias ayudar con eso??

Gl4r3
Admin
3 años
En respuesta a  Bernie

¡Hola, Bernie! Si quieres controlar más dispositivos que pines tiene Arduino, vas a necesitar un multiplexor: https://es.wikipedia.org/wiki/Multiplexor

Bernie
Bernie
3 años
En respuesta a  Gl4r3

Solo sirve para muchas entradas? O también para muchas salidas?

Gl4r3
Admin
3 años
En respuesta a  Bernie

Sirve para ambos.

Bernie
Bernie
3 años
En respuesta a  Gl4r3

Ah y gracias! jajaja

N514
N514
3 años

Tal vez esta pregunta parezca súper estúpida, pero… ¿Dónde descargo la librería? y ¿Dónde la pongo en Python?

Gl4r3
Admin
3 años
En respuesta a  N514

¡Hola! En la web de pySerial hay todas las instrucciones para su instalación:

http://pyserial.readthedocs.io/en/latest/pyserial.html

Andres
Andres
4 años

Hola! tengo una consulta.. cuando recién establezco la comunicación serial debo especificar de antemano el puerto COM (o dev) en el cual se encuentra mi arduino… en python existe alguna forma de “buscarlo” de forma automática.. por ejemplo si antes de la experimentación no conozco en que puerto esta el arduino, que mi programa lo busque y lo especifique?? Muchas gracias y el código de la página funciona 🙂

Gl4r3
Admin
4 años
En respuesta a  Andres

¡Hola Andrés! Mírate este hilo, el primer comentario tiene un código que puede ayudarte a listar todos los puertos Serial de tu ordenador:

http://stackoverflow.com/questions/12090503/listing-available-com-ports-with-python

Jhon
4 años

Hola que tal si quiera crear mi propio protocolo de comunicación sin usar la librería serial como sería?? Espero que me puedas ayudar

henrry
henrry
4 años

como puedo hacer una interfaz grafica para este programa de encender el led utilizando php llamando phyton y arduino un ejemplito porfa con este mismo ejemplo

Josué Chaves
4 años

hola, yo quisiera ejecutar con otra función que recibe números al azar y los compara con otro, y si son iguales necesito que escriba X y encienda un led de cinco que tienen que ser. Lo enciende según la posición de donde este la X. Como podría hacer eso? Gracias de antemano

DiegoAlejo
DiegoAlejo
4 años

Genial robologs! si yo quisiera transportar una palabra completa o algún número de más de 1 dígito a arduino ¿cómo haría?. Un saludo fraterno y terrícola.

Pablo
Pablo
4 años

buen tutorial, muchos saludos 🙂

sebastian_knight
sebastian_knight
5 años

para los que no le sirve el codigo lo tengo actualizado y corregido:

import serial

ser = serial.Serial(‘COM4’, 9600)

print (“Introduce un caracter (‘s’ para salir): “)
entrada = input()

while entrada != ‘s’:

ser.write(str(entrada).encode())
print (“He enviado: “, entrada)
print (“Introduce un caracter (‘s’ para salir): “)

entrada = input()

Javi
Javi
4 años
En respuesta a  sebastian_knight

Hola estoy empezando con python.
me da un error en ser.write (str (entrada).encode ())

Eber
Eber
1 año
En respuesta a  N4n0

Hola, lo he hecho así pero me apare lo siguiente:
unicode strings are not supported, please encode to bytes: “b’a'”

Espero me puedas ayudar

Gl4r3
Admin
1 año
En respuesta a  Eber

¡Hola Eber! He añadido un pequeño cambio en el código de python que creo que solucionará tu problema.

crisxp44
5 años

Porque si hago esto en un archivo .py y lo hago correr no funciona, pero cuando lo escribo directo en la consola de python, si funciona?

import serial
ser = serial.Serial(‘/dev/ttyACM0′, 9600)

entrada = ’1′

ser.write(entrada)

Elias Castro Salazar
Elias Castro Salazar
4 años
En respuesta a  N4n0

Eso ocurre porque Arduino tarda 2 segundos en iniciar el sketch luego de comenzar la conexion serial. Cualquier dato que se envie durante los dos primeros segundos de iniciar la conexion en Python se perdera a Arduino. Siempre despues de iniciar la conexion serial se debe dar una pausa para que Arduino quede “en modo espera” por decirlo de una forma facil de entender. Espero que sirva la explicacion luego de tanto tiempo. Saludos