Servo MG995 no actúa

Hola a todos.

Me inicio en este foro debido a que no encuentro solución al problema que me ha surgido. He de decir que mis conocimientos son bastante limitados, pero trato de investigar y buscar soluciones dentro de mis posibilidades. Espero que desde el foro podáis echarme una mano ya que me imagino que para la gente que sabe será pan comido.

Os explico mi proyecto, de dónde he sacado la información y la situación en la que me encuentro actualmente.

Mi idea es construir un cortador de cables automático. Buscando por internet he encontrado estos dos vídeos que parecen de sencilla aplicación y podrían ajustarse a mis necesidades ( DIY Arduino based Automatic wire cutting Machine - YouTube y Arduino automated wire cutter - YouTube ). La idea es sencilla, el motor avanza un cierto número de pasos para arrastrar el cable y cuando termina, el servo se mueve para bajar el cutter y cortar el cable.

Del vídeo podemos sacar la lista de componentes:

  • Arduino Nano
  • Motor NEMA 17 + extructor
  • A4988
  • Servo Motor (tengo dos, uno MG995 y otro S3003)
  • LCD 16x2
  • Placa PCB
  • Potenciómetro 10Kohm
  • Pulsadores y terminales PCB

El código de arduino es el siguiente:

//------------------------------- librarys ----------------------------------

#include <LiquidCrystal.h>
#include <Servo.h>
 
//------------------------------- lcd ----------------------------------
LiquidCrystal lcd(12, 11, 2, 3, 4, 5);
 
//------------------------------- stepper ----------------------------------
#define stepPin 7
#define dirPin 8
 
//------------------------------- servo ----------------------------------
Servo snippers;
#define servo 10
#define openAngle 90
#define closedAngle 0
 
//------------------------------- input ----------------------------------
 
#define leftButton 14
#define rightButton 9
#define upButton 15
#define downButton 6
 
//------------------------------- user settings ----------------------------------
unsigned int wireLength = 0;
unsigned int wireQuantity = 0;
 
//------------------------------- system settings ----------------------------------
int state = 0;
int incrementSpeed = 1;
int previousWireLength = 0;
int previousWireQuantity = 0;
float mmPerStep = 0.1549;
 
 
void setup() {
  Serial.begin(9600);
 
 
  lcd.begin(16, 2); //LCD columns and rows
 
 
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(leftButton, INPUT_PULLUP);
  pinMode(rightButton, INPUT_PULLUP);
 
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
 
  snippers.attach(servo);
  
  snippers.write(openAngle);
   
  delay(1000);
}
 
void loop() {
  if (!digitalRead(rightButton)){
    if(state == 5){
      state = 0;
    }
    else{
      state += 1;
    }
    delay(200);
    lcd.clear();
  }
  if (!digitalRead(leftButton) && state > 0 && state < 4){
    state -=1;
    delay(200);
    lcd.clear();
  }
 
 
  switch (state){
    case 0:
      homeScreen();
      break;
    case 1:
       chooseWireLength();
       break;
    case 2:
      chooseWireQuantity();
      break;
    case 3:
      confirm();
      break;
    case 4:
      currentlyCutting();
      break;
    case 5:
      finishedCutting();
      break;
  }
 
}
 
 
void homeScreen(){
  lcd.setCursor(0, 0);
  lcd.print("CORTADOR CABLES");
  lcd.setCursor(11, 1);
  lcd.print("SIG.>");
  delay(100);
}
 
 
void chooseWireLength(){
  wireLength = changeValue(wireLength);
 
  //clear LCD if required
  if(previousWireLength != wireLength){
    lcd.clear();
    previousWireLength = wireLength;
  }
 
  //Display information on LCD
  lcd.setCursor(0, 0);
  lcd.print("LONGITUD:" + (String)wireLength + "mm");
  displayNavigation();
}
 
void chooseWireQuantity(){
  wireQuantity = changeValue(wireQuantity);
 
  //clear LCD if required
  if(previousWireQuantity != wireQuantity){
    lcd.clear();
    previousWireQuantity = wireQuantity;
  }
 
  //Display information on LCD
  lcd.setCursor(0, 0);
  lcd.print("CANTIDAD:" + (String)wireQuantity);
  displayNavigation();
}
 
void confirm(){
  lcd.setCursor(0, 0);
  lcd.print((String)wireLength + "mm x " + (String)wireQuantity + "pcs");
  lcd.setCursor(0, 1);
  lcd.print("<VOLVER");
  lcd.setCursor(9, 1);
  lcd.print("INICIO>");
  delay(100);
}
 
void currentlyCutting(){
  lcd.setCursor(0, 0);
  lcd.print((String)0 + "/" + (String)wireQuantity);
  lcd.setCursor(0, 1);
  lcd.print("???s");
  int stepsToTake = (int)wireLength/mmPerStep;
  for(int i = 0; i < wireQuantity; i++){
    unsigned long timeForOneCycle = millis();
    digitalWrite(dirPin,HIGH);
    for(int x = 0; x < stepsToTake; x++) {
      digitalWrite(stepPin,HIGH);
      delayMicroseconds(500);
      digitalWrite(stepPin,LOW);
      delayMicroseconds(500);
    }
   
    lcd.setCursor(0, 0);
    lcd.print((String)(i+1) + "/" + (String)wireQuantity);
 
    snippers.write(closedAngle);
    delay(600);
    snippers.write(openAngle);
    delay(600);
   
    lcd.setCursor(0, 1);
 
    unsigned long timeRemaining = ((millis() - timeForOneCycle)*(wireQuantity - (i+1)))/1000;
    lcd.print((String)timeRemaining + "s    ");
   
  }
  wireLength = 0;
  wireQuantity = 0;
  state = 5;
}
 
void finishedCutting(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CORTADO COMPLETO");
  lcd.setCursor(11, 1);
  lcd.print("SIG.>");
  delay(100);
}
 
 
int changeValue(int currentValue){
  if (!digitalRead(upButton)) {
    delay(100);
    currentValue += incrementSpeed;
    incrementSpeed ++;
    
  }
  if (!digitalRead(downButton)) {
    if(currentValue - incrementSpeed >= 0){
      delay(100);
      currentValue -= incrementSpeed;
      incrementSpeed ++;
    
    }
    else{
      currentValue = 0;
    }
  }
  if (digitalRead(downButton) && digitalRead(upButton)){
    incrementSpeed = 1;
  }
  return currentValue;
}
 
void displayNavigation(){
  lcd.setCursor(0, 1);
  lcd.print("<VOLVER");
  lcd.setCursor(11, 1);
  lcd.print("SIG.>");
  delay(100);
}

Una vez montado todo el circuito, y tras leer que es aconsejable alimentar el servo desde una fuente externa (en el vídeo no lo hacen), así lo hago a través de una protoboard, eso sí, conectando la tierra con la del arduino. Con lo cuál tengo tres alimentaciones:

  • La primera, a través de USB para el arduino.
  • La segunda, al A4988, con un trasformador a 12V 1,25A.
  • La tercera, al servo con 4 pilas alcalinas AA.

El problema:

Pues bien, veo que se ejecuta bien el sketch, el motor avanza (no lo que debería, pero ya ha ajustado el parámetro para que me coincida con la longitud deseada) pero el servo no actúa entre cada movimiento del motor. He comprobado el servo con un código de ejemplo que hace un barrido de 0 a 180º y funciona correctamente alimentándolo externamente, pero al incluirlo con el resto de elementos, no se mueve.

Desconozco si el problema viene del código, o de la alimentación, pero ahora mismo no encuentro más soluciones.

Siento la parrafada pero seguro se me quedaron cosas por decir. Si alguien puede ayudarme y necesita más datos, aquí estaré.

Muchas gracias y un saludo.

Ese servo requiere mucha corriente y la opcion de 12V 1.25A es la mejor que intentaste usar.

Qué es lo que no funcionó cuando agregaste cosas, eso no lo he comprendido.

El resto de los elementos son el LCD y demás?

El transformador de 12V 1,25A nunca lo he probado con el servo, por el tema del voltaje, siempre ha sido para el NEMA17. Al servo lo alimento con las 4 pilas alcalinas AA.

La prueba que he hecho es, en una protoboard, conectar servo y arduino solamente, alimentándolos de manera independiente (USB y 4 pilas AA) con un sketch de barrido de 0 a 180º, simplemente por ver si el servo funcionaba y no estaba ahí el problema.

Pero al conectar todo a la PCB (arduino, LCD, NEMA, A4988, servo) todo funciona menos el servo, es decir, el programa arranca bien, puedo seleccionar la longitud y cantidad bien, inicio y veo en la LCD que se ejecuta y el NEMA se mueve y hace avanzar el cable. Pero entre cada ciclo del NEMA, debería actuar el servo, y no lo hace.

¿Debería probar a alimentar el servo con 12V? ¿Lo puedo llegar a quemar? Teóricamente viene para tensiones entre 4,8 y 7,2 V.

Muchas gracias y un saludo

He vuelto a testear el servo, con alimentacion externa, con una fuente de 5v y 5A. No he conseguido moverlo. Con lo cual no creo que el problema venga de la alimentación.

Esta vez detecto que al conectar el cable de señal del servo al pin 10 del arduino, el servo comienza a vibrar y da igual que ejecute el sketch o no, siempre está vibrando. En cambio, si lo desconecto y sólo le dejo la alimentación, no vibra.

¿Podrá el problema estar en el código?

Muchas gracias.

Mi.,

Mi consejo es que vayas files /ejemplos y ahi encotraras programa de pruebas para la mayoria de los modulos. Ve y selecionas stepper / prueba stepper de una revolucion. Asi podras eliminar si es problema del sktch pero ten segurode que lo tienes bien instalado. Sino no haz hecho un google buscando informacio/tutoria de como alambrar y programar un stepper,y encotraras varias tutorias de como manejar un stepper.

Para probar el servo ,haz lo que te comentan arriba,ve a Archivo->Ejemplos->Servo->Sweep
-Conecta el cable de señal del servo al pin que indica el sketch que has abierto.
-Comprueba que las pilas tienen carga y conectalas a la alimentacion del servo (respeta la polaridad...) .Del gnd del portapilas saca otro cable que conectaras a cualquier pin de gnd de la placa arduino.
-carga el sketch del ejemplo en la placa y deberia funcionar el servo.

Con el código de ejemplo Sweep el servo funciona correctamente. Con lo cuál, el servo no esta dañado.

En cuanto cargo el código del cortador de cables (el que está en el primer mensaje) soy incapaz de que el servo se mueva, solamente vibra en ocasiones.

He estado modificando un poco los Delay() en el ejemplo Sweep para ver como se comporta el servo y veo que en determinadas ocasiones el comportamiento del servo es similar a cuando cargo el código del cortador de cables, es decir se queda vibrando y en ocasiones sin hacer nada.

Con lo cuál casi que descarto que sea problema de alimentación y creo que va más por el sketch.

en el setup mueves el servo a 90º ,eso lo llega a hacer?

Hi,
Acuerdate que tienes que tener cuidado con los delays pues los pulsos tienen que ser de cierto tiempo/duracion. Posiblemente esta enviando pulso que son muy pequenos y tambien tienes que tener en cuenta que tienes que darle tiempo al stepper para que se mueva, Si los mandas muy rapaidos el stepper no se va mover. Si buscas las especificaciones dice que los pulsos deben de ser de ser 20 ms "duty cycle" con una frequencia de 50 ciclos.