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.
Tabla de Contenidos
Características Técnicas
- 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:
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:
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 0º (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:
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <Servo.h> Servo servo1; 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); } void loop() { // Mandamos escribir el angulo deseado del giro. servo1.write(angulo); } |
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.
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 |
#include <Servo.h> Servo servo1; 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);} void loop() { // Giro de 0º a 180º for(angulo = 0; angulo <=180; angulo=angulo+10) { servo1.write(angulo); delay(1000); } // Giro de 180º a 0º for(angulo = 180; angulo >=0; angulo=angulo-10) { servo1.write(angulo); delay(1000); } } |
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:
¿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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <Servo.h> Servo servo1; int pin = 9; int pulsoMinimo = 580; int pulsoMaximo = 2500; int angulo = 0; int lectura; void setup() { servo1.attach(pin,pulsoMinimo,pulsoMaximo); pinMode(A0,INPUT); } void loop() { lectura = analogRead(A0); angulo = map(lectura,0,1023,0,180); // Escalar la lectura a un valor de 0 a 180 servo1.write(angulo); delay(10); } |
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:
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
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);
}
}
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!
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
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
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 completaservo1.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 aattach
y escribir los grados para cerrar (30º). Justo antes demyservo.write(30, 20, true);
Inténtalo y me dices, cualquier duda sigo al pendiente
Gracias por responder en cuanto lo prueve te digo algo
haber si he sabido solucionarlo
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);
}
}
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íneamyservo.write(130, 20, true);
utilizas eltrue
, 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 🙂
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
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
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
¡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.
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
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!
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
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!
#include
#include
#include
las librerias no han aparecido en el texto que te he copiado
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!
Hola ABRAHAMG me puedes mandar una propuesta para ver como lo
termino de ver y me das nuevas ideas
gracias
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
Hola Joel, con mucho gusto te puedo apoyar, ¿cuál es tu duda? Saludos.
Saludos Doctor Abraham, le agradezco mucho el trabajo sobre control de servo con Arduino, lo explica con mucha claridad y detalle, buen trabajo en verdad.
Me encontraba buscando métodos funcionales para reducir la velocidad de servomotores, detener indefinidamente la ejecución del programa y la funcionalidad de un servo controlado por un sensor ultrasónico, llevaba semanas modificando códigos y buscando en la red y sólo encontraba soluciones parciales, pero en la sección de comentarios le respondía a JAVIER la forma de corregir un esquema de programación para controlar una cortina, al revisar un poco el código me dí cuenta de que se integraba a lo que necesitaba, mi objetivo era conseguir que una cabeza robótica girara para mirarme y con un sencillo programa en Processing y OpenCV, realizara una detección facial y un saludo hablado, su esquema funcionó a la perfección, lo felicito además por la paciencia y atención al contestarle al usuario JAVIER, precisamente como un gran docente, puede ver la demostración de funcionamiento de su esquema en https://youtu.be/3FEyPXjPWA8 y si gusta, el código con la adición de un servo extra en https://github.com/adan9233/Robotic-head/find/main.
Nuevamente le expreso mi agradecimiento, felicitaciones por su carrera y suerte en sus estudios.
Adam muchas gracias por tus comentarios! Tu trabajo está increíble! ojalá nos puedas compartir tus avances cada vez que desarrolles algo. Para mí es un placer poder compartir lo poco que he aprendido.
Mas adelante quiero darme el tiempo para poder compartir también sobre procesamiento de imágenes, ya que es un área donde me he especializado 🙂
Gracias por tomarte el tiempo de compartir y escribirme, te mando un gran saludo! No dudes en escribirme si tienes alguna duda, comentario y algo en lo que pueda ayudarte, me encantaría!