Brazo robótico: Servo motores

Después de haber montado las pieza que hemos imprimido en 3D de nuestro brazo robótico, vamos a aprender qué son los servomotores, y a controlarlos con una placa de Arduino.

  1. Servomotores
    1. Servomotor 9g SG 90 de Tower Pro
  2. Práctica 1: Movimiento secuencial directo
    1. Control con Tinkercad
    2. Control con Arduino IDE
    3. Control con ArduinoBlocks
  3. Práctica 2: Movimiento con monitor serie
    1. Comunicación de Arduino con Puerto serie
    2. Control con Tinkercad
    3. Control con Arduino IDE
  4. Práctica 3: Movimiento secuencial «while» (1 servo)
    1. Control con Tinkercad
  5. Práctica 4: Movimiento secuencial directo (4 servos)
  6. Práctica 5: Movimiento secuencial while (4 servos)
  7. Práctica 6: Control con pulsadores
    1. Botón pulsador
  8. Práctica 7: Control con potenciómetros
  9. Práctica 8: Guardar posiciones
  10. Práctica 9: Movimiento por sensor de ultrasonido
  11. Práctica 10: Movimiento por joystick
    1. Mejoras al código
    2. Código completo

Servomotores

La mejor manera para implementar articulaciones de rotación en robótica educativa, es utilizar Servomotores de modelismo, conocidos coloquialmente como Servos.

Hay servos de todos los tamaños y gustos. Estos son algunos de los servos más utilizados: El Futaba 3003 o compatible, y los micro-servos Tower-Pro SG90 y Emax ES08A.

A diferencia de otros tipos de motores en los que controlamos la velocidad de giro, en un servo indicamos directamente el ángulo deseado y el servo se encarga de posicionares en este ángulo.

Típicamente los servos disponen de un rango de movimiento de entre 0º a 180º. Es decir, no son capaces de dar la vuelta por completo (de hecho disponen de topes internos que limitan el rango de movimiento).

Internamente un servo frecuentemente consta de un mecanismo reductor:

En este video se explica muy bien, puedes verlo con subtítulos en español:


Por tanto proporcionan un alto par y un alto grado de precisión (incluso décimas de grado). Por contra, las velocidades de giro son pequeñas frente a los motores de corriente continua.

Los servos se admiten una tensión de alimentación entre 4,8V a 7,2V, siendo el valor más adecuado es 6V. Con tensiones inferiores el motor tiene menos fuerza y velocidad. Con tensiones superiores a 6,5V los servos empiezan a oscilar demasiado, lo cual los hace poco útiles.

Se usan para abrir y cerrar pinzasorientar sensores, o mover articulaciones. Están formados por tres partes: cuerpocabeza (o Corona) y cable de conexión.

Fuente

El cuerpo es la parte más grande, que alberga en su interior el motor, la electrónica y los engranajes. La cabeza es la pieza que va atornillada al eje de salida, y que es la que gira con respecto al cuerpo. En inglés se llama horn (cuerno). El cable está formado por tres hilos de colores que terminan en un conector hembra.

Frecuentemente simplemente se dispone de un potenciómetro unido al eje del servo, que permite al servo para conocer la posición del eje. Esta información es tratada por un controlador integrado que se encarga de ajustar actuar sobre el motor para alcanzar la posición deseada.

La comunicación de la posición deseada se realiza mediante la transmisión de un señal pulsada con periodo de 20ms. El ancho del pulso determina la posición del servo.

La relación entre el ancho del pulso y el ángulo depende del modelo del motor. Por ejemplo, algunos modelos responden con 0º a un pulso de 500 ms, y otros a un pulso de 1000 ms

En general, en todos los modelos:

  • Un pulso entre 500-1000 us corresponde con 0º
  • Un pulso de 1500 ms corresponde con 90º (punto neutro)
  • Un pulso entre 2000-2500us corresponde con 180º

Por tanto, variando la señal en microsegundos podemos disponer de una precisión teórica de 0.18-0.36º, siempre que la mecánica del servo acompañe.

Servomotor 9g SG 90 de Tower Pro

Esta es la hoja de características del fabricante:

Aunque el servo puede moverse con una resolución de más de 1 grado, este es el máximo de resolución que vamos a conseguir debido a la limitación de la señal PWM que es capaz de generar Arduino UNO.

Estos motores funcionan con una señal PWM, con un pulso de trabajo entre 1 ms y 2 ms y con un periodo de 20 ms (50 Hz). ¿Qué quiere decir todo esto? Este dato nos indica la velocidad máxima a la que podemos mover el servomotor con Arduino. Solo podremos cambiar de posición cada 20 ms. Esto dependerá del tipo y marca de nuestro servo.

El elegir una salida PWM u otra da lo mismo, todas las salidas de este tipo funcionan igual.

Práctica 1: Movimiento secuencial directo

Para simular el funcionamiento se pueden emplear distintas aplicaciones: Tinkercad, IDE de Arduino y ArduinoBlocks.

Control con Tinkercad

1. Lo primero que tienes que hacer es entrar en Tinkercad con el código que te ha dado el profesor para tu clase.

2. Ahora vete a Diseños (1), pulsa en Crear (2), y luego en Circuito (3):

3. Lo primero que hacemos al crear un nuevo diseño es nombrarlo para que sea reconocible en Tus Diseños. Cambia el nombre que venga por «Control servomotor» y luego tu nombre e iniciales de los apellidos:

4. Vamos a situar todos los componentes necesarios para el proyecto en el Plano de Trabajo:

  • Un Arduino UNO R3
  • Un Micro Servo

5. Ahora vamos a conectar los componentes a la placa de Arduino. Haz clic una vez para conectar un cable a un componente o pin, y haz clic de nuevo para conectar el otro extremo. También puedes (debes) cambiar los colores de los cables para aportar claridad al proyecto:

6. Fíjate en los colores de los cables. Nosotros usaremos en el MundoReal(C) un shield, con los cables de los mismos colores:

  • Marrón o negro: Conectar a GND.
  • Rojo: Conectar a 5V.
  • Naranja o blanco: Conectar a un PIN digital, en este caso el 13.

7. Ahora es cuando vamos a controlar el servomotor. Para ello vamos a utilizar una programación de bloques de código simples. Abre el editor del código (Botón «Código/Code»):

8. Verás que viene con un código por defecto. Puedes arrastrarlo a la papelera inferior o hacer clic con el botón derecho encima de él y eliminarlo:

9. Como con otras simuaciones con TinkerCAD, tienes que seleccionar primero el tipo de bloque, en este caso Salida/Output (2), luego cuál en concreto de salida, «rotate servo on pin x to x degrees» (3) y arrastrar ese bloque a la zona de trabajo (4):

10. Ahora en el bloque de Control (2) selecciona el bloque de Espera/Wait (3) y arrástralo a la zona de trabajo. Luego modifica las unidades y el tiempo de espera (4):

11. Para probarlo, haz clic en «Start simulation» (1), y para detener la simulación pulsa de nuevo (ahora aparece Stop simulation). Si te fijas, el aspa del mini servomotor gira en sentido antihorario, ¿cómo lo harías para que girase en sentido horario?

13. En cualquier momento puedes cambiar a «Blocks + Text» (1). Se despliega otra ventana en la que aparece el código en el lenguaje de programación c++ (3). ¿Eres capaz de comprenderlo?

14. Aquí tienes otra aproximación al problema. Este es el código básico para añadir con los comentarios. Date cuenta de que tienes que crear una variable nueva llamada «pos».

15. Ahora es tu oportunidad, ¡¡modifica el código a tu gusto!! ¿qué vas a tratar de conseguir?

16. Ahora vamos a descargar el código para pasarlo a la placa Arduino. Pulsa sobre el icono de «Descargar código»:

17. Se abrirá una ventana emergente para que selecciones la carpeta donde lo quieres guardar, ¡¡fíjate bien dónde antes de pulsar en Save!

18. Ahora tienes que abrir ese archivo que se ha descargado con el IDE de Arduino (en mi caso es la versión 2.2.1). Al hacerlo te pregunta que si quieres crear una carpeta y mover ahí el archivo. Dile que OK:

19. Verás que se abre el documento:

20. No te olvides de seleccionar la placa de Arduino UNO, desde Tools>Board>Arduino AVR Boards>Arduino Uno:

21. Cuando conectes tu placa de Arduino UNO por el puerto de USB tienes que seleccionarla también en el programa. En mi caso es el puerto COM6:

22. Ahora hay que comprobar que el código es correcto (1) y subirlo al microcontrolador (2):

Control con Arduino IDE

El control de servos en Arduino es muy sencillo, ya que el IDE Standard proporciona la librería “servo.h”, que permite controlar simultáneamente hasta 12 servos en Arduino Uno/Nano y hasta 48 servos en Arduino Mega.

Entre los ejemplos típicos para ilustrar el funcionamiento de servos tenemos el Sketch “Sweep”, que realiza un barrido continuo con el servo.

Para ello incrementa el ángulo de 0º a 180º a razón de 1º cada 15ms, posteriormente realiza la operación contraria de 180º a 0º, para finalmente reiniciar el bucle.

Dentro de la librería servo.h tienes Servo – attach () y Servo-Write ()

Control con ArduinoBlocks

Si no lo has hecho, regístrate en ArduinoBlocks y elige la placa ArduinoUNO. En el apartado Motor, encontramos los bloques para el control de servo:

Aquí tenemos la explicación de cada uno de los parámetros configurables:

Aquí tenemos un programa similar al realizado en el IDE, con el idioma del programa en Inglés:

Aquí está la «traducción» a código que realizar arduinoblocks. ¿Qué diferencias aprecias con el que has realizado en el IDE?

Añade los comentarios pertinentes al código para que aparezca de la siguiente manera:

También serviría así:

Práctica 2: Movimiento con monitor serie

El programa consiste en mover un sermotor a la posición deseada, introduciendo el valor a través del monitor serie.

Comunicación de Arduino con Puerto serie

Los puertos serie son la principal forma de comunicar una placa Arduino con un ordenador.

  • Un puerto es un interfaz (físico o virtual) que permite comunicación entre dos ordenadores o dispositivos.
  • Un puerto serie envía la información mediante una secuencia de bits. Necesita, al menos, un conector para recepción de datos (RX) y otro para la transmisión (TX). El más conocido es el Universal Serial Port (USB). Otros son el I2C, Serial ATA, Ethernet o FireWire.
  • Un puerto paralelo envía la información mediante múltiples canales de forma simultánea. Necesita muchos más conductores de comunicación.

Los puertos serie están físicamente unidos a distintos pines de la placa Arduino: 0 (RX) y 1 (TX). Mientras usamos estos puertos de serie no podemos usar como entradas o salidas digitales los pines asociados con el puerto serie en uso.

Nuestra placa de Arduino tiene un conector USB conectado a uno de los puertos serie, lo que simplifica el proceso de conexión con un ordenador.

Nota: No debemos acostumbrarnos a usar el puerto serie si realmente no necesitamos comunicar con el ordenador. Las librerías empleadas para el uso de puerto serie ocupan un tamaño considerable, y sólo debemos emplearlas si realmente las necesitamos. Además, supone inhabilitar de forma innecesaria los pines digitales asociados.

Control con Tinkercad

1. Crea un nuevo diseño de circuito con Tinkercad, y cámbiale el nombre a «Control servomotor monitor serie» e incluye de nuevo la placa de ArduinoUNO y el mini servo, conectado al pin 13, tierra (GND) y voltaje apropiado (5V). En la parte inferior selecciona «Serial Monitor«:

2. Dentro de las Variables (1), Crea una nueva variable (2) que se llame «pos» (3) y pulsa en OK (4):

3. Dentro de las Variables (1), elige «set pos to 0» (2) que se llame «pos» (3) y arrástralo a la zona de trabajo (4):

4. Ahora dentro de las entradas/Input (1), selecciona «read degrees on servo on pin 0» y arrástralo al bloque (3). Selecciona el pin digital al que está conectado el micro servo, en este caso el 13 (4):

5. Ahora, dentro de las salidas/Output (1), selecciona el bloque para mostrar en el monitor serie (2) y arrástralo a la zona de trabajo (3):

6. En vez de que muestre «hello world» en el monitor serie, vamos a mostrar el valor de nuestra variable (1) posición (pos) (2):

7. Necesitamos fijar la posición del aspa del servo dentro de las salidas/Output (1, por lo que seleccionamos el bloque apropiado (2), y lo anclamos a los bloques que teníamos (3). No te olvides de fijar el pin digital de la placa Arduino al que está conectado el micro servo (4), en este caso el nº13:

8. Ahora si cambias el valor de los grados (2), verás el desplazamiento del aspa del micro servo (3) y su lectura en el monitor serie (4):

9. Para poder hacerlo al revés (introducir datos en el monitor serie y controlar el servo), vamos a utilizar el texto en vez de los bloques.

Con este programa podemos colocar los servos en la posición que deseamos, para el correcto funcionamiento del brazo robótico.

Control con Arduino IDE

Una vez cargado el programa en el Arduino UNO, abrimos el monitor serie.

El monitor de puerto es una pequeña utilidad integrada dentro de IDE Standard que nos permite enviar y recibir información a través del puerto serie. Tiene dos zonas; una muestra los datos recibidos y otra para enviarlos:

Ejemplo: Empleo del puerto serie para encender o apagar el LED integrado de la placa de Arduino, enviando un carácter.

y vamos introduciendo el ángulo donde deseamos posicionar el servo y pulsamos Intro.

Con este programa podemos colocar los servos en la posición que deseamos, para el correcto funcionamiento del brazo robótico.

[ENTRADA EN CONSTRUCCIÓN]

Práctica 3: Movimiento secuencial «while» (1 servo)

El programa consiste en una secuencia de movimientos que se realizan poco a poco utilizando la instrucción while.

Control con Tinkercad

1. Como en la anterior práctica, partimos de un diseño de circuito en Tinkercad con una placa de ArduinoUNO y un micro servo conectado al pin digital 13:

2. Aquí tienes el código explicado con comentarios, es lo primero que tienes que realizar para comprobarlo:

3. Ahora vamos a añadir al código más movimientos, en este caso para que espere y continúe hasta otra posición:

4. Ahora volvemos al anterior, reduciendo ángulo en vez de aumentándolo:

5. Por último, lo reducimos hasta 10º:

6. Date cuenta que en Tinkercad puedes ver el código «real» (2) en vez de los bloques de colores si lo seleccionas (1):

7. Otra forma de realizarlo más eficiente es:

  • Funciones para Movimientos del Servo: Puedes «encapsular» las operaciones de movimiento del servo en funciones para hacer el código más modular y fácil de entender.
  • Constantes para Ángulos y Tiempos: Puedes utilizar constantes para representar los ángulos y tiempos específicos en lugar de valores numéricos directos.
  • Eliminación de Delay Duplicado: Puedes eliminar el delay repetido después de cada bucle while, ya que parece ser constante en todo el programa.

8. Aquí tienes el código para el IDE de Arduino, ¿eres capaz de saber lo que hace?

9. Aquí tienes la explicación del código:

Práctica 4: Movimiento secuencial directo (4 servos)

El programa consiste en una secuencia de movimientos que se realizan de forma directa.

Cada uno de los servos va a ser una parte del robot: Base, Hombro, Codo y Pinza.

Como hemos visto antes, hay unos valores iniciales de ángulo, y un rango de movimientos para cada uno de ellos:

ServoPinÁngulo inicialMovimiento
Base13-90º1º a 180º
Hombro11-30º45º a 150º
Codo8-100º40º a 180º
Pinza7-100º40º a 180º

1. Vamos a comenzar por crear un diseño nuevo con los 4 micro servos, cada uno con su nombre (base, hombro, codo y pinza), y con las conexiones adecuadas:

2. A continuación abrimos el código, y empezamos con el primero de los servos. Hay que tener en cuenta la posición inicial, con lo que hay que crear variables para cada uno de los servos:

3. Fijamos la posición inicial de cada servo a su ángulo adecuado:

4. Y completamos el movimiento de rotación de cada uno de ellos, añadiendo un intervalo de espera entre movimientos:

5. ¿Se mueve como preveías?

Práctica 5: Movimiento secuencial while (4 servos)

El programa consiste en una secuencia de movimientos que se realizan poco a poco utilizando la instrucción while.

1. Vamos a comenzar por crear un diseño nuevo con los 4 micro servos, cada uno con su nombre (base, hombro, codo y pinza), y con las conexiones adecuadas:

2. A continuación abrimos el código, y empezamos con el primero de los servos. Hay que tener en cuenta la posición inicial, con lo que hay que crear variables para cada uno de los servos:

3. Fijamos (set) los valores iniciales de los ángulos y configuramos los pines a los que están conectados los servomotores. Se esperan (wait) 2 segundos para comenzar.

4. En el bloque Forever/Loop vamos a tener 2 bucles while que controlan el movimiento del brazo robótico.

5. En el primer bucle (while), los ángulos de los servomotores aumentan gradualmente hasta alcanzar ciertos límites (hasta una posición específica). Dentro del bucle, se actualizan los servomotores.

6. Se incluyen condiciones (if) para evitar que superen ciertos límites (por ejemplo, 180º para la base y 60º para el hombro). Además, hay una pausa de 20 milisegundos entre cada iteración de bucle.

7. Aquí está el otro bucle while:

8. Este es todo el código en c++ comentado:

Práctica 6: Control con pulsadores

El programa consiste en un control en tiempo real de cada servo mediante dos pulsadores por cada servo, uno para cada sentido de giro.

Botón pulsador

Un robot obtiene información del entorno mediante sensores. Las señales le llegan a la Unidad de Procesamiento, y se utilizan posteriormente para generar unas respuestas en los actuadores:

Los sensores más sencillos son los sensores binarios, que sólo pueden estar en 2 estados diferentes: ON/OFF, 1/0, pusaldo/no pulsado, etc.

Un botón pulsador es un sensor binario. Es un sensor mecánico. Si hay contacto entre dos partes conductoras, los electrones pasan de una parte a otra si circula una corriente eléctrico. Hay una parte móvil sobre la que ejercemos fuerza, y dispone de un muelle para volver a la posición original.

Nosotros vamos a utilizar un micropulsador. Es un elemento pasivo (no consume energía).

El pin de salida del pulsador que llega a nuestra placa de Arduino debe ser digital, y tener alguno de estos dos valores: 0 ó 1. Así, se debe colocar un circuito adicional para garantizar que llegan sólo estos dos niveles. Una de sus patas la conectamos a GND (0), pero la otra queda «al aire». Si apretamos el botón, la señal de salida será 0, pero cuando NO está apretado NO HAY SEÑAL. El pin NO está conectado a nada, está al aire. Esto NO es válido cuando se trabaja en electrónica digital. Sólo son posibles los valores 0 ó 1.

Para conseguirlo, vamos a utilizar las resistencias de «pull-down», que se colocan entre la salida del pulsador y GND. Los valores de está resistencia deben estar entre 1k y 100k. Nosotros la vamos a utilizar de 10k.

Cuando el pulsador no está apretado, por el pin de Arduino llega a GND, a través de la resistencia R. Se recibe un 0 lógico. Al apretar el pulsador, por el pin de Arduino llega Vcc, que es un 1 lógico. De esta forma garantizamos que siempre llega o bien un 1 o bien un0.

El pulsador se comporta con lógica positiva: 1-apretado, 0-no apretado.

Una vez aprendido esto, ¡Empezamos con Tinkercad!

1. Representa este circuito con un pulsador y una resistencia pull-down de 10k, y un microservo.

2. Aquí tienes el código de los bloques, en este caso probando para mover la base. Como en otros programas, asociamos el servo motor a un pin, y ahora declaramos el pin de entrada para el pulsador. También colocamos el servo en su posición inicial. Mientras activamos el pulsador de la base, se irá incrementando el ángulo de la base cada 30 milisegundos, hasta que dejemos de pulsar. Si el ángulo llega al máximo (en este caso 180º), dejará de aumentar para evitar un fallo mecánico.

3. Ahora es cuestión de ampliarlo para todos los microservos. Aquí tienes la conexión con el shield de Arduino.

y aquí tienes las mismas conexiones, pero en TinkerCAD con una placa breadboard pequeña:

Aquí tienes la declaración de las variables que indican el ángulo inicial de los servos, y la colocación en su posición inicial. En este caso se muestra únicamente el servo de la base:

  • Mientras activamos el pulsador 1 de la base, se irá incrementando el ángulo del aspa del servo cada 30 ms hasta que dejemos de pulsar. Si el ángulo llega al máximo, dejará de aumentar para evitar un fallo mecánico.
  • El mismo procedimiento pero en sentido contrario.

Para los demás servos habría que realizar la misma operación, teniendo la precaución de modificar los pines y los ángulos.

Aquí tienes para el hombro:

Aquí para el codo:

Y aquí para la pinza:

Aquí tienes el código de Arduino IDE con los comentarios:

Práctica 7: Control con potenciómetros

El programa consiste en un control en tiempo real de cada servo mediante dos potenciómetros, una por cada servo, de manera que el eje del miniservo gire en relación al recorrido del potenciómetro.

Se puede usar GPTChat de OpenIA para preguntar acerca de este código:

Esta es la respuesta:

Práctica 8: Guardar posiciones

Práctica 9: Movimiento por sensor de ultrasonido

Práctica 10: Movimiento por joystick

Para esta práctica necesitaremos:

  • 4 miniservos
  • 2 joysticks

Este código de Arduino controla cuatro servomotores que están conectados a los pines 13, 11, 9 y 7 del Arduino. Los servomotores se utilizan para controlar la posición de la base, el hombro, el codo y la pinza de un brazo robótico, respectivamente. El control se realiza mediante dos joysticks, conectados a los pines analógicos A0, A1, A3 y A4 del Arduino.

La primera parte del código incluye la biblioteca Servo.h y declara cuatro objetos de la clase Servo para controlar los cuatro servomotores. También se definen cuatro variables enteras que se utilizan para almacenar los ángulos de cada servo.

La función setup() se utiliza para inicializar los objetos Servo y configurar los ángulos iniciales de los servomotores en 90 grados para la base, 170 grados para el hombro, 50 grados para el codo y 150 grados para la pinza. Además, la velocidad de la comunicación en serie se establece en 9600 baudios.

La función loop() es el bucle principal del programa, que se ejecuta continuamente mientras el Arduino está encendido. El primer comando en el bucle es delay(10), que introduce una pequeña pausa en la ejecución para evitar que el bucle se ejecute demasiado rápido.

Luego se leen los valores de los joysticks en los pines analógicos A0, A1, A3 y A4 mediante la función analogRead(). Estos valores se utilizan para controlar los ángulos de los servomotores.

El siguiente bloque de código utiliza las condiciones if() para comprobar si los joysticks se han movido hacia la derecha o hacia la izquierda. Si el joystick se mueve hacia la derecha y el ángulo del servo correspondiente es menor que 180º, se aumenta el ángulo del servo en una unidad. Si el joystick se mueve hacia la izquierda y el ángulo del servo correspondiente es mayor que 0, se disminuye el ángulo del servo en una unidad. Los cuatro servomotores se controlan de forma independiente utilizando las variables anguloB, anguloH, anguloC y anguloP.

Mejoras al código

Para mejorar este código, se podría añadir una función que limite los ángulos de los servomotores para evitar que se muevan más allá de los límites físicos del brazo robótico. Además, se podría incluir una función de calibración que permita ajustar los ángulos iniciales de los servomotores de forma precisa y fácil. También se podría añadir una interfaz gráfica de usuario para controlar el brazo robótico utilizando un ordenador o un dispositivo móvil.

  1. Función que limite los ángulos de los servomotores:

Actualmente, el código permite que los ángulos de los servomotores excedan los límites físicos del brazo robótico. Es decir, los ángulos pueden ser mayores que 180 grados o menores que 0 grados. Esto puede dañar los servomotores y reducir la vida útil del brazo robótico. Para solucionar esto, se puede implementar una función que limite los ángulos de los servomotores.

La función puede ser algo así:

int limitarAngulo(int angulo, int angulo_min, int angulo_max) {
  if (angulo > angulo_max) {
    return angulo_max;
  }
  else if (angulo < angulo_min) {
    return angulo_min;
  }
  else {
    return angulo;
  }
}

Esta función toma como entrada un ángulo, un ángulo mínimo y un ángulo máximo y devuelve el ángulo limitado dentro de los límites especificados. Se puede usar esta función en el código original para limitar los ángulos de los servomotores, de esta forma:

anguloB = limitarAngulo(anguloB, 0, 180);
anguloH = limitarAngulo(anguloH, 0, 180);
anguloC = limitarAngulo(anguloC, 80, 170);
anguloP = limitarAngulo(anguloP, 40, 120);
  1. Función de calibración:

Otra mejora útil sería agregar una función de calibración que permita establecer los ángulos mínimos y máximos para cada servomotor. Esto puede ser útil cuando se cambia el brazo robótico o se sustituye un servomotor. La función de calibración puede ser algo así:

void calibrarServomotores() {
  Serial.println("Calibrando servomotores...");
  Serial.println("Mueve cada servo a su posición mínima y presiona ENTER.");
  while (!Serial.available()) {
    // Espera a que se presione ENTER
  }
  anguloB = Base.read();
  anguloH = Hombro.read();
  anguloC = Codo.read();
  anguloP = Pinza.read();
  
  Serial.println("Mueve cada servo a su posición máxima y presiona ENTER.");
  while (!Serial.available()) {
    // Espera a que se presione ENTER
  }
  anguloB_max = Base.read();
  anguloH_max = Hombro.read();
  anguloC_max = Codo.read();
  anguloP_max = Pinza.read();
  
  Serial.println("Calibración finalizada.");
}

Esta función solicita al usuario que mueva cada servo a su posición mínima y máxima, y luego lee los ángulos actuales de cada servo. Luego, estos valores se pueden usar para limitar los ángulos de los servos en el código principal, usando la función limitarAngulo() propuesta anteriormente.

Para llamar a esta función desde el código principal, se puede agregar un condicional en la función setup() que verifique si hay datos disponibles en el puerto serie, como se muestra.

Código completo

#include <Servo.h>

Servo Base;
Servo Hombro;
Servo Codo;
Servo Pinza;

int anguloB = 90;
int anguloH = 170;
int anguloC = 50;
int anguloP = 150;
int minAnguloB = 0;
int maxAnguloB = 180;
int minAnguloH = 0;
int maxAnguloH = 180;
int minAnguloC = 80;
int maxAnguloC = 170;
int minAnguloP = 40;
int maxAnguloP = 120;

void setup() {
  Base.attach(13);
  Hombro.attach(11);
  Codo.attach(9);
  Pinza.attach(7);
  Serial.begin(9600);
  Base.write(anguloB);
  Hombro.write(anguloH);
  Codo.write(anguloC);
  Pinza.write(anguloP);
  
  // Calibración de los ángulos mínimos y máximos
  Serial.println("Calibrando el brazo robótico...");
  Serial.println("Mueva cada servo a su posición límite y manténgalo allí durante la calibración.");
  Serial.println("Presione cualquier tecla para comenzar...");
  while (!Serial.available());
  Serial.read();
  calibrarServo(Base, minAnguloB, maxAnguloB);
  calibrarServo(Hombro, minAnguloH, maxAnguloH);
  calibrarServo(Codo, minAnguloC, maxAnguloC);
  calibrarServo(Pinza, minAnguloP, maxAnguloP);
  Serial.println("Calibración finalizada.");
}

void loop() {
  delay(10);
  if (analogRead(A0) > 600 && anguloB < maxAnguloB) { // Derecha
    anguloB++;
    Base.write(anguloB);
  }
  if (analogRead(A0) < 400 && anguloB > minAnguloB) { // Izquierda
    anguloB--;
    Base.write(anguloB);
  }
  if (analogRead(A1) < 400 && anguloH < maxAnguloH) { // Derecha
    anguloH++;
    Hombro.write(anguloH);
  }
  if (analogRead(A1) > 600 && anguloH > minAnguloH) { // Izquierda
    anguloH--;
    Hombro.write(anguloH);
  }
  if (analogRead(A4) < 400 && anguloC < maxAnguloC) { // Derecha
    anguloC++;
    Codo.write(anguloC);
  }
  if (analogRead(A4) > 600 && anguloC > minAnguloC) { // Izquierda
    anguloC--;
    Codo.write(anguloC);
  }
  if (analogRead(A3) < 400 && anguloP < maxAnguloP) { // Derecha
    anguloP++;
    Pinza.write(anguloP);
  }
  if (analogRead(A3) > 600 && anguloP > minAnguloP) { // Izquierda
    anguloP--;
    Pinza.write(anguloP);
  }
}

void calibrarServo(Servo servo, int &minAngulo, int &maxAngulo) {
  int minValor = 1023

Deja un comentario

Comments (

0

)

Diseña un sitio como este con WordPress.com
Comenzar