Como vimos en un tutorial anterior. nos creamos unas funciones que nos permitían reducir la velocidad de nuestros servomotores de rotación continua, para que los giros no fueran demasiado bruscos y así poder controlar mejor la dirección de nuestro robot.

Pero nuestra solución solo reducía la velocidad, proporcionalmente a un valor de 0 a 100, pero si nos fijamos, en linea recta, entre las dos ruedas, una sigue girando más que la otra.

Esto se debe a que los servomotores no son todos iguales, y el número que se determina con una señal PWM no es la misma para unos servomotores que para otros. Es decir, que nuestra proporcionalidad no se ajusta en velocidad justo en el 90 que se supone que determina la velocidad 0.

Hay algunos servomotores que permiten calibrar esta señal PWM con el giro par establecer un offset mediante un potenciometro integrado y a la vista, como aparece en la imagen. Esta sería la solución rápida de calibración pero puede no ser nuestro caso.

 

Lo que si sabemos es que una vez ajustado el punto en el que los dos servomotores comparten una referencia , podemos desarrollar las funciones del tutorial anterior con unas nuevas, que nos permiten mover nuestro robot en linea recta con el mínimo error de giro.

Por ello, añadimos una variable velref que identifica esa referencia y ya sea creciente o decreciente, nuestro robot puede interpretar que sus ruedas giran solidariamente una con la otra,  cambiando ese valor 90; que era la referencia de nuestra velocidad 0 con la nueva.

Para sacar este valor, se puede copiar el código que hay abajo y que nos permitirá conectar mediante Bluetooth a una aplicación desarrollada con App Inventor y que nos permite calibrar estos dos parámetros de velocidad mediante dos sliders.

  • Descarga el proyecto de App Inventor en el siguiente enlace.

De esta manera podemos ir ajustando hasta dar con las dos velocidades que se acoplen adecuadamente.

En este caso, nuestras velocidades son 90 y 100; para una velocidad muy baja. Y la nueva velocidad de parada será de 95.

Desde ArduBlockly podemos crear las siguiente funciones.

Puede ocurrir a veces, que las velocidades difieran en 1 si las velocidades obtenidas fueran 89 y 100. La mitad sería 94.5, así que escogemos 94 para un motor y 95 para el otro.

En este caso se puede utilizar la variable vplus, para añadir o contrarrestar esa diferencia de 1 para dos ceros separados. En caso de no aplicarse, deberemos dejar  igualar el valor de la variable vplus a cero.

 

#include <Servo.h>
#include <SoftwareSerial.h>

char BTdata;
int BTNumber;

SoftwareSerial comm(2,3);
 
Servo LeftServo;
Servo RightServo;

int velref;
int maxvel;
int vel;
int vplus;

// Describe this function...
void Servo_attach() {
  LeftServo.attach(5);
  RightServo.attach(6);
}

// Describe this function...
void Servo_detach() {
  LeftServo.detach();
  RightServo.detach();
}

// Describe this function...
void forward(int vel) {
  Servo_attach();
  LeftServo.write((map(vel,0, 100, velref , 0)));
  RightServo.write((map(vel,0, 100, velref + vplus , 180)));
}

// Describe this function...
void backwards(int vel) {
  Servo_attach();
  LeftServo.write((map(vel,0, 100, velref , 180)));
  RightServo.write((map(vel,0, 100, velref + vplus , 0)));
}

// Describe this function...
void turn_right(int vel) {
  Servo_attach();
  LeftServo.write((map(vel,0, 100, velref , 0)));
  RightServo.write((map(vel,0, 100, velref + vplus , 0)));
}

// Describe this function...
void turn_left(int vel) {
  Servo_attach();
  LeftServo.write((map(vel,0, 100, velref , 180)));
  RightServo.write((map(vel,0, 100, velref + vplus , 180)));
}

// Describe this function...
void stop() {
  LeftServo.write(velref);
  LeftServo.write(velref);
  Servo_detach();
}



void setup() {

  Serial.begin(38400);
  comm.begin(38400);

  BTdata = (char)(('0'));
  BTNumber = (int)(0);
  LeftServo.attach(5);
  RightServo.attach(6);

  velref = (int)(91);
  maxvel = (int)(60);
  vplus = (int)(1);

  for(int i= 0 ; i < 100; i=i+10){ Serial.print("Vel: ");Serial.println(i); forward(i); delay(500); } for(int i= 100 ; i >0; i=i-10){
    Serial.print("Vel: ");Serial.println(i);
    forward(i);
    delay(500);
  }
  stop();
}

void loop() {
  if (comm.available()) {
    BTdata = (comm.read());
    Serial.print("Data: ");Serial.println(BTdata);
    if (BTdata == ('C')) {
      BTNumber = ((comm.readString()).toInt());
      Serial.print("Number: ");Serial.println(BTNumber);
      LeftServo.write(BTNumber);
      
    }
    if (BTdata == ('V')) {
      BTNumber = ((comm.readString()).toInt());
      Serial.print("Number: ");Serial.println(BTNumber);
      RightServo.write(BTNumber);
    }
  }

}



Con esta calibración realizada ya podemos seguir desarrollando otras cualidades para nuestros robots sin necesidad de preocuparnos de fallos en la dirección.