Controlar Servo Motor con Arduino

En este artículo aprenderemos a realizar el control de la posición de un servo motor con Arduino UNO. Pero antes de iniciar ¿qué es un servo motor?

Un servomotor o comúnmente llamado servo a secas, es un motor de corriente directa (DC) con la capacidad de controlar la posición de manera muy precisa y elegir cuando debe hacer el giro. Para lograr esto, los servomotores utilizan una retroalimentación para conocer en todo momento en que posición se encuentra. Por lo tanto, son utilizados para controlar la posición de objetos, el giro de un auto de control remoto, mover brazos, piernas, manos o cabeza de un robot, mover sensores, lámparas, entre muchas otras aplicaciones. Los circuitos necesarios para operar los servos ya se encuentran empaquetados en el mismo mecanismo por lo que es posible, en la mayoría de los casos, utilizarlos directamente con nuestra placa Arduino. Los servomotores incluyen un juego de engranes para reducir la velocidad y aumentar el torque.

En el mercado existen muchos tipos de servos, por lo que hay que revisar detenidamente cual es el que necesitamos. Para verificar las características técnicas de los servos (y de cualquier aparato electrónico), consultaremos su hoja de datos (datasheet). Para este ejemplo utilizaremos el servo SG90 de Tower Pro, ya que es altamente utilizado, tiene mucha disponibilidad en el mercado y su costo es muy bajo. Pero sobre todo, podemos utilizarlo directamente de la alimentación de nuestra placa Arduino siempre y cuando no le añadamos carga al servomotor, que esté libre. Para usos más específicos con cargas, es recomendable utilizar una fuente de alimentación externa, ya que la conexión USB de nuestro computador solo ofrece hasta 500 mA.

Características Técnicas

Servo motor SG90
Servo motor SG90
  • Voltaje de alimentación: 4.8-6 V
  • Torque: 2.5 kg-cm
  • Peso: 14.7 g
  • Velocidad: 0.1 s
  • Ángulo de rotación: 180º

Diagrama de conexiones

El servo contiene tres pines de conexión, con los cuales vamos a alimentarlo y a enviar la señal de control. El conector integrado maneja un código de colores, mismo que podemos observar en la siguiente imagen:

Diagrama de conexión SG90
Diagrama de conexión SG90

El cable de VCC irá conectado a la alimentación de 5V que puede ser el pin de energía 5V que tiene nuestro Arduino. El GND irá conectado a la terminal de tierra de nuestro Arduino, igualmente llamado GND. Y el conector anaranjado irá conectado a la salida de tipo PWM (indicada con ~ en nuestro Arduino), la seleccionaremos más adelante en el ejemplo.

Señal de control

Para que el servo realice su tarea, es necesario enviarle una señal PWM, donde el tiempo en alto es equivalente a la posición del servo. El cual, tendrá que estar entre 1 y 2 ms y el periodo total deberá ser de 20 ms (50 Hz), por lo que sólo podremos cambiar de posición cada 20 ms. Recordando que estos parámetros aplican para el servo SG90, si utilizan otro servo es necesario revisar su datasheet.

La siguiente imagen pretende explicar este punto:

Diagrama de tiempos del servo SG90
Diagrama de tiempos del servo SG90.

Este servo tiene un ángulo de giro de 180º. Es decir, podemos hacer un barrido entre -90º y 90º. Para indicar la cantidad de giro tenemos que enviarles una señal PWM (explicada en otro capítulo). Para un giro de (posición derecha) se le envía un pulso de 1 ms; y finalmente, para un giro de 90º (posición central) se le envía un PWM de 1.5 ms; y para indicarle un giro de 180º (posición izquierda) se le envía un PWM de 2 ms.

Librería servo.h

Para apoyarnos en el manejo de las señales de control, utilizaremos la librería servo.h que ya se encuentra instalada en nuestra IDE Arduino (interfaz de programación). Esta librería contiene implementadas las funciones necesarias para controlar hasta 12 servos con la mayoría de las placas Arduino y hasta 48 servos para la placa Arduino Mega.

Para poder utilizar la librería servo.h, es necesario declarar al inicio una variable del tipo Servo: Servo servo1;, esta variable utilizará las funciones.

Las funciones implementadas en la librería servo.h son:

  • attach(pin, min, max) donde el parámetro pin se utilizará para indicarle en qué pin estará conectado nuestro servo; min (opcional) será el ancho del pulso en microsegundos correspondiente a un giro de 0º del servo (por defecto es 544); max (opcional) será el ancho del pulso en microsegundos correspondiente a un giro de 180º (por defecto es 2400).
  • write(angulo) donde el parámetro angulo será el valor del ángulo que deseamos que gire el servo dado de 0º a 180º. En los servos que son de giro continuo, este parámetro establecerá la velocidad del giro, donde 0 será velocidad máxima en una dirección, 180 será velocidad máxima en la dirección opuesta, y un valor cercano a 90 será detenerse.
  • writeMicroseconds(tiempo) donde el parámetro tiempo será el ancho del pulso indicado en microsegundos.
  • read() lee la posición actual del servo dado en grados, devolviendo un valor entre 0 y 180.
  • attached(pin) verifica si la variable del tipo Servo está asignada al pin indicado. Devuelve un valor de true o false.
  • detach(pin) separa la variable del tipo Servo del pin indicado.

Hasta este punto ya tenemos lista toda la teoría necesaria para trabajar con nuestros servo motores.

Calibrando el Control de un Servo Motor

Los materiales que necesitamos para controlar un servo son:

  • Placa Arduino UNO.
  • Servomotor SG90.
  • Cables de conexión macho-macho

Lo siguiente será conectar nuestro sistema basándonos en el siguiente diagrama de conexión:

Diagrama de conexión de un servo motor con Arduino.
Diagrama de conexión de un servo motor con Arduino.

Conectaremos el cable anaranjado del servo al pin 9 del Arduino, el cual será la señal PWM necesaria para controlar el mismo. Posteriormente, abriremos nuestro IDE para realizar la programación.

Primeramente deberemos agregar la librería mencionada con anterioridad (Servo.h). Agregamos la declaración de una variable del tipo Servo, para el ejemplo se llamará servo1 . Esta variable podrá utilizar las funciones de la librería que anteriormente estudiamos. Declaramos a continuación las variables necesarias para configurar nuestro servo. Con la variable pin elegimos el pin físico de la placa Arduino a utilizar como control del servo. En la variable pulsoMinimo guardaremos el valor en microsegundos equivalente a la duración del pulso para indicar un giro de 0º y en la variable pulsoMaximo el valor equivalente a la duración de un pulso para indicar un giro de 180º. Para este ejemplo se utilizó pulsoMinimo = 580 y pulsoMaximo = 2500. Podemos utilizar los valores predefinidos; sin embargo, para mi caso estos me resultaron mas convenientes, ya que cuando agregamos un ancho de pulso mas pequeño para el giro de 0º, o mas grande para el giro de 180º en mi servo se escucha un ruido como si se estuviera forzando de más para establecer el giro. Lo que sucede, es que el servo intenta girar más de lo posible. Les recomiendo hacer algunas pruebas, considerando que la posición de absoluto 0º y absoluto 180º se presente.

Podemos observan en el código que hemos creado una variable llamada angulo para indicar el grado de giro que aplicaremos. Para este ejemplo solo mandamos escribir la variable angulo al servo. Cada vez que mandamos a escribir en el Arduino, la posición cambiará. Es necesario sobreescribir el valor del angulo y volver a programar para cambiar de giro. Este primer programa se los recomiendo para calibrar su servo de manera manual. Cambien el valor del angulo a 90 y 180 para verificar.

¿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

Variando el Giro de un Servo con Arduino

En este segundo ejemplo, programaremos una secuencia de giro en un sentido, posteriormente realizar un cambio de sentido e iniciar de nuevo. Con esto validaremos todas las posiciones posibles que nuestro servo puede realizar.

Podemos observar que el valor de la variable angulo se sobreescribe en cada ciclo for. Con este código estaremos aumentando el ángulo de giro de 1º en 1º cada 10 ms que es la máxima resolución que podemos obtener en este servomotor. El resultado de programar el código anterior es el siguiente:

Video controlando un servo con Arduino.

¿Cómo podrías modificar el código para que aumente un grado cada segundo?

Controlar un Servo con un Potenciómetro y Arduino UNO

Hasta este momento hemos controlado la posición de nuestro servo a través del programa. Ahora aprenderemos a hacerlo mediante un potenciómetro. Para lo cual utilizaremos un potenciómetro de manera similar a lo que vimos en el episodio anterior. El potenciómetro a utilizar será de 1 KΩ.

El diagrama de conexiones para este ejemplo es el siguiente:

Diagrama de conexión servo con potenciómetro.
Diagrama de conexión servo con potenciómetro.

Para el ejemplo, hemos agregado una variable llamada lectura, la cual nos servirá para guardar el valor obtenido del potenciómetro. Posteriormente utilizando la función map, convertiremos el rango de lectura de la entrada analógica (0-1023) a una escala para el servo (0-180). ¡Fácil! Ya solo nos resta enviar esta conversión escribiendo en el puerto del servo, como anteriormente lo habíamos estado haciendo.

Una vez programado nuestra placa Arduino, nos quedará algo como esto:

Video controlando un servo con potenciómetro.

Hasta aquí el capítulo de hoy, ¿qué les ha parecido? Te reto a que modifiques a tu antojo y beneficio los programas. Te invito a compartir esta información y a dejarme un comentario.

Recuerda visitar nuestras redes sociales

21 pensamientos sobre “Controlar Servo Motor con Arduino”

  1. Hola me llamo javier y me han gustado mucho tus vídeos
    como veo que entiendes del tema de programación quería preguntarte una duda que
    tengo
    tengo un proyecto de un sensor ultrasonido con servo y leds
    es una puerta que habre al detectar el sensor y luego despues de un tiempo se cierra
    lo que queria es que cuando el servo llegue a 130 grados (apertura de la puerta) se desconecte y cuando pase el tiempo del delay 50000, y se vuelva a conectar y vuelva a girar a 30 grados y cuando llegue a su posicion se vuelva a desconectar

    entre ida y vuelta que el servo se quede sin corriente

    este es el esquema que yo tengo
    Haber si me puedes ayudar te lo agradecería mucho

    // Apertura de cortina con 2 LEDS rojo y verde Y SENSOR DE DISTANCIA HCSR04

    #include
    VarSpeedServo myservo;
    const int servo = 9; //define ‘Servo Signal Pin’
    const int trigPin = 10; //define ‘Trigger Pin’
    const int echoPin = 11; //define ‘Echo Pin’

    // define variables
    long duration;
    int distance;
    int pos = 30; // Variable para almacenar la posicion del servo

    int ledverde =5;
    int estado=LOW;
    int ledrojo =6;

    void setup(){

    pinMode(ledverde, OUTPUT);
    pinMode(ledrojo, OUTPUT);

    pinMode(trigPin, OUTPUT); // Establece a ‘trigPin’ como Salida
    pinMode(echoPin, INPUT); // Establece a ‘echoPin’ como Entrada
    myservo.attach(servo); // Acopla al servo en el pin 9
    myservo.write(30); // Sets Servo to initially 0 degrees
    delay (2000);
    Serial.begin(9600); // Comienza la comunicacion serial
    digitalWrite(ledrojo,HIGH);
    digitalWrite(ledverde,LOW);

    }

    void loop() {

    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    // Establece a ‘trigPin’ en estado alto (HIGH) por 10 microsegundos
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    // Lectura del ‘echoPin’, retorna el tiempo de viaje de la onda ultrasonica en microsegundos
    duration = pulseIn(echoPin, HIGH);

    // Calculando la distancia
    distance= duration*0.034/2;

    // Imprime la distancia en el monitor serial
    Serial.print(«Distance: «);
    Serial.println(distance);
    estado = digitalRead(ledverde);
    estado = digitalRead(ledrojo);

    if(distance<50)
    { //Revision: que la distancia sea menos que 50cm
    digitalWrite (ledrojo,LOW);
    digitalWrite (ledverde, HIGH);

    myservo.write(130, 20, true);
    delayMicroseconds(20);
    myservo.write(125, 20, true);
    delay (50000);
    digitalWrite (ledverde, HIGH);
    delay(400);
    digitalWrite(ledverde, LOW);
    delay(400);
    digitalWrite (ledverde, HIGH);
    delay(400); // retardo en milisegundos
    digitalWrite(ledverde, LOW); // apaga el LED.
    delay(400);
    digitalWrite (ledverde, HIGH);
    delay(400);
    digitalWrite (ledverde, LOW);
    delay(400);
    digitalWrite (ledrojo, HIGH);

    myservo.write(30, 20, true);
    digitalWrite (ledrojo, HIGH);
    digitalWrite(ledrojo, LOW); // enciende el LED.
    delay(400); // retardo en milisegundos
    digitalWrite (ledrojo, HIGH);
    delay(400);
    digitalWrite(ledrojo, LOW); // apaga el LED.
    delay(400);

    digitalWrite (ledrojo, HIGH);

    digitalWrite (ledverde, LOW);

    }
    }

    1. Hola Javier muchas gracias por tu comentario,

      Con mucho gusto te ayudo. Me parece muy interesante tu proyecto, pero me gustaría que me contaras más, por ejemplo:
      – El sensor de ultrasonido lo utilizas solamente para detectar presencia o estás midiendo la distancia, si es lo segundo, cuales son las reglas de control, que a «X» distancia abra o cierre… etc
      – A qué te refieres con que se «desconecte y vuelva a conectar»?
      – A qué te refieres con que «entre ida y vuelta que el servo se quede sin corriente»?
      – Con esquema te refieres al código o a algún diagrama? (aunque esto igual no es tan necesario que me lo compartas)

      Te pregunto lo anterior para entender un poco mejor la dinámica de funcionamiento que deseas obtener, ya que si solamente requieres la señal para que el sistema decida cuando activar o desactivar el servo para abir o no… podrías simplificarlo con otro tipo de sensor.

      ¡Espero tus comentarios!

  2. Hola ABRAHAMG el proyecto es de apertura de una cortina
    cuando pasa una persona a menos de 50 cm se activa el servo y gira asta los 130 grados (abriendo la cortina lentamente)

    if(distance<50)
    myservo.write(130, 20, true);

    cuando llega a esa posicion de los 130 grados lo que quiero es que el servo
    deje de tener corriente cuando llega a la posicion de 130 grados (es por el ruido que genera el servo y queria quitar ese ruido desconectando el servo cuando llega a su posicion de 130 grados)
    con la opcion detach (que deja de suministrar corriente al servo)

    Lo que quiero es que el servo cuando este la puerta abierta 130 grados
    el servo deje de tener corriente
    se que se utiliza la opcion servo .detach ()
    pero si la pongo despues de que llegue el servo a 130 (abre la cortina y espera un delay 50000)
    el servo deja de funcionar y no cierra la cortina
    no se en que linea tengo que volver a ponerlo para que se vuelva a activar
    el sketch es el que te he mandado antes

    te mandare un video con el sistema para que lo veas
    te pondre un enlace

  3. Hola ABRAHAMG te envio este video de esta papelera que
    mediante un pulsador se abre y cuando vuelves a pulsar se cierra
    lo que queria es que cuando esta abierta el servo deje de hacer fuerza (no tenga corriente )
    y cuando vuelva a pulsar el boton el servo vuelva a funcionar y baje la tapa de la papelera

    https://drive.google.com/file/d/1-7bwDUwumeuF3z4VIbPyHlOxFEvsSCkx/view?usp=sharing

    te agradeceria si puedes darme una idea
    en que linea tendria que poner el detach y luego que vuelva a funcionar otra vez el servo
    un saludo
    javier

    1. Hola Javier, gracias por tu detallada descripción.
      Primero creo que si tu servo hace ruido cuando ya está en una posición, puede ser por dos cosas, el desgaste del servo, o que está mal calibrado. Veo que cuando haces el attach no le envías la configuración completa servo1.attach(pin,pulsoMinimo,pulsoMaximo); Intenta calibrar tu servo para que funcione de manera correcta. No debería hacer ruido. En el capítulo se menciona un poco de esto, trata de «calibrarlo a mano» cambiando los valores, sobre todo asegurarte que un 0º sea exactamente la posición que debería ser sin forzarse (ruido).
      Por otro lado, si quieres de cualquier manera quitarle la corriente al servo puedes volver a realizar el attach dentro del código, por ejemplo:
      servo1.write(130);
      delay(3000);
      servo1.detach();
      delay(1000);
      servo1.attach(pin,pulsoMinimo,pulsoMaximo);
      delay(2000);
      servo1.write(0);
      delay(3000);

      Para tu caso en específico, supongo que la mejor manera podría ser después de alcanzar la posición deseada (130º) realizar un detach, y después de realizar el retardo necesario, volver a attach y escribir los grados para cerrar (30º). Justo antes de myservo.write(30, 20, true);

      Inténtalo y me dices, cualquier duda sigo al pendiente

  4. Hola ABRAHAMG he estado probando el codigo que me has dicho y me pasa lo siguiente
    declaro las variables

    int pulsoMinimo;
    int pulsoMaximo;

    en el void setup (){

    myservo.attach(servo,pulsoMinimo,pulsoMaximo);
    myservo.write(0); // inicia el servo a 0 grados
    delay (2000);

    hasta aqui bien
    entonces
    en el void loop() {
    le digo que si la distancia es menor que 50 active el servo

    if(distance<50)
    myservo.write(130, 20, true); // abre la puerta a 130 grados lentamente
    delay(3000);
    myservo.detach(); // desconecto el servo durante 1 minuto que es el delay de 50000 que e puesto
    delay(50000); //tiempo para que aguante la puerta abierta

    myservo.attach(servo,pulsoMinimo,pulsoMaximo);
    delay(2000);
    myservo.write(0,20,true);
    delay(3000);

    myservo.detach();
    delay(2000);
    myservo.attach(servo,pulsoMinimo,pulsoMaximo);
    delay(2000);
    myservo.write(0);
    delay(2000);

    cuando el servo llega a la posicion de 130 grados se desconecta el servo durante 1 minuto
    (delay 50000 tiempo para que aguante la puerta abierta )
    cuando pasa ese minuto se vuelve a activar el servo
    girando a la posicion de 0 grados lentamente ( myservo.write(0,20,true); )

    myservo.detach();
    delay(2000); // el problema lo tengo con el delay
    myservo.attach(servo,pulsoMinimo,pulsoMaximo);
    delay(2000);
    myservo.write(0);
    delay(2000);

    el problema lo tengo con el delay
    lo que quiero es que el servo en el inicio de 0 grados se quede sin corriente hasta
    que yo pase por el sensor ultrasonico que sera el que active el servo y ira a la posición de 130
    grados alli el servo se volvera a quedar sin corriente durante 1 minuto y volvera a su posicion
    de 0 grados , en la que el servo se vuelva a desconectar y se mantendra desconectado hasta que
    el sensor ultrasonico detecte presencia

    No se si me habre explicado bien
    te mando este video donde te explico lo que me pasa

    https://drive.google.com/file/d/1u7hmPeuTDBvCATsWyarNE0H48IYX2Ws-/view?usp=sharing

    espero tu respuesta

    te dejo el programa

    // Apertura de cortina con 2 LEDS rojo y verde Y SENSOR DE DISTANCIA HCSR04

    #include
    VarSpeedServo myservo;
    const int servo = 9; //define ‘Servo Signal Pin’
    const int trigPin = 10; //define ‘Trigger Pin’
    const int echoPin = 11; //define ‘Echo Pin’

    // define variables
    long duration;
    int distance;
    int pos = 0; // Variable para almacenar la posicion del servo
    int pulsoMinimo;
    int pulsoMaximo;
    int ledverde =5;
    int estado=LOW;
    int ledrojo =6;

    void setup(){

    pinMode(ledverde, OUTPUT);
    pinMode(ledrojo, OUTPUT);

    pinMode(trigPin, OUTPUT); // Establece a ‘trigPin’ como Salida
    pinMode(echoPin, INPUT); // Establece a ‘echoPin’ como Entrada
    myservo.attach(servo,pulsoMinimo,pulsoMaximo); // Acopla al servo en el pin 9

    myservo.write(0); // Sets Servo to initially 0 degrees
    delay (2000);

    Serial.begin(9600); // Comienza la comunicacion serial
    digitalWrite(ledrojo,HIGH);
    digitalWrite(ledverde,LOW);

    }

    void loop() {

    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    // Establece a ‘trigPin’ en estado alto (HIGH) por 10 microsegundos
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    // Lectura del ‘echoPin’, retorna el tiempo de viaje de la onda ultrasonica en microsegundos
    duration = pulseIn(echoPin, HIGH);

    // Calculando la distancia
    distance= duration*0.034/2;

    // Imprime la distancia en el monitor serial
    Serial.print(«Distance: «);
    Serial.println(distance);
    estado = digitalRead(ledverde);
    estado = digitalRead(ledrojo);

    if(distance<50)
    { //Revision: que la distancia sea menos que 50cm
    digitalWrite (ledrojo,LOW);
    digitalWrite (ledverde, HIGH);

    myservo.write(130, 20, true);
    delay(3000);
    myservo.detach();
    delay(50000);//tiempo para que aguante la puerta abierta

    myservo.attach(servo,pulsoMinimo,pulsoMaximo);
    delay(2000);
    myservo.write(0,20,true);
    delay(3000);

    myservo.detach();

    delay(2000);
    myservo.attach(servo,pulsoMinimo,pulsoMaximo);
    delay(2000);
    myservo.write(0);
    delay(2000);
    digitalWrite (ledverde, HIGH);
    delay(400);
    digitalWrite(ledverde, LOW);
    delay(400);
    digitalWrite (ledverde, HIGH);
    delay(400); // retardo en milisegundos
    digitalWrite(ledverde, LOW); // apaga el LED.
    delay(400);
    digitalWrite (ledverde, HIGH);
    delay(400);
    digitalWrite (ledverde, LOW);
    delay(400);
    digitalWrite (ledrojo, HIGH);
    myservo.write(0, 20, true);
    delay (3000);

    digitalWrite (ledrojo, HIGH);
    digitalWrite(ledrojo, LOW); // enciende el LED.
    delay(400); // retardo en milisegundos
    digitalWrite (ledrojo, HIGH);
    delay(400);
    digitalWrite(ledrojo, LOW); // apaga el LED.
    delay(400);

    digitalWrite (ledrojo, HIGH);
    digitalWrite (ledverde, LOW);

    }
    }

    1. Hola Javier, muchas gracias por el video, ahora te entiendo perfectamente lo que buscas lograr.
      Como estás usando la librería VarSpeedServo, y en tu línea myservo.write(130, 20, true); utilizas el true, por lo que el código se detendrá de ejecutar hasta que el servo haya llegado a la posición; por lo que no necesitas meter un delay después de esta línea. Entonces en tu código podrías eliminar:
      myservo.write(130, 20, true);
      delay(3000);
      myservo.detach();
      delay(50000);//tiempo para que aguante la puerta abierta

      myservo.attach(servo,pulsoMinimo,pulsoMaximo);
      delay(2000);
      myservo.write(0,20,true);
      delay(3000);

      myservo.detach();

      Ya que el tiempo entre el attach y el write el servo no se está moviendo, por lo que es innecesario (para tu caso) el mantenerlo energizado. Te recomiendo probar de esta manera.

      Ahora, si quieres que el servo permanezca sin corriente hasta que detectes con el sensor, entonces el attach insértalo justo después del
      if(distancia<50){
      myservo.attach....
      myservo.write(130,20,true);
      .
      .
      .
      .
      myservo.write(0,20,true);
      myservo.detach();
      }

      Otra solución digamos "a la mala" es utilizar un relevador para controlar mediante un pin digital, cuando se alimenta el servo y cuando no. Por lo que no necesitarías hacer detach nunca, solamente activarías el pin digital cada vez que quieras realizar un movimiento.

      Platícame que tal te funciona esta vez. No dudes en escribirme cualquier detalle, lo tenemos que conseguir 🙂

  5. Hola ABRAHAMG ahora si que funciona con esta configuración

    if(distance<50)
    { //Revision: que la distancia sea menos que 50cm
    digitalWrite (ledrojo,LOW);
    digitalWrite (ledverde, HIGH);

    myservo.attach (servo,pulsoMinimo,pulsoMaximo);
    myservo.write(130, 20, true);
    myservo.detach();
    delay(50000);//tiempo para que aguante la puerta abierta
    myservo.attach(servo,pulsoMinimo,pulsoMaximo);
    myservo.write(0,20,true);
    myservo.detach();
    if(distance<50)
    {

    ahora se mantiene tanto en 0 grados como en 130 sin energía el servo
    hasta qui todo bien (perfecto)

    Ahora me falta la siguiente operación
    lo que quiero es que cuando el servo este cerrando la puerta ( de 130 grados a 0 grados )
    y estoy tapando el sensor que la puerta se mantenga en 130 grados y no actúe el temporizador de
    50000 asta que quede libre el sensor
    si el servo esta a mitad de camino cerrando la puerta y yo tapo el sensor el servo
    cambiara de sentido y volverá a abrirse a 130 grados
    no se si me he explicado bien
    te envió este vídeo
    en el que te explico lo que quiero hacer

    https://drive.google.com/file/d/1UouDlnaakfbrquBP6ntVTgIY21KQHahR/view?usp=sharing

    1. Qué tal Javier, me da gusto que te haya funcionado. Gracias nuevamente por el video, vamos a ello.

      Para lo que quieres lograr en mi opinión no hay una mejor forma de hacerlo que con un ciclo for. Te anexo el código completo, le modifiqué algunas cosas a tu código y le borré todo lo de los LEDs, se lo puedes volver a poner. Revisa que te he agregado una función para medir la distancia en el sensor, para usarla de manera más ordenada, ya que lo vamos a utilizar muchas veces… El código lo he probado yo mismo y funciona bien; sin embargo, impleméntalo y me avisas.
      Si tienes alguna duda en cuanto al funcionamiento de las funciones que agregué me dices, con mucho gusto te las explico, algo de ello lo explico en la Guía de Inicio Arduino que puedes descargar de acá. En estas próximas semanas, dependiendo del tiempo, iré agregando más capítulos explicando a detalle todo lo realizado acá, me encantaría que al implementar tu proyecto me compartas tu resultado final y lo podemos agregar al Blog, te gustaría?

      ¡Quedo al pendiente de tus comentarios y te mando un gran saludo!
      CODIGO

  6. Hola ABRAHAMG el código que me has enviado va perfecto se ha podido solucionar todas las dudas que te plantee muchas gracias
    Te envío un enlace en el que puedes ver el video como ha quedado

    https://drive.google.com/file/d/1SDOYTFmBkH-DR6cJaxlJFZ6nFcQnPhOP/view

    Yo hace tiempo hice un proyecto con un módulo que compré que era un grabador de servo
    Podías grabar en su memoria hasta 4 minutos de movimientos de un servo motor
    Con este módulo hice unos muñecos que imitaban a cantantes moviendo la boca
    Yo quería hacer un proyecto así con el arduino un servo y un potenciómetro y un módulo de tarjeta Sd para grabar los movimientos del servo y después reproducirlo mediante un botón de
    Reproducción 1 botón de grabación y barios botones más para elegir las canciones que quería
    En ese momento
    Como tu muy bien sabes arduino no tiene suficiente memoria para grabar tantas posiciones de los servos
    Me gustaría hacer este proyecto con tu ayuda en cuanto lo tenga un poco avanzado te digo algo a ver si podemos hacerlo
    Es bastante complicado, pero no imposible
    Te envío el enlace para que veas el proyecto que hice hace tiempo

    https://youtu.be/IbJEzmHEbFA

    te voy a enviar una página donde tengo más cosas hechas por si quieres echarle un vistazo

    https://sites.google.com/site/maquetasjaviergranena/maquetas

    Muchas gracias por tu ayuda
    Espero que estemos en contacto
    Un saludo
    Javier

    1. ¡Muchas gracias a ti Javier, he visto algunos de tus videos, eres buenísimo! Con mucho gusto quedo en espera de tus comentarios e intentamos realizar el proyecto.
      Saludos.

  7. Hola ABRAHAMG te lo he puesto 2 veces porque no veía lo que te había mandado
    te quería agradecer que cuando pusiste el código
    lo pusiste bien detallado con lo que hacia cada función y muy bien explicado
    te lo agradezco mucho
    un saludo
    javier

    1. Javier un gran gusto! No te preocupes, los comentarios por default no aparecen de manera instantánea, ya que los tengo que aprobar manualmente, no te preocupes por eso.
      He visto tu video final ah quedado perfecto, y claro, siempre tendrás que ajustar a lo que tú buscas, esa es la idea!
      Te agradezco yo a ti por comentar y preguntar, seguimos en contacto y no dudes escribir cuando lo desees.
      Saludos!

  8. Hola ABRAHAMG como te comente estoy intentando grabar las posiciones del servo en una tarjeta SD y con un potenciometro mover el servo y que quede registrada en la tarjeta SD
    con un nombre (por ejemplo Pinpinela)

    cuando abro el monitor serial veo las numeraciones de como van registrándose cuando muevo
    el servo
    tengo que poner un botón para que empiece a grabar y mediante un led se encienda para saber
    que esta grabando (con este mismo botón se pararía la grabación si lo vuelvo a presionar ? luego poner otro botón para reproducirlo
    lo que pasa es que no se que nombre tiene el archivo que le da a la tarjeta sd
    cuando graba los movimientos

    me daba un error con los de las librerías
    he cambiado la versión del arduino y se ha corregido
    el programa es el siguiente

    //servo recorder arduino

    //librerias

    #include
    #include
    #include

    // Pin CS para el módulo de tarjeta SD
    const int chipSelect = 4;
    // Pin analógico para potenciómetro
    int analogPin = 0;
    // Entero para mantener el valor del potenciómetro
    int val = 0;

    // Crear un objeto Servo
    Servo myservo;

    void setup() {

    // Abra comunicaciones en serie y espere a que se abra el puerto
    Serial.begin(9600);
    while (!Serial) {
    ; // espera a que se conecte el puerto serie.
    }

    Serial.print(«Initializing SD card…»);

    // ver si la tarjeta está presente y se puede inicializar:
    if (!SD.begin(chipSelect)) {
    Serial.println(«Card failed, or not present»);
    // no hagas nada más
    while (1);
    }
    Serial.println(«card initialized.»);

    // Adjunte el servo en el pin 9 al objeto servo
    myservo.attach(9);
    }

    void loop() {
    // crea una cadena para ensamblar los datos para registrar:
    String dataString = «»;

    // Leer el valor del bote y agregarlo a la cadena
    // Mapa para rango de 0-180 para servo
    val = map(analogRead(analogPin), 0, 1023, 0, 180);
    dataString += String(val);

    // Escribe al servo
    // Retraso para permitir que el servo se asiente en posición
    myservo.write(val);
    delay(15);

    // abre el archivo. tenga en cuenta que solo se puede abrir un archivo a la vez,
    // así que debes cerrar esta antes de abrir otra
    File dataFile = SD.open(«servopos.txt», FILE_WRITE);

    // si el archivo está disponible, escríbalo
    if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // imprime también en el puerto serie
    Serial.println(dataString);
    }
    // si el archivo no está abierto, aparece un error:
    else {
    Serial.println(«error opening servopos.txt»);
    }
    }

    haber si podemos hacerlo
    te envio este video
    con un poco del proyecto

    https://drive.google.com/file/d/1HB4gIyvcVjRui88_wxp_flcEq-Qv4uAa/view?usp=sharing

    un saludo
    javier

    1. Que tal Javier, tu proyecto está genial.
      Te recomiendo primero iniciar con lo fácil:
      – Cada cuanto quieres que se repita el loop; es decir, cada cuanto grabar una posición nueva?
      – Dónde se reproduce la canción, le das play/grabar en arduino y en la PC o en otro lado al mismo tiempo?
      – El nombre que le da al archivo en el SD está precisamente en: File dataFile = SD.open(«servopos.txt», FILE_WRITE); (no sé por qué se ponen los <<>> debería ser comillas dobles)
      – Te recomiendo grabar primero una canción a la vez, para que puedas cambiarle el nombre al archivo cada vez, o a menos que quieras darle una numeración seriada… cada vez que se presione un botón o así.

      Para hacer que el botón REC gobierne cuando empieza a grabar, hay que hacer un ciclo if que dependa del estado del Botón: if(Botón==True){ Grabar todo }, solamente recuerda los rebotes del botón que en este capítulo lo vimos.

      Se podrían hacer dos funciones, una para grabar y una para leer, con la intensión de verificar las posiciones grabadas.

      ¿Lo quieres intentar, o te mando una propuesta?

      Saludos!

    1. No te preocupes, si gustas también puedes mandarme un correo a contacto@automatizacionparatodos.com para compartirme tus dudas y comentarios, así como el código. Si quieres seguir aquí también está perfecto, solo te recomendaría que subieras tu archivo de código a google drive por ejemplo, para que puedas anexar tu código más correcto y pegas el link en el comentario, podría ser.
      Saludos!

  9. Hola AbrahamG queria saber si me puedes, tengo un proyecto mediante la lectura de un sensor de humedad el servo tiene que girar 90 grados a la derecha y -90 grados a la izquierda.

    te agradeceria mucho tu ayuda
    gracias

Deja un comentario