En esta ocasión te mostraré por medio de un pequeño ejemplo cómo es que la visión artificial puede interconectarse con tu Arduino. Para demostrártelo, controlaremos la posición de un servomotor de acuerdo con la posición de un objeto frente a una cámara.
Tabla de Contenidos
¿Qué es la visión artificial?
Antes de iniciar con los ejemplos, es necesario que te explique un poco sobre visión artificial. Seguramente has leído, escuchado o visto algo sobre visión artificial, y cómo no, está en todos lados ahora, desde los filtros que utilizamos al publicar una foto en Instagram, o para resaltar características de alguna imagen, pero sobre todo, para automatizar procesos sin la necesidad de un sensor propiamente dicho.
Para definir qué es la visión artificial, es necesario definir primero el procesamiento de imágenes. El procesamiento de imágenes es simplemente aplicar algoritmos matemáticos a una imagen para resaltar algunos elementos dentro de ella, ya sea aplicando filtros, eliminando datos o segmentando para separar la información. Cuando procesamos una imagen, podemos rescatar (o resaltar) cierta información, pero el qué hacemos con esa información depende de nosotros.
Es aquí cuando el siguiente concepto, visión artificial, entra en juego. La visión artificial toma a la imagen procesada, y con base en los elementos que se destacan, se construye un sistema o algoritmo matemático que puede tomar una decisión con esa información. Entonces es cuando nosotros le programamos para que pueda el sistema discernir de manera autónoma. Aquí se convierte en un sistema de visión artificial. Y el concepto de visión, pues viene de que estamos hablando de imágenes a través de una cámara por ejemplo. Recuerda que un video no son más que muchas imágenes una detrás de otra.
La visión artificial cada vez se está utilizando más y más, gracias al gran potencial que tiene de aplicación, ya que solamente necesitamos una cámara y código de programación para hacer maravillas. Es un tema que realmente me gusta mucho y puedo enseñarte algunos truquitos 😎.
Visión Artificial con Arduino
Para el ejemplo que te mostraré el día de hoy, la placa Arduino no realizará propiamente el procesamiento, simplemente ejecutará las instrucciones finales de control. El esquema sobre el que trabajaremos será el siguiente:
Dentro de la computadora implementaremos un código utilizando el lenguaje Python y OpenCV para acceder a la webcam, capturar en tiempo real la posición de un objeto de un color que destaque y mapearemos su posición dentro de la imagen. De acuerdo con esta posición, se le enviará al Arduino la posición mediante el puerto Serie, que se encuentra dentro del puerto USB. Este mensaje, el Arduino lo recibirá y dependiendo de que posición sea, mandará la instrucción a un servomotor para modificar su posición. La idea general es que la posición del servo «siga» a la posición del objeto clave, como si lo estuviera observando directamente.
Si no estás muy familiarizado con el procesamiento de imágenes y visión artificial o con el lenguaje de programación Python, no te preocupes, como siempre te guiaré paso a paso para lograr el objetivo.
Instalar Python en tu computadora
Lo primero que debes saber es que Python es un lenguaje de programación muy fácil de utilizar y sobre todo me gusta porque es multiplataforma, funciona en Windows®, Mac OSX® y Linux®. Pero me gusta más porque fácilmente podemos migrar su funcionamiento de una computadora a una tarjeta electrónica dedicada como las RaspberryPi®.
Para instalar Python en tu computadora tienes que simplemente descargar una versión del lenguaje y del compilador, para mi caso yo instalé la versión 3.9.2. Para revisar la versión más reciente para tu sistema operativo visita la página oficial.
Una vez que lo tienes instalado, existen varias maneras de utilizarlo en tu computadora, puede ser desde la Terminal, desde el IDE instalado junto con el compilador, o puedes instalar software de terceros para gestionar tus programas, a mí me gusta trabajar con PyCharm, con su versión gratuita.
Si quieres aprender más a detalle sobre programación en Python déjame tus comentarios!
Sea cual sea tu decisión, el código funcionará sin problemas. Pero para realizar el ejercicio de hoy, necesitaremos instalar una librería más.
¿Te está gustando este artículo?
Te invito a descargar totalmente gratis la Guía de Inicio en Arduino
Encontrarás mucha información extra, conceptos y sobre todo podrás llevarla contigo en todo momento
Instalar OpenCV en tu computadora
OpenCV es una biblioteca desarrollada especialmente para la visión por computadora (visión artificial), es libre y originalmente la desarrolló Intel®. De igual manera, es multiplataforma, tanto para sistemas operativos como para arquitecturas de hardware como RaspberryPi, entre otras.
La versión que yo instalé para este proyecto es la 4.5.1.48. Para instalarla existen muchos métodos, si estás en Windows puedes descargarlo desde aquí. O de una manera simplificada, abres tu Terminal y escribes pip install opencv-contrib-python
de manera automática te instalará los paquetes básicos de OpenCV para Python y algunos paquetes extras.
Yo como estoy en el sistema operativo de Mac OSX, lo instalé directamente desde PyCharm, ya que en este software puedo elegir distintas versiones para trabajar con cada proyecto de manera independiente.
Puedes verificar si todo quedó instalado correctamente abriendo tu Terminal (o cmd en Windows) y teclear lo siguiente:
1 |
python3 |
Con esto entras a la interfaz de python en su versión 3. Ahora tienes que importar la biblioteca de OpenCV y posteriormente revisar la versión:
1 2 |
import cv2 cv2.__version__ |
Si en algún paso de los anteriores te saltó un error, es que la instalación no quedó correcta.
Si todo sale correcto, verás algo parecido a esto:
Por cierto, también necesitaremos instalar la biblioteca numpy: pip install numpy
esta nos ayudará a manejar matrices de datos, ya que las imágenes básicamente son matrices de números.
Si te interesa aprender sobre procesamiento de imágenes déjame tus comentarios y puedo enseñarte todo lo que sé!
Editado el 17 de junio del 2021
También necesitaremos instalar una librería para utilizar el puerto Serie, ya que para este ejemplo utilizaremos la comunicación serial con el Arduino y la PC. Para instalarla, deberemos ejecutar el comando: pip install pyserial
Código en Python para utilizar con Arduino
Ahora pasaremos a crear el código para realizar el algoritmo de visión artificial y enviarle los datos al Arduino por medio del puerto Serie.
El código completo a utilizar es el siguiente:
Editado el 25 de abril del 2021
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
import cv2 import numpy as np import serial COM = '/dev/cu.usbserial-14120' BAUD = 9600 ser = serial.Serial(COM, BAUD) cap = cv2.VideoCapture(2) azulBajo = np.array([90, 100, 20], np.uint8) azulAlto = np.array([120, 255, 255], np.uint8) while True: ret, frame = cap.read() if ret: frame = cv2.flip(frame, 1) frameHSV = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) mascara = cv2.inRange(frameHSV, azulBajo, azulAlto) contornos, _ = cv2.findContours(mascara, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(frame, contornos, -1, (255, 0, 0), 4) for c in contornos: area = cv2.contourArea(c) if area > 6000: M = cv2.moments(c) if M["m00"] == 0: M["m00"] = 1 x = int(M["m10"] / M["m00"]) y = int(M['m01'] / M['m00']) cv2.circle(frame, (x, y), 7, (0, 0, 255), -1) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(frame, '{},{}'.format(x, y), (x + 10, y), font, 1.2, (0, 0, 255), 2, cv2.LINE_AA) nuevoContorno = cv2.convexHull(c) cv2.drawContours(frame, [nuevoContorno], 0, (255, 0, 0), 3) if x < 200: print("Mover a la izquierda 100%") ser.write(b"izq1\n") elif 420 > x >= 200: print("Mover a la izquierda 60%") ser.write(b"izq2\n") elif 520 > x >= 420: print("Mover a la izquierda 30%") ser.write(b"izq3\n") # Mover al centro elif 520 <= x < 650: print("Mover al centro") ser.write(b"ctr\n") elif 650 <= x < 860: print("moviendo a la derecha 30%") ser.write(b"der3\n") elif 860 <= x < 1080: print("moviendo a la derecha 60%") ser.write(b"der2\n") elif x >= 1080: print("Moviendo a la derecha 100%") ser.write(b"der1\n") # cv2.imshow('mascaraAzul', mascara) cv2.imshow('frame', frame) if cv2.waitKey(1) & 0xFF == ord('s'): ser.close() break cap.release() cv2.destroyAllWindows() |
¿Muy cortito no? Pero para aquellos que estamos aprendiendo Python, vamos a desglosarlo.
Primero importamos las bibliotecas a utilizar, que son la de OpenCV, numpy y serial:
1 2 3 |
import cv2 import numpy as np import serial |
Posteriormente, inicializaremos el puerto Serie con la configuración adecuada. En mi caso, declararé el nombre del puerto serie donde tengo conectada mi placa Arduino. Si estás en Windows, probablemente sea un COM3 o algo así. Para verificar donde lo tienes conectado, simplemente conecta tu placa al puerto USB y dentro del IDE de Arduino, verifica el puerto de conexión, ahí podrás observar el nombre. La velocidad tú la eliges, recordando que tanto el Arduino como el código en Python deberán tener la misma. Finalmente creamos una variable llamada ser
que será para el puerto serie.
1 2 3 |
COM = '/dev/cu.usbserial-14120' BAUD = 9600 ser = serial.Serial(COM, BAUD) |
Ahora vamos a crear una variable para obtener la imagen de la webcam. Si observas, utilizamos la biblioteca de OpenCV, con cv2.VideoCapture()
dentro del paréntesis deberá ir un ID de acuerdo con la cantidad de dispositivos de cámaras que tengas instalados en tu computadora, normalmente con un 0
debería de funcionar; si no, ya sabes, ponle 1
o 2
etc.
1 |
cap = cv2.VideoCapture(2) |
Ahora crearemos dos variables donde almacenaremos los valores que vamos a utilizar como referencia de segmentación:
1 2 |
azulBajo = np.array([90, 100, 20], np.uint8) azulAlto = np.array([120, 255, 255], np.uint8) |
Si observas estamos utilizando numpy a través de np
como lo importamos al inicio. Estos dos vectores de datos contienen los valores correspondientes en el Espacio de Color HSV (tinte, saturación, brillo). Sin entrar mucho en detalles de este espacio de color, nos ayuda mucho en el procesamiento de imágenes ya que podemos procesar los colores desde otras perspectiva. Para este ejemplo vamos a detectar una tapadera de garrafón de agua color azul, por lo que declaramos un nivel bajo y un nivel alto de tonos de azul de acuerdo con el espacio de color HSV mostrado en la siguiente imagen, puedes observar que los tonos azules van de un valor de entre 90 y 130. Puedes tomar de referencia la imagen para determinar los valores de H (el primer parámetro, y saturación y brillo los puedes dejar como te los muestro en el ejemplo)
Dentro del ciclo while tendremos el código que se ejecutará continuamente. Aquí vamos a describir la primer línea: ret, frame = cap.read()
con ella obtenemos dos variables ret y frame. En ret se almacena un true si se realizó una captura de manera correcta y frame es la imagen capturada por la webcam.
Posteriormente, si se realizó una captura correctamente procesamos imágenes, para esto sirve el if ret
Con frame = cv2.flip(frame, 1)
reflejamos la imagen para tener una perspectiva directa del movimiento.
Con frameHSV = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
convertimos del espacio de color BGR (blue, green, red que es el espacio de color en el que las imágenes se capturan), a HSV.
Ahora creamos una máscara mascara = cv2.inRange(frameHSV, azulBajo, azulAlto)
utilizando las variables azulBajo y azulAlto como los límites inferior y superior. Ahora necesitamos obtener los contornos de la máscara obtenida anteriormente para lo que utilizamos contornos, _ = cv2.findContours(mascara, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
guardando en la variable contornos
todos los encontrados de la variable mascara
.
Ahora los vamos a dibujar sobre la imagen original cv2.drawContours(frame, contornos, -1, (255, 0, 0), 4)
, para dibujarla utilizamos la función cv2.drawContours
además le agregamos el color que deseamos que utilice para destacar los contornos, en mi caso elegí un color azul muy marcado (255,0,0) recordando que OpenCV utiliza un formato (B,G,R).
Posteriormente, necesitamos verificar todos los contornos que obtuvimos de la imagen, revisar el área de cada contorno y encontrar el centroide. Para esto, primero iniciamos un bloque for y calculamos el área de cada contorno, si el área es mayor a 6000 píxeles entonces buscamos el centroide:
1 2 3 |
for c in contornos: area = cv2.contourArea(c) if area > 6000: |
Este tamaño de área tú lo configuras, en mi caso me dio buen resultado con 6000, pero puedes modificarlo de acuerdo a tu implementación. Recuerda que las condiciones de luz afectan mucho para la captura de imágenes, por lo que siempre es preferible estar bajo un ambiente de buena iluminación.
Ahora calculamos los momentos M = cv2.moments(c)
y revisamos que si el momento «m00» es igual a cero, lo igualamos a 1, ya que realizaremos una división y dividir entre 0 es infinito y luego aparecerá un error. En OpenCV podemos encontrar el punto central de un contorno o imagen binaria utilizando los momentos, luego lo aprovechamos para calcular las coordenadas x e y del punto central (centroide):
1 2 3 4 |
if M["m00"] == 0: M["m00"] = 1 x = int(M["m10"] / M["m00"]) y = int(M['m01'] / M['m00']) |
Realizando las divisiones anteriores encontramos entonces las coordenadas donde se encuentra el centroide. Ahora realizamos el dibujo de un círculo cv2.circle(frame, (x, y), 7, (0, 0, 255), -1)
dentro de la imagen original (frame) en las coordenadas x e y calculadas, de radio 7 y de color (0,0,255) que sería un rojo intenso, y el parámetro final es para indicarle el grosor, al utilizar -1 le indicamos que simplemente rellene el círculo.
Creamos la variable para utilizar la tipografía font = cv2.FONT_HERSHEY_SIMPLEX
y ahora insertamos un texto con las coordenadas cv2.putText(frame, '{},{}'.format(x, y), (x + 10, y), font, 1.2, (0, 0, 255), 2, cv2.LINE_AA)
justo en la coordenada (x+10, y), el resto de parámetros son para configurar la tipografía, tamaño y color.
Ahora creamos un nuevo contorno nuevoContorno = cv2.convexHull(c)
con esta función creamos un contorno de forma convexa, uniendo una serie de puntos para formar una figura, esto nos ayuda para el caso de que la figura o el contorno de la figura no sea muy regular, simplemente unirá los puntos para formar una figura cerrada. Y dibujamos el nuevo contorno cv2.drawContours(frame, [nuevoContorno], 0, (255, 0, 0), 3)
.
Ahora vamos a dividir nuestra imagen en rangos, para mi caso, la imagen que obtengo de mi webcam es de 1280×720, así que la dividí tomando solamente la componente en x, algo así:
Con esta referencia, dentro de un if comparé si la x estaba dentro de cierto rango, enviar por el puerto serie en formato de byte la palabra clave para el movimiento.
Editado el 25 de abril del 2021
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
if x < 200: print("Mover a la izquierda 100%") ser.write(b"izq1\n") elif 420 > x >= 200: print("Mover a la izquierda 60%") ser.write(b"izq2\n") elif 520 > x >= 420: print("Mover a la izquierda 30%") ser.write(b"izq3\n") # Mover al centro elif 520 <= x < 650: print("Mover al centro") ser.write(b"ctr\n") elif 650 <= x < 860: print("moviendo a la derecha 30%") ser.write(b"der3\n") elif 860 <= x < 1080: print("moviendo a la derecha 60%") ser.write(b"der2\n") elif x >= 1080: print("Moviendo a la derecha 100%") ser.write(b"der1\n") |
Los movimientos los configuré de manera que el Arduino pueda entender e interpretar en un equivalente en grados:
Comando | Grados |
izq1\n | 0 |
izq2\n | 30 |
izq3\n | 60 |
ctr\n | 90 |
der3\n | 120 |
der2\n | 150 |
der1\n | 180 |
Finalmente, mostramos la imagen en una ventana ya con todo dibujado, y comparamos si en el teclado presionamos la tecla s que se cierre la ventana y se detenga el código.
1 2 3 4 5 |
# cv2.imshow('mascaraAzul', mascara) cv2.imshow('frame', frame) if cv2.waitKey(1) & 0xFF == ord('s'): ser.close() break |
Por último –ahora si–liberamos la webcam y cerramos todas las ventanas
1 2 |
cap.release() cv2.destroyAllWindows() |
Código en Arduino para mover el servo
Ahora vamos al código que tenemos que cargar a la placa Arduino. Para este ejemplo básicamente se modificó el código que ya te mostré en este artículo. Utilizamos el pin 9 para controlar la posición del servo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
#include <Servo.h> Servo servo1; String entradaSerial = ""; // String para almacenar entrada bool entradaCompleta = false; // Indicar si el String está completo int pin = 9; // pin de conexión PWM al servo int pulsoMinimo = 580; // Duración en microsegundos del pulso para girar 0º int pulsoMaximo = 2500; // Duración en microsegundos del pulso para girar 180º int angulo = 0; // Variable para guardar el angulo que deseamos de giro void setup() { servo1.attach(pin, pulsoMinimo, pulsoMaximo); Serial.begin(9600); } void loop() { if (entradaCompleta) { if (entradaSerial == "izq1\n") { Serial.print("0 grados\n"); // Mandamos escribir el angulo deseado del giro. servo1.write(0); } else if (entradaSerial == "izq2\n") { Serial.print("30 grados\n"); // Mandamos escribir el angulo deseado del giro. servo1.write(30); } else if (entradaSerial == "izq3\n") { Serial.print("60 grados\n"); // Mandamos escribir el angulo deseado del giro. servo1.write(60); } else if (entradaSerial == "ctr\n") { Serial.print("Centro 90 grados\n"); // Mandamos escribir el angulo deseado del giro. servo1.write(90); } else if (entradaSerial == "der3\n") { Serial.print("120 grados\n"); // Mandamos escribir el angulo deseado del giro. servo1.write(120); } else if (entradaSerial == "der2\n") { Serial.print("150 grados\n"); // Mandamos escribir el angulo deseado del giro. servo1.write(150); } else if (entradaSerial == "der1\n") { Serial.print("180 grados\n"); // Mandamos escribir el angulo deseado del giro. servo1.write(180); } else { // Cualquier otro dato recibido Serial.println("El dato recibido es inválido!!"); } entradaSerial = ""; entradaCompleta = false; } } // Función que se activa al recibir algo por // el puerto serie, Interrupción del Puerto Serie. void serialEvent() { while (Serial.available()) { // Obtener bytes de entrada: char inChar = (char)Serial.read(); // Agregar al String de entrada: entradaSerial += inChar; // Para saber si el string está completo, se detendrá al recibir // el caracter de retorno de línea ENTER \n if (inChar == '\n') { entradaCompleta = true; } } } |
Como puedes observar, se ajustó para que la palabra recibida por el puerto serie se verifique y se compare de acuerdo a la tabla que te mostré anteriormente con la palabra y los grados (posición del servo).
¿Qué te ha parecido este artículo? ¿Para qué aplicación se te ocurre? Platícame en dónde lo quieres utilizar, recuerda que yo te muestro herramientas, diseño, algunos proyectos, pero sobre todo la imaginación es tu límite. Puedes utilizar este ejemplo para modificarlo a tu antojo y agregar más grados de libertad, o ejes de movimiento.
¡Hasta la próxima!
Recuerda visitar nuestras redes sociales
Abraham que tal. Me ha encantado tu video, muy explicativo y bastante fácil de digerir para los que estamos iniciando en la visión artificial. Y planeo usar este principio para mi proyecto de Robótica.
Tengo un problema con el sistema. Ambos códigos me corren bien, ninguno presenta errores y el de Python si hace las detecciones de mi objeto y su trayectoria, sin embargo por alguna razón el servomotor nunca se mueve. Ya probé con 3 diferentes y revise que no estuvieran descompuestos pero estos si funcionan, incluso use tu código del tutorial para controlar el servo con Arduino y funciono perfecto. Pero por alguna razón con este no se mueve. La placa Arduino parece que si recibe la señal ya que cuando la cámara detecta el objeto, el foco RX de la placa parpadea conforme muevo el objeto.
Revise los pines, cambie a otros, revise el COM y no encuentro cual podría ser el problema.
Se que mi descripción es muy vaga pero tienes alguna idea de cual podría ser el problema?
Hola Alan, me da gusto que te sirva el artículo. Al parecer el Arduino está recibiendo mensajes, pero no está activando la bandera de que el mensaje ya terminó de llegar, ¿qué caracter estás utilizando para detectar el fin de mensaje? en el código manejé \n podrías poner una parte del código para revisarlo o puedes escribirme a mi correo: contacto@automatizacionparatodos.com
Saludos!
Hola Alan, contesto tu comentario por aquí también. Ya he dado respuesta a tu pregunta directamente por correo, pero para las personas que lean este comentario, el error estaba en el código, ya está corregido. Gracias de nuevo por tu comentarios. Saludos!
Hola, gracias por este proyecto. Cuando intento instalar opencv con el comando que pusiste, me salta este error:
File «», line 1
pip install opencv-contrib-python
^
SyntaxError: invalid syntax
Lo mismo ocurre con estos comandos:
pip install numpy
pip install pyserial
He probado con la version 3.7 y 3.9 de python pero siempre obtengo el mismo error. Gracias.
Hola Ramón, los comandos de instalación se escriben en la terminal, si estás utilizando PyCharm, en la parte inferior tiene una pestaña de terminal, si no, necesitas abrir la ventana de comandos. En Windows se llama CMD y en MacOS se llama Terminal. Todos los comandos que inician con pip deberán ir en esa ventana. Quedo atento a tus comentarios. Saludos!
Muchas gracias, efectivamente utilizando la consola de windows pude instalar las librerías.
Otra consulta si no es molestia..
Seria posible utilizar este proyecto para controlar dos motores paso a paso y poder controlar un telescopio para que haga seguimiento automático de un avión o un satélite?
Excelente Ramón. Tu propuesta es muy interesante, si se podría utilizar. El mayor reto estaría en el tamaño del objeto con respecto a la imagen para que lo puedas segmentar correctamente, fuera de eso, el proceso es prácticamente igual. Saludos!
Gracias.. yo de phyton no tengo ni idea a la hora de programar.. si te pago lo que creas oportuno, podrías hacer el código?
Hola Ramón, escríbeme a contacto@automatizacionparatodos.com y platícame todos los detalles que quieres conseguir con tu proyecto y te voy platicando sobre en qué partes puedo apoyarte. Saludos!
Hola, excelente proyecto, tengo un problema al momento de capturar el video en vivo, se queda trabada la ventana de la cámara, que puedo hacer?
Hola Jos, no podría darte una respuesta con seguridad, tendrías que enviarme tu código para poder verlo para ver si es algo relacionado a algún error en el código, puedes escribirme a contacto@automatizacionparatodos.com
Hola un saludo, quisiera saber si tienes un tutorial como controlar un servo motor con Arduino e IA mediante el movimiento independiente de los dedos de la mano, ya que no poseo mucho conocimiento en Python y me queda un poco difícil, agradecería tu ayuda.
Hola estimado Miguel, aún no tengo un video como el que mencionas, pero lo tomaré en cuenta para un futuro video y con mucho gusto lo podré preparar. Muchas gracias! Saludos!
Hola excelente proyecto quisiera saber que estoy haciendo mal porque ya instale todas las librerias y el numero del puerto pero me sale este error
Traceback (most recent call last):
File «C:\Users\jooze\PycharmProjects\servodf\main.py», line 7, in
ser = serial.Serial(COM, BAUD)
File «C:\Users\jooze\PycharmProjects\servodf\venv\lib\site-packages\serial\serialwin32.py», line 33, in __init__
super(Serial, self).__init__(*args, **kwargs)
File «C:\Users\jooze\PycharmProjects\servodf\venv\lib\site-packages\serial\serialutil.py», line 222, in __init__
self.port = port
File «C:\Users\jooze\PycharmProjects\servodf\venv\lib\site-packages\serial\serialutil.py», line 268, in port
raise ValueError(‘»port» must be None or a string, not {}’.format(type(port)))
ValueError: «port» must be None or a string, not
Ya lo solucione cambiando la linea de código de
COM = ‘/dev/cu.usbserial-14120’
BAUD = 9600
ser = serial.Serial(COM, BAUD)
—> ser = serial.Serial(‘COM69’, 9600)
Por si alguien tiene ese error usando Windows
Muchas gracias por tu comentario, seguro que a alguien más le servirá. Cada computadora puede asignar el nombre distinto a cada puerto, es mejor revisar siempre el nombre que se le asigna.
Saludos!
Buenos días excelente tutorial, y muy bueno tu canal en youtube, hace poco empece, estoy tratando de mover dos servos con reconocimiento facial, pero siempre me manda el mismo error:
raise SerialException(«WriteFile failed ({!r})».format(ctypes.WinError()))
Hola Uriel, podrías enviarme tu código a mi correo para darle un vistazo ya que por el error creo que es por el formato con el que lo envías.
Saludos!
a mi me salio una ventana de
color naaranja
Hola super interesante y muy entendible tu video, te he dejado mensaje pues debo hacer algo similar y no logro hacerlo. Muchas gracias por tu video y espero tu respuesta. Saludos.
Hola Ana, dónde me dejaste el mensaje? ya que no me ha llegado. Si me escribes por el buzón de mensajes, asegúrate de dejarme tu correo. Saludos!
excelente tutorial, muy bien explicado… solo un problema con la comunicación serial, el servomotor no se movia y tuve modificar la programación de arduino.
consulta… respecto del eje y y querer mover un segundo servo. ¿que tanto se tendria que modificar la programacion de python ?
Hola Edzul, gracias por tu comentario. Para agregar un segundo servomotor, puedes usar las coordenadas en el eje y, las cuales ya también están disponibles con el código actual. Solamente sería agregar los if’s necesarios tanto en el código de pyhton como en arduino. Pronto haré un video de esto. Saludos!
Hola, hace unas semanas que ví tu vídeo y me pareció muy interesante, ya que tengo como proyecto el mover una «CNC» de dos ejes usando motores a pasos en vez de servos, el punto es que cuando yo envío datos de python a los pines de Arduino el puerto serial Lee los datos pero no se mueve el eje de los motores, cabe mencionar que estoy usando el mismo programa de python que realizaste, con la diferencia de que muevo motores a pasos en vez de servos, espero puedas ayudarme y agradezco de antemano.
PD: sigue subiendo este tipo de contenido, ayuda muchísimo, gracias!
Hola Oscar, muchas gracias por tu comentario. Lo que puedo pensar es que puedes probar tu código en Arduino de manera local (enviando los comandos por el monitor serie)con esto revisarías si está funcionando correctamente, puede ser que no le estén llegando los mensajes correctamente.
Saludos!
que cambios se podrian hacer al codigo para poder controlar un stepper
Buenas hermano, el proyecto me funciona el servo se mueve cada vez que le pongo un objeto, pero al momento de colocarlo el programa se traba, se bugea y el servo no se mueve, hay que colocar el objeto rápido y quitarlo para que el servo se mueva, no sé qué podria hacer ¿ podrías ayudarme ?
Hola Buenas tardes Dairon, es complicado poder ayudarte sin ver alguna pantalla del error que te lanza la consola, ¿podrías compartirnos una imagen? Saludos!
Excelente articulo, podrias enviarme el codigo para que la placa arduino lea el serial y mueva el servo?
Muchas gracias
Hola Gustavo, muchas gracias por tu comentario. El código completo está en este mismo artículo, tanto para el Arduino como para la computadora en Python. Sigo atento.