delay() se vuelve loco usando servo

Me pasa algo muy extraño.

He conectado un servo MG996R a arduino, con intención de manejarlo con un potenciometro. Vamos, el típico ejemplo "Knob" de la librería "Servo.h".

Pues lo curioso es que si conecto todo el sistema mediante usb, ¡la comunicación Serial no funciona! Extrañamente el servo interfiere.

Suponiendo que se trataba de que el servo que uso necesita mucha alimentación (aunque supuestamente con 5v debe funcionar) conecté arduino además a una toma de 12V por el jack. Entonces, ya sí que funcionó la conexión serial (con la que monitorizo los valores del potenciometro).

Ahora, lo curioso es que fijé un delay de 100ms, sobran para el servo y además no envía demasiados datos de manera innecesaria por serial. Pues siempre llega un momento, a los pocos segundos, que ya el servo no hace caso a los movimientos del potenciómetro y ¡el serial comienza a mostrar datos como si la parte del delay fuese inexistente! como si el loop no tuviese ningún delay o lo tuviese a 1ms.

He hecho varias pruebas, una de ellas dos bucles for que hacen que el servo gire totalmente a su izquierda y luego totalmente a su derecha con un delay de 30ms. Pues igualmente llega un momento que simplemente se detiene, como si el delay no estuviese haciendo efecto.

La verdad es que estoy intrigado de porqué arduino se comporta así, supongo que alimentando el servo externamente debería solucionarse, pero, ¿porqué creeis que pasa eso? ¿cómo solucionarlo sin alimentación externa?

Un saludo!

Prueba a alimentar el servo con 6v directamente y conecta tambien el negativo de la fuente de alimentación que estes usando para el servo al GND de Arduino.
Saludos.

Creo que son dos cosas. Lo primero te aconsejo alimentar siempre los servos con un alimentador externo tal como dice chocala. Para lo del retardo pon el código que estás utilizando ya que no sé si podría ser algo de la programación.

Hola, gracias por las respuestas.

Yo sé que casi con toda seguridad se solucionará todo haciendo lo indicado por chocala, sin embargo lo que verdaderamente me gustaría es que alguien supiese qué es lo que está pasando, si se trata de picos que afectan a arduino, corriente de retroceso, lo que sea, y así poder pensar si se solucionaría fácilmente con condensador, diodo y demás. No para usar el servo de ese modo, sino para entender lo que ocurre y saber como se soluciona, aunque finalmente use alimentación externa.

También decir, como curiosidad que en una de las primeras pruebas, alimentando por usb, el portatil que usaba dió un pantallazo azul y creo que no fue simple casualidad :stuck_out_tongue_closed_eyes:.

El código como digo, he usado primeramente el ejemplo Knob:

#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 
 
int potpin = A0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin 
 
void setup() 
{ 
  pinMode(potpin, INPUT); // declare the ledPin as as OUTPUT
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Serial.begin(9600);
} 
 
void loop() 
{ 
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023) 
  val = map(val, 0, 1023, 0, 179);     // scale it to use it with the servo (value between 0 and 180) 
  myservo.write(val);                  // sets the servo position according to the scaled value 
  delay(100);                           // waits for the servo to get there 
  Serial.println(val);
}

Tiene añadido un muestreo por serial, cada 100ms, que llegado un momento el servo deja de funcionar y el muestreo por serial va "a toda leche" como si el delay no existiese.

Ahora estoy usando un ejemplo para recorrer el servo en las dos direcciones de manera secuencial y cíclica, también muy sencillo:

#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 
 
int potpin = A0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin 
 
void setup() 
{ 
  pinMode(potpin, INPUT); // declare the ledPin as as OUTPUT
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
} 
 
void loop() 
{ 
  for(int i=0; i<179; i++){
    myservo.write(i);
    delay(50);
    i+=2;
  }
  for(int i=179; i>0; i--){
    myservo.write(i);
    delay(50); 
    i-=2;
  }
}

Que como dije, llega un momento que el servo no funciona y probablemente sea porque de nuevo el delay no es respetado y sabemos que necesita de cierto delay para actualizar la posición del servo.

¿No os intriga tanto como a mi? jejej

No te entendí que te hace el mismo efecto con el ejemplo Knob. La verdad es que es extraño. No obstante en el segundo código creo que te sobra lo de i+=2 y i-=2 puesto que en la instrucción for ya pones i++ e i--, si quieres que vaya más rápido puedes sustituir estos últimos por los primeros o por i+=2, o i+=3, etc.
Sobre el fallo la verdad que lo primero es probar con alimentación independiente para el servo. Si así funciona tema resuelto y si no a seguir investigando con el código.

Hola.

Sí, desde luego sobra el i+=2, olvidé borrarlo a la hora de adjuntar el código, solo lo usé para pequeñas pruebas para ver como se comportaba el servo, ya sabes lo que se chapucea a veces buscando fallos.

Acabo de probarlo con una batería de 6V a medio cargar, funciona de maravilla tal y como era de esperar (eso sí, sin olvidar interconectar gnd), vamos, del código ya sabía que no era aunque no está de más descartarlo totalmente.

Supongo que me quedaré con la duda de porqué interfiere en el buen funcionamiento de arduino si no se usa alimentación externa jej.

Gracias por las respuestas

Seguramente sea por consumo del servo, el arduino puede suministrar hasta 40ma y si el servo consume mas ya empiezan los problemas, de ahi lo de usar una fuente externa.

Que batería de 6V utilizasteis para que os funcione. Yo he probado con el MG996R y como batería externa 4 pilas alcalinas de 2200mhA, y con un delay(15) el arduino se resetea constantemente. Creo que el problema viene porque tiene unos picos de consumo muy altos. En la hoja de especificaciones pone que llega a tener 2.5A de consumo, y creo que lo que sucede es que eso picos no los aguantan las baterías.

Se que el hilo es de hace tiempo, pero si alguien tiene la solución agradecería un mensaje.

4 pilas dan 1.3x5 = 5.2 volts si lo alimentas por donde debe ser menos caida del regulador apenas te deja margen para que funcione el arduino.
Cuando se activan los servos tienes un pico de consumo (como bien dijiste) que hace que caiga la tensión a un valor que resetea el arduino y vuelta a comenzar.

Debes llegar a 7V como entrada externa minima asi que suma 2 pilas mas.