Para introducir una serie de detalles útiles a nuestros robots con servomotores en las ruedas, un apartado importante es la velocidad. Seguramente habremos comprobado que no alcanzan tanta velocidad como nos gustaría. Pero realmente no nos interesa tanto la velocidad en linea recta; sino la velocidad de rotación o velocidad respectiva de una rueda con otra.

Si alguna vez hemos hecho una carrera de robots sin ninguna forma de control remoto para ir de un punto A a un punto B, veremos que no podemos aplicar la misma velocidad en linea recta que en los giros. Ya que un pequeño intervalo de tiempo a mucha velocidad, puede hacer que nuestro robot de unas cuantas vueltas sobre sí mismo.

Es por ello, que podemos aplicar unas funciones que son muy útiles para aplicar y con las que se puede establecer facilmente un nivel de velocidad de 0 a 100. De esta manera, cuando queramos determinar giros, les podremos definir una velocidad para aportar más precisión y para linea recta, una velocidad mayor.

Este modelo de programación se aplica a dos servomotores con el servomotor izquierdo en el pin 9 y el servomotor derecho en el pin 10.

 

Estas funciones ofrecen la posibilidad determinar la velocidad, incluso para calibración dinámica. Es decir, podemos comunicar por Bluetooth, cuál es la velocidad que queremos en nuestro robot para cada caso y hacer más preciso el funcionamiento por control remoto enviando el valor desde una aplicación.

#include <Servo.h>

int vel;

Servo LeftServo;
Servo RightServo;

void Servo_attach() {
  LeftServo.attach(9);
  RightServo.attach(10);
}

void Servo_detach() {
  LeftServo.detach();
  RightServo.detach();
}

void forward(int vel) {
  if (vel > 100){vel = 100;} 
  Servo_attach();
  RightServo.write(map(vel, 0,100,90,180));
  LeftServo.write(map(vel, 0,100,90,0));
}

void turn_left(int vel) {
  Servo_attach();
  LeftServo.write(map(vel, 0,100,90,180));
  RightServo.write(map(vel, 0,100,90,180));
}

void stop() {
  LeftServo.write(90);
  RightServo.write(90);
  Servo_detach();
}

void backwards(int vel) {
  Servo_attach();
  LeftServo.write(map(vel, 0,100,90,0));
  RightServo.write(map(vel, 0,100,90,180));
}

void turn_right(int vel) {
  Servo_attach();
  LeftServo.write(map(vel, 0,100,90,0));
  RightServo.write(map(vel, 0,100,90,0));
}

En el próximo tutorial, veremos que este método nos sirve para reducir la velocidad, pero cuando queramos ir hacia delante se puede apreciar un ligero giro de una rueda que es más rápida que la otra. Por ello, necesitaremos calibrar esta diferencia de giro en el tutorial posterior para determinar distintas velocidades en linea recta proporcionalmente a la velocidad que buscamos.

Mientras tanto, aprovechando el tutorial para el robot Beetle, vamos a realizar un control para que la velocidad de nuestro robot, sea proporcional a la diferencia entre los niveles de luz que reciben los sensores de luz. De esta manera, cuanto más diferencia de luz, más rápido se movera, y cuando la luz se haga más tenue y homogénea, el robot reducira su velocidad hasta pararse.

 

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

int vel;
char BTData;
int LDR_diff;
int threshold;
int diff_threshold;
int fwd_amplifier = 30;

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

void Servo_attach() {
  LeftServo.attach(9);
  RightServo.attach(10);
}

void Servo_detach() {
  LeftServo.detach();
  RightServo.detach();
}

void forward(int vel) {
  if (vel > 100){vel = 100;} 
  Servo_attach();
  RightServo.write(map(vel, 0,100,90,180));
  LeftServo.write(map(vel, 0,100,90,0));
}

void turn_left(int vel) {
  Servo_attach();
  LeftServo.write(map(vel, 0,100,90,180));
  RightServo.write(map(vel, 0,100,90,180));
}

void stop() {
  LeftServo.write(90);
  RightServo.write(90);
  Servo_detach();
}

void backwards(int vel) {
  Servo_attach();
  LeftServo.write(map(vel, 0,100,90,0));
  RightServo.write(map(vel, 0,100,90,180));
}

void turn_right(int vel) {
  Servo_attach();
  LeftServo.write(map(vel, 0,100,90,0));
  RightServo.write(map(vel, 0,100,90,0));
}


void setup() {
  Serial.begin(38400);
  comm.begin(38400);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);

  LeftServo.attach(9);
  RightServo.attach(10);
  LDR_diff = (int)(0);
  threshold = (int)(300);
  diff_threshold = (int)(100);

}

void loop() {
  LDR_diff = analogRead(A0) - analogRead(A1);
  Serial.print(analogRead(A0));
  Serial.print(",");
  Serial.println(analogRead(A1));
  if (abs(LDR_diff) > diff_threshold) {
    if (LDR_diff > diff_threshold) {
      Serial.println("LEFT");
      turn_left(abs(LDR_diff));
    } else if (LDR_diff < diff_threshold * -1) { Serial.println("RIGHT"); turn_right(abs(LDR_diff)); } } else if (analogRead(A0) > threshold && analogRead(A1) > threshold) {
    Serial.println(100*abs(LDR_diff)/diff_threshold);
    forward(100*abs(LDR_diff)/diff_threshold+fwd_amplifier);
  } else if (analogRead(A0) < threshold && analogRead(A1) < threshold) {
    stop();
  }

}

Este truco también lo utilizaremos para otros robots con motores DC que proporcionan más velocidad y suelen dar más problemas a la hora de calibrar.