Projeto Atual:

Programando Aplicativos com Javascript

08/01/2020

Programação e Robótica II - Parte 7

Servomotor

Instalamos um servomotor na base do sensor de distância, para poder virar o sensor e calcular distâncias à direita e à esquerda do carro, além da distância à frente que já calculávamos. Com isso, se o carro encontrar um obstáculo, podemos decidir para que lado virar.

O servomotor tem que ficar ligado a um pino PWM do Arduino. Escolhemos o pino 10, que estava livre. Quando fizemos os primeiros testes, descobrimos que o uso do servomotor no pino 10 com PWM juntamente com o controle do motor no pino 9 com PWM causavam mal funcionamento. Para resolver o problema, tivemos que trocar as ligações dos pinos 9 e 5 do motor. Tivemos também que fazer alterações na placa de protótipos, para conseguir mais pontos de conexão ao terra (GND).




Tivemos que alterar a função acionar_motores(), para trocar os sinais enviados para os pinos 5 e 9. Por termos escondido toda a lógica das ligações dentro desta função, apenas ela teve que ser modificada. Esta é uma das vantagens do uso de funções em um programa.

Aproveitamos para adicionar um ajuste de velocidade, para compensar uma diferença de rotação que impedia o carro de andar em linha reta.

Esta é a listagem da função alterada:

// Aciona os motores de acordo com parâmetros:
// Direcao:
// -1 - Para trás
// 0 - Parar
// 1 - Para frente
// 2 - Para a direita
// 3 - Para a esquerda
// Velocidade altera potencia dos motores
void acionar_motores() {
  ajuste_velocidade = 0;
  if (direcao == 0) {
    digitalWrite(4, LOW);
    digitalWrite(9, LOW);
    analogWrite(6, 0);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
    analogWrite(5, 0);
  } else {
    if (direcao == 1) {
      digitalWrite(4, HIGH);
      digitalWrite(9, LOW);
      digitalWrite(7, HIGH);
      digitalWrite(8, LOW);
      ajuste_velocidade = velocidade / 10;
    } else if (direcao == 2) {
      digitalWrite(4, LOW);
      digitalWrite(9, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(8, LOW);
    } else if (direcao == 3) {
      digitalWrite(4, HIGH);
      digitalWrite(9, LOW);
      digitalWrite(7, LOW);
      digitalWrite(8, HIGH);
    } else if (direcao == -1) {
      digitalWrite(4, LOW);
      digitalWrite(9, HIGH);
      digitalWrite(7, LOW);
      digitalWrite(8, HIGH);
    }
    analogWrite(6, (velocidade + ajuste_velocidade));
    analogWrite(5, velocidade);
  }
}



Criamos a função posicionar_sonar() que direciona o sensor de distância no ângulo indicado. O ângulo de 90° aponta para a frente. 10° aponta para a direita, e 170°, para a esquerda. Não utilizamos zero e 180° para não desgastar o mecanismo do servo nestas posições. No código principal, usamos a nova função combinada com distancia() para obter as distâncias à esquerda e à direita, e decidir para que lado desviar.



Quando testamos o código, o funcionamento não foi o esperado. Descobrimos que o Ardublockly estava convertendo a lógica em blocos de forma errada ao gerar o programa intermediário em C/C++. As ativações da função distancia() não estavam sendo convertidas corretamente. Tivemos que alterar o código em C/C++ diretamente para corrigir o problema.

Fragmento de código gerado pelo Ardublocky:

void loop() {
  if (distancia() < 30) {
    parar();
    angulo_sonar = 10;
    posicionar_sonar();
    espaço_direita = 0; // Errado! Deveria ser = distancia().
    angulo_sonar = 170;
    posicionar_sonar();
    espaco_esquerda = 0; // Errado! Deveria ser = distancia().
    angulo_sonar = 90;
    posicionar_sonar();
    if (espaco_esquerda == 0 || espaco_esquerda > espaco_direita) {
      esquerda();
    } else {
      direita();
    }
  } else ...


Programa corrigido:

Servo myServo10;

// Posicionar sonar no ângulo indicado.
void posicionar_sonar() {
  myServo10.write(angulo_sonar);
  delay(1000);
}

void loop() {
  if (distancia() < 30) {
    parar();
    angulo_sonar = 10;
    posicionar_sonar();
    espaco_direita = distancia();
    angulo_sonar = 170;
    posicionar_sonar();
    espaco_esquerda = distancia();
    angulo_sonar = 90;
    posicionar_sonar();
    if (espaco_esquerda == 0 || espaco_esquerda > espaco_direita) {
      esquerda();
    } else {
      direita();
    }
  } else {
    avancar();
  }
  if (tem_luz()) {
    apagar_farol();
  } else {
    acender_farol();
  }
  delay(200);

}

Mais detalhes

Um servomotor é um motor que gira seu eixo acompanhando um sinal elétrico. Em geral, o movimento do eixo é de apenas 180°. Este tipo de motor é utilizado para girar o leme dos navios, acompanhando o movimento da roda de leme na cabine de comando. Os servomotores também são muito utilizados em aeromodelos e carros de controle remoto.

O servomotor que utilizamos é o SG90, muito utilizado em aeromodelismo. Suas características técnicas estão em: http://www.ee.ic.ac.uk/pcheung/teaching/DE1_EE/stores/sg90_datasheet.pdf

Os dados importantes são que ele opera com tensões de 4,8 a 6V, e é controlado por um sinal PWM com ciclo de 50Hz e largura de pulso variando e 1ms a 2ms, que faz o eixo variar de 0 a 180 graus. Os sinais PWM do Arduino são gerados com frequência de cerca de 500Hz, muito alta para controlar os servos. Para resolver isso, foi criada uma biblioteca (servo.h), que tem funções de controle, e que converte parâmetros fornecidos em graus para a largura de pulso necessária, simplificando o uso.

Outro detalhe que aprendemos após o uso dos servos em diversos projetos é que eles demandam bastante corrente, e causam mal funcionamento se ligados juntamente com outros dispositivos à alimentação de 5V fornecida pelo Arduino. Os servos devem ser ligados diretamente às baterias, assim como os motores das rodas.

Antes de serem utilizados, os servos precisam ser calibrados. É preciso ligá-los ao Arduino, rodando um programa simples que posiciona o servo em 90°. Esta posição pode ser marcada com um marcador de CDs, e será utilizada para a montagem da haste. Este artigo mostra o programa: https://www.robocore.net/modules.php?name=Forums&file=viewtopic&t=3783

Este artigo fornece mais informações a respeito dos servomotores: https://pt.wikipedia.org/wiki/Servomotor

Avançar à Parte 8

Nenhum comentário:

Postar um comentário