¿Como Mover tu Brazo Robotico 6s Kimo con Control Remoto?
Explora el emocionante mundo de la robótica con nuestra guía en línea. Aprende a controlar con precisión tu Brazo Robótico Kimo 6s utilizando un control infrarrojo y su módulo IR Remote. Te acompañaremos paso a paso en este fascinante proceso, asegurándonos de que domines cada detalle para sacar el máximo provecho de tu brazo robótico.
Materiales Necesarios:
Pasos a Seguir:
Primero debes realizar la siguiente conexión electrónica, se mostrara el esquema en Arduino UNO pero la conexión en expansión de Arduino Nano es la misma, si deseas descargar el esquema solo debes dar clic en la imagen del esquema:
2. Ahora debes cargar los códigos a tu Arduino, si no sabes como cargar códigos a tu Arduino a continuación puedes aprender como: APRENDER
Librerías Necesarias:
El desarrollo de proyectos de robótica y automatización con Arduino requiere del uso de ciertas librerías especializadas que facilitan la programación y control de dispositivos. Algunas de las librerías necesarias en este proyecto son:
- IRremote: Esta librería permite la recepción y decodificación de señales infrarrojas, lo cual es fundamental para interactuar con controles remotos infrarrojos y otros dispositivos de entrada. Descárgala AQUI
- Servo: La librería Servo simplifica el control de servomotores, permitiendo configurar y mover los servomotores con facilidad mediante el protocolo PWM (modulación por ancho de pulso).
Código Completo:
Primero te mostraremos el código completo y luego procederemos a explicar paso a paso.
/*Movimiento Brazo Robotico con Monitor Serial Desarrollado por RDC - Robotica de Colombia Visitanos: www.facebook.com/roboticadecolombia www.youtube.com/@RoboticadeColombia www.instagram.com/roboticadecolombia/ Mercadolibre: www.mercadolibre.com.co/perfil/ROBOTICADECOLOMBIA */ #include <IRremote.h> #include <Servo.h> Servo rotacion; Servo Hombro1; Servo Hombro2; Servo Codo; Servo muneca; Servo Garra; int angulorotacion = 90; int angulohombro1 = 50; int angulohombro2 = 130; int angulocodo = 180; int angulomuneca = 40; int angulogarra = 20; int RECV_PIN = 3; int STATUS_PIN = 13; IRrecv irrecv(RECV_PIN); IRsend irsend; decode_results results; void setup() { Serial.begin(115200); Serial.println("Iniciando... "); irrecv.enableIRIn(); // Iniciar el receptor pinMode(STATUS_PIN, OUTPUT); rotacion.attach(2); Hombro1.attach(4); Hombro2.attach(5); Codo.attach(6); muneca.attach(7); Garra.attach(8); rotacion.write(angulorotacion); Hombro1.write(angulohombro1); Hombro2.write(angulohombro2); Codo.write(angulocodo); muneca.write(angulomuneca); Garra.write(angulogarra); delay(500); } void moverServoSuavemente(Servo& servo, int anguloInicio, int anguloFin, int tiempoTotal) { int pasos = 20; // número de pasos para la rampa int incremento = (anguloFin - anguloInicio) / pasos; int delayTiempo = tiempoTotal / pasos; for (int i = 0; i <= pasos; i++) { servo.write(anguloInicio + incremento * i); delay(delayTiempo); } } // Almacenamiento para el código grabado int codeType = -1; // El tipo de código unsigned long codeValue; // El valor del código si no es crudo unsigned int rawCodes[RAWBUF]; // Las duraciones si es crudo int codeLen; // La longitud del código // Almacena el código para su reproducción posterior void storeCode(decode_results* results) { codeType = results->decode_type; int count = results->rawlen; if (codeType == UNKNOWN) { codeLen = results->rawlen - 1; for (int i = 1; i <= codeLen; i++) { if (i % 2) { rawCodes[i - 1] = results->rawbuf[i] * USECPERTICK - MARK_EXCESS; } else { rawCodes[i - 1] = results->rawbuf[i] * USECPERTICK + MARK_EXCESS; } } } else { if (codeType == NEC) { if (results->value == REPEAT) { return; } } Serial.print("NEC recibido: "); Serial.println(results->value, HEX); codeValue = results->value; codeLen = results->bits; } } void sendCode(int repeat) { if (codeType == NEC) { if (repeat) { irsend.sendNEC(REPEAT, codeLen); } else { irsend.sendNEC(codeValue, codeLen); } } else if (codeType == UNKNOWN /* es decir, crudo */) { irsend.sendRaw(rawCodes, codeLen, 38); Serial.println("Crudo enviado"); } } void loop() { // Si se recibe un código IR if (irrecv.decode(&results)) { digitalWrite(STATUS_PIN, HIGH); storeCode(&results); switch (results.value) { case 0xFFA25D: Serial.println("Tecla 1"); angulocodo -= 10; Codo.write(angulocodo); break; case 0xFF629D: Serial.println("Tecla 2"); angulomuneca -= 10; muneca.write(angulomuneca); break; case 0xFFE21D: Serial.println("Tecla 3"); angulogarra = 50; Garra.write(angulogarra); break; case 0xFF22DD: Serial.println("Tecla 4"); angulocodo += 10; Codo.write(angulocodo); break; case 0xFF02FD: Serial.println("Tecla 5"); angulomuneca += 10; muneca.write(angulomuneca); break; case 0xFFC23D: Serial.println("Tecla 6"); angulogarra = 20; Garra.write(angulogarra); break; case 0xFFE01F: moverServoSuavemente(rotacion, rotacion.read(), 0, 300); moverServoSuavemente(Hombro1, Hombro1.read(), 130, 300); moverServoSuavemente(Hombro2, Hombro2.read(), 50, 300); moverServoSuavemente(Codo, Codo.read(), 140, 300); moverServoSuavemente(muneca, muneca.read(), 0, 300); Garra.write(20); delay(300); // Pequeño retraso para el efecto visual Garra.write(50); delay(500); // Pequeño retraso para el efecto visual moverServoSuavemente(rotacion, rotacion.read(), 180, 300); moverServoSuavemente(Hombro1, Hombro1.read(), 50, 300); moverServoSuavemente(Hombro2, Hombro2.read(), 130, 300); moverServoSuavemente(Codo, Codo.read(), 150, 300); moverServoSuavemente(muneca, muneca.read(), 0, 300); delay(300); // Pequeño retraso para el efecto visual Garra.write(20); delay(500); // Pequeño retraso para el efecto visual moverServoSuavemente(rotacion, rotacion.read(), 90, 300); moverServoSuavemente(Hombro1, Hombro1.read(), 50, 300); moverServoSuavemente(Hombro2, Hombro2.read(), 130, 300); moverServoSuavemente(Codo, Codo.read(), 180, 300); moverServoSuavemente(muneca, muneca.read(), 40, 300); moverServoSuavemente(Garra, Garra.read(), 20, 300); break; case 0xFFA857: Serial.println("Tecla 8"); break; case 0xFF906F: Serial.println("Tecla 9"); break; case 0xFF6897: Serial.println("Tecla *"); break; case 0xFF9867: Serial.println("Tecla 0"); break; case 0xFFB04F: Serial.println("Tecla #"); break; case 0xFF18E7: Serial.println("Tecla arriba"); angulohombro1 += 10; angulohombro2 -= 10; Hombro1.write(angulohombro1); Hombro2.write(angulohombro2); break; case 0xFF10EF: Serial.println("Tecla izquierda"); angulorotacion += 10; rotacion.write(angulorotacion); break; case 0xFF5AA5: Serial.println("Tecla derecha"); angulorotacion -= 10; rotacion.write(angulorotacion); break; case 0xFF4AB5: Serial.println("Tecla abajo"); angulohombro1 -= 10; angulohombro2 += 10; Hombro1.write(angulohombro1); Hombro2.write(angulohombro2); break; case 0xFF38C7: Serial.println("Tecla ok"); rotacion.write(90); Hombro1.write(90); Hombro2.write(90); Codo.write(180); muneca.write(40); Garra.write(20); break; default: break; } irrecv.resume(); digitalWrite(STATUS_PIN, LOW); } }
Si deseas descargar el código anterior, lo encuentras AQUI:
Explicación Código:
a. Importación de Librerías:
#include <IRremote.h> //libreria IRRemote con la cual entenderemos las señales del control inflarrojo #include <Servo.h> //Libreria Servomotor con la cual controlaremos nuestro servomotor
Se importan las librerías necesarias para el funcionamiento del código. IRremote.h
para el control remoto infrarrojo y Servo.h
para controlar los servomotores.
b. Declaración de Objetos y Variables
Servo rotacion, Hombro1, Hombro2, Codo, muneca, Garra; int angulorotacion = 90, angulohombro1 = 50, angulohombro2 = 130; int angulocodo = 180, angulomuneca = 40, angulogarra = 20; int RECV_PIN = 3, STATUS_PIN = 13; IRrecv irrecv(RECV_PIN); IRsend irsend; decode_results results;
Se declaran los objetos de tipo Servo
para cada parte del brazo robótico y se inicializan los ángulos. También se declaran pines para el receptor infrarrojo y un LED indicador. Se crean objetos IRrecv
y IRsend
para manejar el receptor y emisor infrarrojo.
c. Definición del pin de recepción IR:
int RECV_PIN = 3; // Pin al cual conectaremos el Pin Señal de nuestro modulo AX-1838HS
Se define la variable RECV_PIN
para almacenar el número de pin al cual está conectado el receptor infrarrojo.
d. Inicialización del receptor IR:
IRrecv irrecv(RECV_PIN);
Se crea un objeto IRrecv
que se encargará de recibir las señales infrarrojas en el pin definido anteriormente.
e. Definición de la variable para almacenar los resultados:
decode_results results; // Nombre en donde decodificará los valores
Se define la variable results
del tipo decode_results
, que se utilizará para almacenar los datos decodificados de las señales infrarrojas recibidas.
f. Definición de los ángulos iniciales de los servomotores:
int angulocadera = 90; // Nuestro servomotor iniciará siempre en 90º int angulohombro1 = 90; // Nuestro servomotor iniciará siempre en 90º int angulohombro2 = 90; // Nuestro servomotor iniciará siempre en 90º int angulocodo = 0; // Nuestro servomotor iniciará siempre en 75º int angulomuneca = 70; // Nuestro servomotor iniciará siempre en 50º int angulogarra = 180; // Nuestro servomotor iniciará siempre en 50º
Se definen las variables para almacenar los ángulos iniciales de cada servomotor. Estos ángulos se utilizarán como posiciones de inicio para cada servomotor.
g. Funición setup():
void setup() { Serial.begin(115200); Serial.println("Iniciando... "); irrecv.enableIRIn(); // Iniciar el receptor pinMode(STATUS_PIN, OUTPUT); rotacion.attach(2); Hombro1.attach(4); Hombro2.attach(5); Codo.attach(6); muneca.attach(7); Garra.attach(8); rotacion.write(angulorotacion); Hombro1.write(angulohombro1); Hombro2.write(angulohombro2); Codo.write(angulocodo); muneca.write(angulomuneca); Garra.write(angulogarra); delay(500); }
Se establecen las configuraciones iniciales en el método setup()
. Se adjuntan los servomotores a los pines correspondientes, se habilita la recepción de señales infrarrojas y se inicia la comunicación serial.
h. Función loop(), Bucle Principal:
void loop() { if (irrecv.decode(&results)) { // Se verifica si hay una señal infrarroja recibida Serial.println(results.value, HEX); // Se imprime el valor recibido en hexadecimal por el control infrarrojo // Se utiliza una estructura switch-case para manejar diferentes valores recibidos switch(results.value){ case 0xFF5AA5: // Si se recibe este valor, se incrementa el ángulo de la cadera angulocadera += 10; break; // Otros casos similares para diferentes direcciones y movimientos del brazo // (izquierda, arriba, abajo, etc.) case 0xFF38C7: // Si se recibe este valor, se restablecen los ángulos a sus valores iniciales angulocadera = 90; angulohombro1 = 90; angulohombro2 = 90; angulocodo = 140; angulomuneca = 140; angulogarra = 70; break; } // Se aplican restricciones a los ángulos para asegurar que estén dentro de los límites deseados angulocodo = constrain(angulocodo, 0, 170); angulohombro1 = constrain(angulohombro1, 0, 170); angulohombro2 = constrain(angulohombro2, 0, 170); angulocadera = constrain(angulocadera, 0, 170); angulomuneca = constrain(angulomuneca, 0, 170); // Se escriben los ángulos en los servomotores correspondientes para controlar el brazo cadera.write(angulocadera); hombro1.write(angulohombro1); hombro2.write(angulohombro2); codo.write(angulocodo); muneca.write(angulomuneca); garra.write(angulogarra); irrecv.resume(); // Se reinicia la recepción de señales infrarrojas para esperar la próxima delay(10); // Se espera un breve tiempo antes de continuar para evitar lecturas erróneas } }
La función loop()
es el corazón del programa y se ejecuta continuamente después de que setup()
haya completado su ejecución. En este caso:
3. Ahora solo debes enviar a través de tu control remoto a tu nuevo Brazo Robótico, a continuación te dejamos una imagen que ilustra los comandos y que rol cumplen.
4. Si seguiste los pasos al pie de la letra deberás tener tu Brazo Robótico totalmente funcional con control remoto, ya solo queda que añadas a los códigos faltantes espectaculares secuencias.
1 thoughts on “¿Como Mover tu Brazo Robotico 6s Kimo con Control Remoto?”
Excelente guía.