O control dos motores

Imos facer unhas prácticas para controlar o movemento do mClon.

O controlador de motores:

Para poder programar o movemento dos motores debemos dar as instrucións precisas para que os motores se movan nun sentido ou no outro e a unha velocidade determinada.

No mClon o motor esquerdo polos pins AIN1(D7, sentido de xiro) e PWMA (D6, velocidade) e o motor dereito está controlado polos pins  do driver BIN1(D4, sentido de xiro) e PWMB (D5, velocidade)

Declaración de variables

O primeiro que facemos, no inicio do programa, é definir os pins da placa cos que imos actuar.

const int PWMA = 6;    // Pins motor esquerdo (m1)
const int AIN1 =7;

const int PWMB = 5;     // Pins motor dereito (m2)
const int BIN1 =4;

Configuración

Temos que configurar os pins anteriores como saída, pois por defecto os pins dixitais considéranse entradas.

Tamén imos poñer a instrución de que agarde a que o pulsador estea premido para evitar que comece a moverse nada máis cargar o programa e nos dea tempo a poñelo no chan. Poñémolo dentro do setup porque queremos que se execute unha soa vez.

O pulsador está conectado no pin analóxico A7 en pull-up. Os valores que nos pode dar son 0 cando está premido e cerca de 1023 cando non. A instrución while fai que agardemos mentres se cumpra que o pulsador está desactivado.

// Configuración:

void setup(){
  pinMode(PWMA, OUTPUT);        // Configuramos os pins
  pinMode(AIN1, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(BIN1, OUTPUT);

  while(analogRead(A7)>100);  // agardamos mentres non se pulse o botón
}

Funcións

Tal e como están conectados os motores no mClon o motor esquerdo móvese cara adiante cando AIN1=0, e cara atrás cando AIN1=1, e o motor dereito ao revés, móvese cara adiante cando BIN1=1 e cara atŕas cando BIN1=0. Pode ser moi lioso programar o movemento dando estes valores, así que imos crear unhas funcións para cada un dos motores de maneira que poidamos controlalos de forma sinxela.

Para indicar o sentido de xiro escribimos 1 cando queremos ir cara adiante e -1 cara atrás
Para indicar a velocidade introducimos un valor de 0 a 255

// motor esquerdo m1

void m1(int sentido, int velocidade) {
  if (sentido > 0){
    digitalWrite(AIN1, 0);     
  }
  else{
    digitalWrite(AIN1, 1);   
  }
  analogWrite(PWMA, velocidade);
}

// Motor dereito m2
  
void m2(int sentido, int velocidade) {
  if (sentido > 0){
    digitalWrite(BIN1, 1);     
  }
  else{
    digitalWrite(BIN1, 0);   
  }   
  analogWrite(PWMB, velocidade);
}

Bucle

Dentro do bucle loop() escribimos todas as instrucións que queremos que se executen continuamente.

Por exemplo, se queremos que o robot se mova cara adiante durante 1 segundo a velocidade media, cara atrás outro segundo e así indefinidamente invocaremos as funcións m1 e m2 dos motores da seguinte maneira:

void loop() {

  //avanza 1 segundo
  m1(1, 125);   
  m2(1, 125);
  delay(1000);

  //retrocede 1 segundo
  m1(-1, 125);   
  m2(-1, 125);
  delay(1000);

}

O programa completo quedaría así:

// Declaración de variables:

const int PWMA = 6;    // Pins motor esquerdo
const int AIN1 =7;

const int PWMB = 5;     // Pins motor dereito
const int BIN1 =4;

// Configuración:

void setup(){
  pinMode( PWMA, OUTPUT);        // Configuramos os pins
  pinMode( AIN1, OUTPUT);
  pinMode( PWMB, OUTPUT);
  pinMode( BIN1, OUTPUT);

  while(analogRead(A7)>100);  // agardamos mentres non se pulse o botón

}

/***** Funcións: *****/
// sentido: adiante: 1, atrás: -1
// velocidade: 0 -> 255

// motor esquerdo m1

void m1(int sentido, int velocidade) {
  if (sentido > 0){
    digitalWrite(AIN1, 0);     
  }
  else{
    digitalWrite(AIN1, 1);   
  }
  analogWrite(PWMA, velocidade);
}

// Motor dereito m2
  
void m2(int sentido, int velocidade) {
  if (sentido > 0){
    digitalWrite(BIN1, 1);     
  }
  else{
    digitalWrite(BIN1, 0);   
  }   
  analogWrite(PWMB, velocidade);
}


/***** Bucle *****/

void loop() {

  //avanza 1 segundo
  m1(1, 100);   
  m2(1, 100);
  delay(1000);

  //retrocede 1 segundo
  m1(-1, 100);   
  m2(-1, 100);
  delay(1000);

}

Agora falta que lle indiques que xire manténdose na súa posición (un motor vai cara adiante e outro cara atrás) ou que avance xirando (unha roda vai a máis velocidade cá outra). Deberás completar o programa anterior para facer as seguintes prácticas.

Prácticas:

1. Unha nova función: Cambia as funcións dos motores de xeito que poidamos programalos executando as instrucións m1(100); para que o motor esquerdo se mova cara adiante e m1(-100); para que se mova cara atrás. Fai o mesmo coa función do motor dereito.

2. Unha función para os dous motores: Cambia as funcións de xeito que con unha única instrución controlemos o movemento de ambos motores. Por exemplo, ao escribir m(100, -100); o motor esquerdo avanza e o motor dereito retrocede a velocidade 100.

3. Límites: Os sinais PWM só poden tomar valores desde 0 a 255. Engade o necesario para que se alguén escribe un valor maior, por exemplo m1(500); a instrución velocidade tome o valor 255.

4. Movemento: Deseña un programa que execute as seguintes accións consecutivas:

Cando prememos no pulsador:

  • O robot avanza durante 1 segundo.

  • O robot xira 1 segundo cara á esquerda

  • O robot retrocede durante 1 segundo

  • O robot xira 1 segundo cara á dereita

  • O robot avanza xirando cara á esquerda durante 2 segundos

  • O robot avanza xirando cara á dereita durante 2 segundos

  • O robot detense.

Retos:

Rodear lata

Sitúa o robot a 15 cm dunha lata de refresco. Debes programar os movementos necesarios para que a rodee sen tocala e, unha vez rodeada, avance na mesma dirección que tiña inicialmente.

Xira cara á esquerda -> avanza -> avanza xirando cara á dereita -> xira cara á esquerda -> avanza, … Controla as velocidades dos motores e os tempos para que o robot rodee a lata sen chocar contra ela.