Como Construir um Robô de Resgate Competitivo – Parte 3: Programação
Makers, unam-se! Pois chegamos ao último post da série Como Construir um Robô de Resgate Competitivo. Depois de aprendermos sobre os desafios que enfrentaremos e já termos montado nosso robô, é hora de programa-lo! No código, iremos usar muitas bibliotecas para simplificar o trabalho, mas não se preocupe, todos os links usados serão compartilhados 🙂
Figura 01 – Nosso Nosso Robô de Resgate Montado.
Fonte: Autocore Robótica.
Calibrando Os Sensores Infravermelhos Line Follower + Linha Prata
Primeiramente, vamos entender os sensores de seguir a linha. Nosso robô utiliza 4 sensores infravermelhos com um sinal de saída digital (0 ou 1.) O funcionamento desses sensores é bastante simples: um LED infravermelho emite um feixe de luz infravermelha que é refletida pela superfície.
O feixe refletido é então recebido por um fotoresistor (LDR) que muda sua resistência interna de acordo com a intensidade do feixe. No entanto, o sensor que utilizamos, o Módulo Seguidor de Linha Infravermelho 4 Canais, usa um resistor variável (trimpot) para regular um limite, tipicamente chamado threshold, para enviar um sinal digital (1) quando a resistência do LDR atinge certo valor.
Figura 02 – Os Trimpots São Localizados na Placa Principal .
Fonte: Autocore Robótica.
Desta forma, o primeiro passo para fazermos nosso robô seguir uma linha é calibrar os sensores. Para isto, basta você copiar código abaixo e alterar a resistência do trimpot usando uma pequena chave de fenda até o Arduino receber sinais digitais de 5V do sensor. Quando isto ocorrer, o Serial começará a mostrar sinais “1.” É importante usar os 2 sensores centrais para detectar a linha preta e os 2 sensores externos para detectar a linha prata que indica o começo da 3ª sala.
void setup(){ pinMode(10, INPUT); // Nessas 4 linhas de código, estamos dizendo ao Arduino que as portas pinMode(11, INPUT); // 10, 11, 12 e 13 como entrada (INPUT) de informação. pinMode(12, INPUT); pinMode(13, INPUT); Serial.begin(9600); // Nessa linhda, inicia-se o Serial do Arduino com baundrate de 96000 } void loop(){ Serial.print(digitalRead(10)); // Com o comando Serial.print, ordenamos o Arduino a mostrar os valores de uma Serial.print(","); // porta que será indicada entre os parenteses. Serial.print(digitalRead(11)); Serial.print(","); Serial.print(digitalRead(12)); Serial.print(","); Serial.println(digitalRead(13)); }
Dessa forma, com os trimpots calibrados, nosso robô receberá um sinal HIGH (5V) quando exposto à linha preta e prata.
Programando o Para Resolver o Labirinto Line Follower
#include "AFMotor.h" //Esta é a biblioteca que utilizaremos para controlar a Motor Shield do robô #include "SPI.h" //Esta é a biblioteca de comunicação do robô para certos componentes #include "SharpIR.h" //Por fim, esta biblioteca nos dá de maneira simplificada a distancia reconhecida pelo sensor infravermelho Sharp SharpIR sensor (SharpIR::GP2Y0A21YK0F, A4); //Aqui indicamos qual sensor Sharp estamos utilizando e a qual porta ele está conectado AF_DCMotor motor_direito(1); // Indicamos que o motor direito esta conectado no conector Borne 1 da Motor Shield AF_DCMotor motor_esquerdo(2); // Indicamos que o motor esquerdo esta conectado no conector Borne 2 da Motor Shield const int linha_prata_esquerdo = 11; // Assim como no código de calibração, aqui indicamos as portas que os sensores infravermelhos const int linha_preta_esquerdo = 12; // estão conectados. const int linha_preta_direito = 10; const int linha_prata_direito = 13; int distancia = 0, sala = 1; //Ao longo do projeto, precisaremos de 2 variáveis para o robô saber em qual sala está e a distancia sendo lida pelo sensor Sharp void setup(){ pinMode(10, INPUT); // Nessas 4 linhas de código, estamos dizendo ao Arduino que as portas pinMode(11, INPUT); // 10, 11, 12 e 13 como entrada (INPUT) de informação. pinMode(12, INPUT); pinMode(13, INPUT); } void loop() { while(sala == 1){ // Este comando While diz para o Arduino fazer os comandos internos enquanto a variável "sala" tenha um valor igual a 1 motor_direito.run(FORWARD); // O comando ".run" diz para o motor rotacionar e entre parênteses você indica a direção FORWARD ou BACKWARD motor_esquerdo.run(FORWARD); motor_direito.setSpeed(200); // O comando ".setSpeed" nos permite controlar a velociada de de rotação do motor de 0 até 255 motor_esquerdo.setSpeed(200); distancia = sensor.getDistance(); // Este comando indica que a variável inteira "distancia" terá o mesmo valor que a distancia lida pelo sensor Sharp //Nossa programação consistirá em vários "if" com diferentes condições para torna-la mais simples if(linha_preta_esquerdo == HIGH && linha_preta_direito == LOW){ // Este comando indica para o robô fazer certas ações quando o sensor esquerdo ver preto e o direito não. motor_direito.run(RELEASE); motor_esquerdo.run(RELEASE); delay(50); motor_direito.run(FORWARD); motor_esquerdo.run(BACKWARD); delay(200); motor_esquerdo.run(FORWARD); } if(linha_preta_esquerdo == LOW && linha_preta_direito == HIGH){ // Este comando indica para o robô fazer certas ações quando o sensor direito ver preto e o esquerdo não. motor_direito.run(RELEASE); motor_esquerdo.run(RELEASE); delay(50); motor_direito.run(BACKWARD); motor_esquerdo.run(FORWARD); delay(200); motor_direito.run(FORWARD); } if(distancia <= 15){ motor_direito.run(RELEASE); motor_esquerdo.run(RELEASE); delay(100); motor_direito.setSpeed(100); motor_esquerdo.setSpeed(100); motor_direito.run(FORWARD); motor_esquerdo.run(BACKWARD); delay(300); motor_direito.run(FORWARD); motor_esquerdo.run(FORWARD); delay(500); motor_direito.run(BACKWARD); motor_esquerdo.run(FORWARD); delay(600); } if(linha_prata_esquerdo == HIGH && linha_prata_direito == HIGH){ // Este comando indica para o robô fazer certas ações quando o sensor esquerdo e direito virem prata motor_esquerdo.run(RELEASE); delay(50); motor_direito.setSpeed(150); motor_esquerdo.setSpeed(150); motor_direito.run(FORWARD); motor_direito.run(BACKWARD); delay(1000); sala = 3; } } /* Este bloco "While" é a programação para a 3ª sala do desafio, onde precisamos encontrar uma vítima. Nosso código fará o robô ir até o centro da sala e rodar em torno de seu próprio eixo até detectar algo. Em seguida, ele se aproximará e irá confirmar se realmente é a vítima */ while(sala == 3){ motor_direito.setSpeed(100); motor_esquerdo.setSpeed(100); if(distancia <= 25){ motor_direito.run(RELEASE); motor_esquerdo.run(RELEASE); delay(50); motor_direito.setSpeed(100); motor_esquerdo.setSpeed(100); motor_direito.run(FORWARD); motor_esquerdo.run(FORWARD); if(distancia < 12){ motor_direito.run(RELEASE); motor_esquerdo.run(RELEASE); delay(50); motor_direito.run(BACKWARD); motor_esquerdo.run(FORWARD); delay(200); if(distancia > 15){ motor_direito.run(FORWARD); motor_esquerdo.run(BACKWARD); delay(200); motor_direito.run(RELEASE); motor_esquerdo.run(RELEASE); delay(10000); } else{ motor_direito.run(BACKWARD); motor_esquerdo.run(BACKWARD); delay(500); } } } } }
Conclusão
Com a programação feita, basta clicar no “Upload” na IDE do Arduino e ver seu robô resolver um labirinto sozinho. Se quiser ver uma prévia de como será, veja nosso vídeo com uma perspectiva única do desafio.