martes, 6 de octubre de 2015

Moviendo desvíos con servos y Arduino

Buenas a todos!!! Después de estar mirando como poder mover los desvíos de mi nueva maqueta (aun en construcción) y viendo los precios y los diferentes sistemas (electroimanes, reles, motores caseros, etc..) me he decantado por los servos de modelismo y Arduino.

Lo que más me ha convencido son su bajo precio y lo fácil que son de instalar, si a eso le añadimos una placa Arduino, la cosa se hace mucho más interesante.

Ya no es que solo podamos mover el servo con Arduino, sino que también podremos tener salidas para poder conectar semáforos o cualquier otra cosa que queramos como los corazones de los desvíos.

El servo en cuestión es el servo 9G:



Y la placa de Arduino que he elegido para este proyecto es la Arduino NANO con un shield especial (o ideal) para este proyecto:

Arduino Nano

Shield Arduino Nano

Además el precio es más que asequible, en total las dos placas tienen un coste menor de 8€.

En este caso, al no ir conectadas a ninguna central DCC, he tenido que construir un pequeño panel donde van 4 pulsadores y conectarlos a una entrada analógica.

Si, se podrían haber conectado a pines digitales pero he preferido hacerlo de manera analógica sobre todo por el tema del cableado y por que así me sobran otros tantos pines para una posible ampliación o conectar cualquier otra cosa que se me ocurra, pero eso sera cuando este la maqueta más avanzada. En principio se quedara tal y como se ve en el vídeo.


Los 4 pines asignados a los servos son el 6, 7, 8 y 9 y los 4 pines asignados a accesorios son el 10, 11, 12, 13. Los pulsadores van conectados en el pin A0 con 5 resistencias de 1K.


Servo desvíos arduino UNO
Conexión de los pulsadores a Arduino

Pulsadores

Arduino + Shield y servos

Aquí está el código:


/* Programa final para mover los desvíos de una maqueta mediante
 * servos de modelismo. Se utilizan 4 pulsadores conectados al pin
 * analógico A0. 
 * Los pines reservados para los servos son: pin 6,7,8,9
 * y van enlazados a los pines 10,11,12,13 respectivamente para encender
 * un LED o accionar un rele 
 */

#include "Servo.h"

Servo servo1;       // Primer servo
Servo servo2;       // Segundo servo
Servo servo3;       // Tercer servo
Servo servo4;       // Cuarto servo 
int swcs = 0;

int estadoPos1 = 1;    // Estado posición servo1
int estadoPos2 = 1;    // Estado posición servo2
int estadoPos3 = 1;    // Estado posición servo3
int estadoPos4 = 0;    // Estado posición servo4

int servoVar1 = 70;    // Posición del servo1 al iniciar el programa
int servoVar2 = 70;    // Posición del servo2 al iniciar el programa
int servoVar3 = 70;    // Posición del servo3 al iniciar el programa
int servoVar4 = 95;    // Posición del servo4 al iniciar el programa
int servoVarMin1 = 70;  // Valor mínimo del servo1
int servoVarMin2 = 70;  // Valor mínimo del servo2
int servoVarMin3 = 70;  // Valor mínimo del servo3  
int servoVarMin4 = 65;  // Valor mínimo del servo4
int servoVarMax1 = 95;  // Valor máximo del servo1
int servoVarMax2 = 95;  // Valor máximo del servo2
int servoVarMax3 = 95;  // Valor máximo del servo3
int servoVarMax4 = 95;  // Valor máximo del servo4
int timeDelay = 50; 	// 90

int Led1=10;  // LED en pin 10 para servo1
int Led2=11;  // LED en pin 11 para servo2
int Led3=12;  // LED en pin 12 para servo3
int Led4=13;  // LED en pin 13 para servo4

void setup() {
	Serial.begin(115200);
	servo1.attach(6);    // Adjuntamos el pin 6 a servo1
	servo2.attach(7);    // Adjuntamos el pin 7 a servo2
	servo3.attach(8);    // Adjuntamos el pin 8 a servo3
	servo4.attach(9);    // Adjuntamos el pin 9 a servo4
	delay (150);
	servo1.write(servoVar1); 
	servo2.write(servoVar2); 	
	delay (150);
	servo3.write(servoVar3); 
	servo4.write(servoVar4); 
	servo1.detach();
	servo2.detach();
	servo3.detach();
	servo4.detach();
	pinMode(Led1,OUTPUT);
	pinMode(Led2,OUTPUT);
	pinMode(Led3,OUTPUT);
	pinMode(Led4,OUTPUT); 
}

void loop() {

 	int valorPulsador= analogRead(0); // Valor de la entrada analógica A0
       
	if (valorPulsador > 600 && valorPulsador < 1000){
       	swcs=1;
	    Serial.println("b1");
        Serial.println(valorPulsador);
        }
	if (valorPulsador > 400 && valorPulsador < 600){
		swcs=2;
        Serial.println("b2");
        Serial.println(valorPulsador);
        }
	if (valorPulsador > 300 && valorPulsador < 400){
    	swcs=3;
        Serial.println("b3");
        Serial.println(valorPulsador);
        }
	if (valorPulsador > 200 && valorPulsador < 300){
		swcs=4;
        Serial.println("b4");
        Serial.println(valorPulsador);
        }   
                        		
	

	switch (swcs){
	// Movimiento Servo 1-------------------
		case 1:
			servo1.attach(6);    //Adjuntamos el pin 6 a servo1 
			if (estadoPos1==1) {
   				for(servoVar1 = servoVarMin1; servoVar1 <= servoVarMax1; servoVar1 += 1){                                  
    				servo1.write(servoVar1);              
    				delay(timeDelay);
 					// Serial.print (servoVar2);
 					// Serial.print (", "); 
    			}    
    			estadoPos1=0;
    		swcs = 0;
    		digitalWrite (Led1, HIGH);    
    		delay (50);
    		} else {                   
 				if (estadoPos1==0){   
    				for(servoVar1 = servoVarMax1; servoVar1 >= servoVarMin1; servoVar1 -= 1){                                   
    					servo1.write(servoVar1);              
    					delay(timeDelay); 
   						// Serial.print (servoVar2);
   						// Serial.print (", ");
    			}
    			estadoPos1= 1;
    			swcs= 0;
    			digitalWrite (Led1,LOW);    
    			delay (50);             
      			}
    		}
			servo1.detach();    
  			break;
   
   // Movimiento Servo 2-------------------
 		case 2:
 			servo2.attach(7);    // Adjuntamos el pin 6 a servo1 
 			if (estadoPos2 == 1) {
   				for(servoVar2 = servoVarMin2; servoVar2 <= servoVarMax2; servoVar2 += 1){                                  
    			servo2.write(servoVar2);              
    			delay(timeDelay);
 				// Serial.print (servoVar2);
 				// Serial.print (", "); 
    			}    
    		estadoPos2=	0;
    		swcs = 0;
    		digitalWrite(Led2, HIGH);    
    		delay(50);
    		} else {                   
 				if (estadoPos2 == 0){   
    				for(servoVar2 = servoVarMax2; servoVar2 >= servoVarMin2; servoVar2 -= 1){                                   
                    	servo2.write(servoVar2);              
    					delay(timeDelay); 
   						// Serial.print (servoVar2);
   						// Serial.print (", ");
    			}
    			estadoPos2= 1;
    			swcs= 0;
    			digitalWrite(Led2,LOW);    
    			delay(50);             
      		}
    	}
		servo2.detach();    
  		break;
  // Movimiento Servo 3-------------------
		case 3: 
 			servo3.attach(8);    // Adjuntamos el pin 8 a servo3   
 			if (estadoPos3 == 1) {
   				for(servoVar3 = servoVarMin3; servoVar3 <= servoVarMax3; servoVar3 += 1){                                  
    				servo3.write(servoVar3);              
    				delay(timeDelay); 
    				// Serial.print(servoVar3);
    				// Serial.print (", ");
    				}    
    		estadoPos3 = 0;
    		swcs = 0;
    		digitalWrite (Led3, HIGH);    
    		delay (50);
    		} else {                   
 				if (estadoPos3 == 0){
    				servo3.attach(8);    // Adjuntamos el pin 8 a servo3   
    					for(servoVar3 = servoVarMax3; servoVar3 >= servoVarMin3; servoVar3 -= 1){                                   
    						servo3.write(servoVar3);              
    						delay(timeDelay); 
   							// Serial.print (servoVar3);
   							// Serial.print (", ");
    					}
    					estadoPos3= 1;
    					swcs= 0;    
    					digitalWrite(Led3, LOW);    
   			 			delay(50);             
      				}
    			}
				servo3.detach();
  				break;
  // Movimiento Servo 4 -------------------
 		case 4: 
 			servo4.attach(9);    //Adjuntamos el pin 9 a servo4
 			if (estadoPos4 == 1) {
   			for(servoVar4 = servoVarMin4; servoVar4 <= servoVarMax4; servoVar4 += 1){ 
    			servo4.write(servoVar4);              
    			delay(timeDelay); 
    			// Serial.print (servoVar4);
    			// Serial.print (", ");
    			}    
    	estadoPos4= 0;
    	swcs= 0; 
    	digitalWrite (Led4, HIGH);    
    	delay(50);
    	} else {                   
 			if (estadoPos4 == 0){   
    			for(servoVar4 = servoVarMax4; servoVar4 >= servoVarMin4; servoVar4 -= 1){                                   
    				servo4.write(servoVar4);              
    				delay(timeDelay); 
    				// Serial.print (servoVar4);
   					// Serial.print (", ");
    				}
    		estadoPos4= 1;
    		swcs= 0;
    		digitalWrite(Led4, LOW);    
    		delay(50);             
			}
    	}
 		servo4.detach();   
  		break;
	}

	delay(500);
	Serial.println("");	
	Serial.print(estadoPos1);
	Serial.print(", ");
	Serial.print(estadoPos2);
	Serial.print(", ");
	Serial.print(estadoPos3);
	Serial.print(", ");
	Serial.print(estadoPos4);
}

Si te ha gustado el articulo puedes o quieres ver más proyectos con servos y Arduino, aquí tienes una lista:

Arduino: moviendo un servo

Arduino: Brazo robot con servos ( Robot arm )

Arduino: Brazo robot con servos ( Robot arm ) Parte 2

Saludos!!

26 comentarios :

  1. Hola:Me parece muy interesante tu circuito. estoy intentando hacer lo mismo en mi maqueta pero no encuentro los valores de las resistencias que has colocado. Con las que yo estoy colocando no me funciona bien.
    Un saludo y gracias

    ResponderEliminar
    Respuestas
    1. Buenas Alberto, las resistencias son de 1K (1000ohm) y tienen que tener todas el mismo valor, si no, no funcionara. Espero te ayude, Saludos!!!

      Eliminar
    2. muchas gracias, mañana me las compro y lo pruebo.
      un saludo

      Eliminar
  2. Hola ya tengo todo montado tal y como pone aquí en este manual, pero tengo un problema, solo me funcionan dos servos, y uno funciona con dos pulsadores, el mismo servo actúa al pulsar tanto un pulsador como con otro, sabes de qué puede ser, a ver si me podéis ayudar, y ante todo muchas gracias por el trabajo que hacéis,

    ResponderEliminar
    Respuestas
    1. Buenas Tomovil Ford! ¿Has puesto el mismo número de pulsadores? en caso de que sea que si, ¿has comprobado las resistencias? en el programa viene un pequeño debug para comprobar en el monitor serie del IDE de Arduino (Ctrl+Mayus+M), en el te dirá el valor de cada pulsador y en función a esto puedes ajustar un poco mas los valores con respecto al servo. Espero haberte ayudado y si tu problema persiste, puedes mandarme una captura de pantalla del monitor serie a mi correo peyutron@gmail.com. Saludos!!!

      Eliminar
  3. Gracias. Peyutron , probaré lo que me dices, y te comentaré, bueno a ver si me entero bien, por qué estos verde en este tema, jeje, Mubchas gracias

    ResponderEliminar
  4. Está muy buena tu publicación y gracias por compartirla. Llevo mas de un año buscando información de cómo accionar servos con un pulsador. Una consulta, teniendo libres los pines 0 al 5, se podrá poner mas servos por placa? Esto con el fin de comprar menos placas solamente y ahorrar un poco.
    Reitero mis agradecimientos

    ResponderEliminar
    Respuestas
    1. Buenas! Si, no hay problema en usar esos pines, aunque te aconsejaría que el 0 y el 1 no los usará ya que puede dar problemas al cargar el sketch ya que son los pines que utiliza arduino para comunicarse con el PC, Saludos!!!!

      Eliminar
  5. Otra consulta, el código funciona en una placa Arduino Uno?

    ResponderEliminar
    Respuestas
    1. Buenas! En principio tiene que funcionar, de echo las pruebas las hice con UNO. Si te diera alguna error comentamelo y vemos la solución. Pero en principio tendría que ir bien. Saludos!!!

      Eliminar
    2. Hola, me he demorado un poco en poner en práctica tu aporte pero ya empecé. El fin de semana pasado lo monté en la protoboard con el Arduino UNO R3 y me dio varios errores. Uno de ellos es que los servos no van de un lado a otro conforme se presiona el pulsador sino que van y vuelven de inmediato a su posición original. Por otro lado, los LED no prenden de acuerdo al pulsador accionado sino que es un tanto aleatorio. Revisé una y mil veces las conexiones y creo que están bien. La fuente de energía para los servos la tuve que poner en forma independiente (no desde la misma placa) porque si lo hacía al parecer hacía corto circuito y suspendía la placa. Voy a hacer un esquema en Fritzing de las conexiones y lo subo. Saludos

      Eliminar
  6. hola, este montaje es justo lo que busco aunque pretendo mover 8 desvios. en el caso de hacerlo con arduino uno, como conectas los servos? por otro lado, los pulsadores como los has conectado?
    un saludo y gracias por adelantado

    ResponderEliminar
  7. Hola, me gustaría saber si los servos también se podrían controlar mediante interruptores y no botones. Muchas gracias por la ayuda.

    ResponderEliminar
    Respuestas
    1. Buenas Raúl, aquí tienes un ejemplo de cómo aplicar interruptores: https://paletosdelaelectronica.wordpress.com/2016/02/07/usando-un-interruptor-con-arduino sólo tendras que cambiar un par de cosas y funcionará. Saludos!!!

      Eliminar
  8. Hola, me gustaría saber si los servos también se podrían controlar mediante interruptores y no botones. Muchas gracias por la ayuda.

    ResponderEliminar
  9. Y en el caso de que se tratará de conmutadores, ¿sería el mismo esquema que el tuyo con los botones?

    ResponderEliminar
    Respuestas
    1. Buenas, no sirve para interruptores porque utilizo el puerto analógico para leer los pulsadores. Para poner interruptores tendrías que usar un pin digital por interruptor. Saludos!

      Eliminar
    2. He visto en la foto de el circuito que ha compartido arriba que desde la placa hacia los pulsadores hay 3 cables, ¿el verde hacia donde va? Perdón por mi pesadez, jajajja

      Eliminar
    3. Imagino que te refieres al gris, este va al puerto analógico, con la suma de resistencias hace que cada pulsador tenga un valor fijo, es como tener un potenciómetro, pero que no varía. Si te refieres a las líneas líneas que se ven como más apagadas son las que crea fritzing para que se vea cómo van las conexiones dentro de la placa de pruebas, no pasa nada, no hay que quedarse con la duda, saludos!!!

      Eliminar
  10. hola, perdonad si me meto por medio pero tengo una duda, solo necesitas un pin analógico para los 4 pulsadores? si no usas las resistencias funciona?
    un saludo y gracias de antemano

    ResponderEliminar
    Respuestas
    1. Buenas chuko72,sin resistencias el pin analógico solo leerá un pin al aire pero al ir sumando resistencias tienes siempreun valor fijo, saludos!!!

      Eliminar
  11. hola Peyutron, muchas gracias por responder. aclaradas las resistencias. la otra duda, un solo pin para los 4 servos? otra cosa, en el esquema, las lineas violetas son puentes entre los pulsadores?
    gracias por adelantado y perdona tanta pregunta pero es que me interesa mucho tu montaje y tengo muy pocos conocimientos de arduino

    ResponderEliminar
    Respuestas
    1. Buenas chuko72, un solo pin (y analógico) para los pulsadores, los servos cada uno a un pin. Las líneas violeta son puentes entre pulsadores para que la resistencia que va "sola" tenga contacto con todos los pulsadores. Saludos!!!

      Eliminar
    2. Muchas gracias por la aclaración. Por último, se pueden usar más servos y valdría la nano? Cambia el valor de las resistencias?
      Nuevamente gracias por adelantado

      Eliminar
  12. hola Peyutron, pudiste ver si es posible usar hasta 8 servos con la nano?
    un saludo

    ResponderEliminar