Construye tu Propio Robot Asistente IA con Arduino y Python
Componentes y suministros
| Arduino Nano R3 | × | 1 | |
| Micro-servomotor SG90 | × | 1 | |
| Sensor Ultrasónico HC-SR04 (Genérico) | × | 1 | |
| PCB Personalizado PCBWay | × | 1 | https://www.pcbway.com/project/shareproject/Multi_functional_Robot_PCB__Mofiza_.html |
Aplicaciones y servicios online
- Arduino IDE
Sobre este proyecto
Introducción:
Todos estamos familiarizados con 'Jarvis', el robot asistente IA de las películas de "Iron Man" y series de Marvel. Siempre ha sido el sueño de los programadores crear algo propio. Hoy mostraré una forma sencilla de hacer un asistente así usando programación Python. Además, también haré un avatar físico de ese robot, para que cuando hablemos con él, pueda hacer algunos movimientos. Eso será más increíble que solo un robot de software. ¡Porque si tiene cuerpo, es genial! Así que hoy aprenderemos a usar tanto Arduino como Python para hacer un robot IA que pueda controlar tu computadora y charlar un poco contigo. ¡Vamos!
¿Por qué llamé al robot 'Jaundice'? ¡Porque lo pinté amarillo, muy muy amarillo!
Partes:
Electrónica -
- Arduino Nano – 1x
- Micro Servo SG90 – 3x
- Sensor Ultrasónico HC-SR04 – 1x
Cuerpo –
- Lámina PVC (preferiblemente blanca, mejor para colorear, usé una azul)
- Rueda de servo (para el soporte)
Herramientas:
- Cúter
- Tijeras
- Pegamento caliente
- Pintura en spray
Software -
- Python 3
- Arduino IDE
Principio:
Antes de entrar en la construcción, es genial tener una idea de lo que haremos.
El código principal o parte de IA correrá en la computadora, ¿por qué? Porque soporta Python y tiene más potencia de procesamiento que el pequeño Arduino. Además, como el bot IA controlará/automatizará algunas tareas de mi PC, tiene que correr en mi PC. La placa Arduino está conectada a mi computadora mediante cable USB.
La idea es ejecutar un programa Python que hará la parte de Voz a Texto, procesará el texto y también hará Texto a Voz. O sea, el robot escuchará, entenderá y responderá. Para el movimiento del cuerpo guardé algunos movimientos (encapsulados en funciones) en la placa Arduino. La función para cada movimiento es ejecutada por el código Python.
Como ejemplo: si el robot tiene que decir 'Hola', el código Python enviará un byte 'h', Arduino ejecutará la función hi(). Tan simple como eso.
Ahora que tienes una idea, pasemos al siguiente proceso.
Circuitos y electrónica
Los circuitos son lo que más fastidia a los makers. Si algo sale mal, puedes quemar piezas caras. Por eso diseñé una placa PCB que puede usarse para numerosos proyectos. Tiene ranura para micro SD, ranura para módulo Bluetooth, fuente de alimentación externa 5V y todo alimentado por Arduino Nano.
Diseñé un PCB usando EasyEDA e imprimí usando el servicio online PCBWay. Su servicio es increíble. Pedí usando cotización instantánea PCBWay y su sistema hizo todo automáticamente. En 3 días recibí la placa desde China a Bangladesh. La calidad es fantástica, el enmascarado de soldadura perfecto y las pistas/acabado tan bueno como podría ser.
De todos modos, usé pistas de 300mm ya que pueden soportar 1Amp de corriente.
Puedes descargar los archivos PCB aquí.
Soldar cosas y probar circuito:
En este paso soldé todo. Ten mucho cuidado de no inhalar los humos, pueden causar cáncer.
No uso módulo Bluetooth ni TF, así que los dejé sin soldar. Lo bueno es que usé 3 servomotores y un sensor sonar, todo se alimenta fácilmente desde el cable USB que conectamos para programar el Arduino. Esto es genial porque no tenemos que pensar en otra fuente de alimentación.
Sin embargo, si aún quieres usar baterías externas, ve por lipo 2s (7.4V), más que eso y el servo se quema.
Hacer el cuerpo:
Usé lámina PVC para hacer el cuerpo, también puedes usar cartón. Primero hice una caja para la parte principal, ahí va la placa principal y servomotores. Es como hacer cajas. Hice la cabeza de la misma forma, hice dos agujeros para el sensor (como ojos). Añadí todas las fotos que necesitas. Hice una mano como llave inglesa y otra como enchufe. En realidad usé un enchufe y lo añadí a un brazo con pegamento caliente.
¿Dimensiones? En realidad no hay, ¡es tu robot! Puedes hacerlo con herramientas fáciles, hazlo como quieras, de cualquier forma y tamaño.
Ten mucho cuidado de añadir toda la electrónica antes de cerrar el cuerpo. Pinté el cuerpo después de poner sensores y toda la electrónica. No hagas eso, ya coloreé mi Arduino de amarillo.
Así que pinta después de terminar el cuerpo, luego pon toda la electrónica.
Codificación 1 (Python):
Descarga Python de este sitio, asegúrate de añadir Python a tu PATH al instalar.
Después de instalar Python necesitarás ejecutar algunos comandos desde símbolo del sistema/terminal para instalar librerías para Reconocimiento de Voz, Soporte de Audio, Texto a Voz, Automatización de Navegador, Comunicación Serial. Ejecuta estos comandos:
pip install speechrecognition
pip install pyaudio
pip install pyttsx3
pip install pywhatkit
pip install pyserial
Luego descarga el código Python aquí o copia de abajo. Ve al paso de codificación 2.
""" JAUNDICE: Robot Asistente IA con Arduino y Python
autor: ashraf minhaj
mail: ashraf_minhaj@yahoo.com
Última edición: Nov 2020
Licencia: Copyright (C) Ashraf Minhaj. Licencia Pública General (GPL3+) """
import speech_recognition as sr # librería reconocimiento de voz
import random # para elegir palabras aleatorias de lista
import pyttsx3 # Texto a Voz offline
import datetime # para obtener fecha y hora
import webbrowser # para abrir y realizar tareas web
import serial # para comunicación serial
import pywhatkit # para más automatización web
# Declarar nombre del robot (Palabra de activación)
robot_name = 'jaundice'
# listas de palabras aleatorias
hi_words = ['hi', 'hello', 'yo baby', 'salam']
bye_words = ['bye', 'tata', 'hasta la vista']
r_u_there = ['are you there', 'you there']
# inicializar cosas
engine = pyttsx3.init() # inicializar motor texto a voz
# voices = engine.getProperty('voices') # comprobar voces
# engine.setProperty('voice', voices[1].id) # voz femenina
listener = sr.Recognizer() # inicializar API reconocimiento de voz
# conectar con placa controladora NiNi por comunicación serial
try:
port = serial.Serial("COM15", 9600)
print("Cuerpo físico, conectado.")
except:
print("No se puede conectar a mi cuerpo físico")
def listen():
""" escuchar lo que dice el usuario """
try:
with sr.Microphone() as source:
# obtener entrada del micrófono
print("Habla>>")
voice = listener.listen(source) # escuchar del micrófono
command = listener.recognize_google(voice).lower() # usar API Google
# todas las palabras minúsculas - para procesar fácilmente
print(command)
# buscar palabra de activación al principio
if (command.split(' ')[0] == robot_name):
# si palabra de activación encontrada....
print("[palabra de activación encontrada]")
process(command) # llamar función process para actuar
except:
pass
def process(words):
""" procesar lo que dice el usuario y actuar """
print(words)
# comprobar si recibió algún comando
# dividir palabras en
word_list = words.split(' ')[1:] # dividir por espacio e ignorar palabra activación
if (len(word_list)==1):
if (word_list[0] == robot_name):
talk("¿Cómo puedo ayudarte?")
#.write(b'l')
return
if word_list[0] == 'play':
""" si comando para reproducir cosas, reproducir de youtube """
talk("OK jefe, reproduciendo")
extension = ' '.join(word_list[1:]) # buscar sin la palabra comando
port.write(b'u')
pywhatkit.playonyt(extension)
port.write(b'l')
return
elif word_list[0] == 'search':
""" si comando para búsqueda en Google """
port.write(b'u')
talk("OK jefe, buscando")
port.write(b'l')
extension = ' '.join(word_list[1:])
pywhatkit.search(extension)
return
if (word_list[0] == 'get') and (word_list[1] == 'info'):
""" si comando para obtener info """
port.write(b'u')
talk("OK, voy allá")
port.write(b'u')
extension = ' '.join(word_list[2:]) # buscar sin palabras comando
inf = pywhatkit.info(extension)
talk(inf) # leer resultado
return
elif word_list[0] == 'open':
""" si comando para abrir URLs """
port.write(b'l')
talk("Abriendo, señor")
url = f"https://{''.join(word_list[1:])}" # crear URL
webbrowser.open(url)
return
elif word_list[0] == 'uppercut':
port.write(b'U')
elif word_list[0] == 'smash':
port.write(b's')
elif word_list[0] == 'punch':
port.write(b'p')
# ahora comprobar coincidencias
for word in word_list:
if word in hi_words:
""" si usuario dice hola/saludos, saludar entsprechend """
port.write(b'h') # enviar comando para saludar con mano
talk(random.choice(hi_words))
elif word in bye_words:
""" si usuario dice adiós etc """
talk(random.choice(bye_words))
def talk(sentence):
""" hablar / responder al usuario """
engine.say(sentence)
engine.runAndWait()
# ejecutar la app
while True:
listen() # ejecuta listen una vez
Codificación 2 (Arduino):
Esta parte es fácil, nada que instalar. Usa Arduino IDE para programar la placa. Descarga aquí si nunca has usado Arduino.
Como mencioné antes, el programa Arduino espera datos seriales, si recibe alguno comprueba el byte. Si el dato coincide con un comando predefinido, ejecuta una sentencia. Si se envía 'u', sube ambas manos, etc.
Descarga el código aquí o copia de abajo.
/** JAUNDICE: Robot Asistente IA con Arduino y Python **
*
* autor: ashraf minhaj
* mail: ashraf_minhaj@yahoo.com
* Última edición: Nov 2020
*
* Licencia: Copyright (C) Ashraf Minhaj.
* Licencia Pública General (GPL3+) */
#include <Servo.h>
Servo head;
Servo l_hand;
Servo r_hand;
// definir pines del sensor sonar
int trig = 4;
int echo = 5;
// dato recibido
byte val = "";
void setup() {
// código de configuración, ejecutar una vez:
head.attach(2);
l_hand.attach(3);
r_hand.attach(4);
Serial.begin(9600); // para comunicar via puerto serial con Python
}
void standby(){
// todos los motores a estas posiciones
head.write(90);
int r_pos = 30;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
}
void hi(){
// todos los motores a estas posiciones
head.write(90);
int i = 0;
for(i=30; i<= 170; i++){
r_hand.write(i);
delay(5);
}
for(i=170; i>= 100; i--){
r_hand.write(i);
delay(5);
}
for(i=100; i<= 170; i++){
r_hand.write(i);
delay(5);
}
for(i=170; i>= 30; i--){
r_hand.write(i);
delay(5);
}
standby();
}
void hands_up(){
// hacer esto en cada comando (nada mucho, solo mover manos un poco)
//head.write(150);
//delay(300);
//head.write(90);
int i = 0;
for(i=30; i<= 170; i++){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(5);
}
delay(600);
for(i=170; i>= 30; i--){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(5);
}
}
void weight_lift(){
// levantar peso con ambas manos
int i = 0;
for(i=30; i<= 170; i++){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(5);
}
for(int count=0; count<=4; count++){
for(i=170; i>= 60; i--){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(5);
}
for(i=60; i<= 170; i++){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(5);
}
}
for(i=170; i>= 30; i--){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(5);
}
}
void excited(){
return;
}
void look_left(){
// girar cabeza a la izquierda
head.write(180);
}
void confused(){
for(int count=0; count<=1; count++){
head.write(30);
r_hand.write(170);
delay(700);
r_hand.write(30);
head.write(120);
l_hand.write(30);
delay(700);
l_hand.write(160);
}
standby();
}
void double_punch(){
// dar un puñetazo
int i = 0;
for(i=30; i>= 0; i--){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(5);
}
delay(2000);
int r_pos = 80;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(500);
standby();
}
void r_upper_cut(){
// hacer uppercut derecho
int i = 0;
for(i=30; i<= 170; i++){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(5);
}
for(int count=0; count<=4; count++){
int i = 0;
for(i=170; i>= 60; i--){
r_hand.write(i);
delay(1);
}
for(i=60; i<= 170; i++){
r_hand.write(i);
delay(1);
}
}
standby();
delay(100);
}
void smash(){
// aplastar cosas
int i = 0;
for(i=30; i<= 170; i++){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(5);
}
delay(2000);
for(i=170; i>= 0; i--){
int r_pos = i;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(1);
}
delay(300);
int r_pos = 180;
int l_pos = map(r_pos, 0, 180, 180, 0);
l_hand.write(l_pos);
r_hand.write(r_pos);
delay(1000);
standby();
}
void eye_detect(){
// hacer algo si sensor ocular detecta movimiento
return;
}
void loop() {
// código principal, ejecutar repetidamente:
standby();
while(Serial.available() > 0) // buscar datos seriales disponibles
{
val = Serial.read(); // leer valor serial
if(val == 'h'){
// hacer hi
hi();
}
if(val == 'p'){
// hacer hi
double_punch();
}
if(val == 'u'){
hands_up();
delay(3000);
}
if(val == 'l'){
standby();
look_left();
delay(2000);
}
if(val == 'U'){
// uppercut
r_upper_cut();
delay(2000);
}
if(val == 's'){
smash();
delay(2000);
}
}
}
Sube el código.
Unir todo y listo:
Después de completar todos esos pasos conecté mi Arduino a la PC usando el cable USB y ejecuté el programa Python. Mientras lo uses asegúrate de poner el puerto correcto del Arduino en el código Python. Si hiciste todo como mencioné, el bot debería funcionar como un encanto.
¡Gracias!
Código
Código Fuente
https://github.com/ashraf-minhaj/JAUNDICE-AI-Assistant-Robot
Esquemáticos
Proceso de manufactura
- Construya un robot con Raspberry Pi y Python: Guía completa
- Construya un robot con streaming de vídeo controlado por Internet con Arduino y Raspberry Pi
- Sistema de Asistencia RFID Fiable con Arduino y Python
- Robot evasor de obstáculos con servo: Construcción con Arduino y HC-SR04
- Controla tu Roomba Create 2 con Arduino y Android: Guía Completa
- Control Preciso de Servo con Arduino y MPU6050 (SG90 / MG996R)
- Módulo GPS u-blox LEA‑6H 02: Guía de integración con Arduino y Python
- Dominando reconocimiento y síntesis de voz en Arduino Due
- Robot Asistente Doméstico Autónomo "O'nine" – Integración ROS, Alexa y Brazo Robótico
- Controla tu brazo robótico Arduino con app Android dedicada
- Entendiendo type() e isinstance() en Python: ejemplos prácticos