Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Código do Robô Ac.Belterra
/* ***************************** */
//
// SOBRE O AUTOR:
// Código criado por Ronilson dos Santos Bezerra,
// Cientisda da Computação pela Universidade Federal do Oeste do Pará - Ufopa.
// e autor do BLOG DO RONILSON: www.ronilsonsb.blogspot.com
// Lattes: http://lattes.cnpq.br/7179672616852182
//
/* ***************************** */
/**
* *****************************
* **** SOBRE A LICENÇA ******
* *****************************
* ESTE código é parte da postagem "Conheça o robô AC.Tapajós: ele é autônomo
* e também pode ser controlado por dispositivos Android" disponibilizado no link
* http://www.ronilsonsb.blogspot.com/2014/07/construindo-um-robo-autonomo-com.html
* e registrado sob a Licença Creative Commons - Atribuição-NãoComercial 4.0 Internacional.
*
*/
//MOTORES - PORTAS PWM
#define MotorEsq1 5
#define MotorEsq2 6
#define MotorDir1 10
#define MotorDir2 11
//OUTROS COMPONENTES - PORTAS DIGITAIS
#define _LedFrontalDir 2 //Led Frontal Direito
#define _LedFrontalEsq 3 //Led Frontal Esquerdo
#define _LedLuzTraseira 8 //Luz traseira
const int TrigPin = 12; //Envia o pulso do Sensor ultrassônico
const int EchoPin = 13; // Lê o pulso do Sensor ultrassônico
//PORTAS ANALÓGICAS.
#define Potenciometro A0 //Potenciômetro.
const int _LDRfrontalDireito = A2; //LDR Frontal Direito
const int LedInferior1 = A3; //LED Frontal Direito
const int LedInferior2 = A4; //LED Frontal Direito
const int _LDRfrontalEsquerdo = A5; //LDR Frontal Esquerdo
//OBJETOS E VARIÁVEIS GLOBAIS
int _DistanciaAnterior[5]; //Vetor utilizado pelo Evita Engate
int _Contador = 0; //Contador utilizado pelo AndaFrente para definir a _Velocidade do robô
int _DistanciaObstaculo; //Armazena a distância lida pelo sensor ultrassônico
int _ValorLdrDireito; //Armazena o valor lido pelo LDR frontal direito
int _ValorLdrEsquerdo; //Armazena o valor lido pelo LDR frontal esquerdo
int _ContEngate = 0; //Contador utilizado pela função "Evita Engate".
int _Velocidade = 0; //Armazena o valor lido pelo potenciômetro
boolean LadoEscolhido = 1; //Variável booleana utilizada pela função evita engate para escolher um lado para virar.
int VetorEngateCurva[3];
int _ContaEngateCurva = 0;
void setup(void) {
Serial.begin(9600); //Inicia a comunicação com a porta serial
//Setando motores
pinMode(MotorEsq1, OUTPUT);
pinMode(MotorEsq2, OUTPUT);
pinMode(MotorDir1, OUTPUT);
pinMode(MotorDir2, OUTPUT);
//Setando sensor ultrassônico
pinMode(TrigPin, OUTPUT); //RECEPTOR - Seta pino como ENTRADA do Sensor Ultrassônico
pinMode(EchoPin, INPUT); //EMISSOR - Seta pino como saída do Sensor Ultrassônico
//Setando LEDs
pinMode(_LedFrontalEsq, OUTPUT); //Setando LED Frontal esquerdo
pinMode(_LedFrontalDir, OUTPUT); //Setando LED frontal direito
pinMode(_LedLuzTraseira, OUTPUT); //Setando luz de freio
pinMode(LedInferior1, OUTPUT); //LED inferior
pinMode(LedInferior2, OUTPUT);//LED inferior
//Setando LDRs
pinMode(_LDRfrontalEsquerdo, INPUT); //LDR frontal Esquerdo
pinMode(_LDRfrontalDireito, INPUT); //LDR frontal Direito
//Iniciando LEDs com sinal alto (HIGH)
digitalWrite(_LedFrontalEsq, HIGH);
digitalWrite(_LedFrontalDir, HIGH);
analogWrite(LedInferior1, 200);
analogWrite(LedInferior2, 200);
}
//Faz a leitura no LDR esquerdo e retorna o valor
int LdrEsquerdo() {
_ValorLdrEsquerdo = analogRead(_LDRfrontalEsquerdo);
_ValorLdrEsquerdo = map(_ValorLdrEsquerdo, 0, 1023, 0, 100);
return (_ValorLdrEsquerdo);
}
//Lê o LDR direito e retorna o valor
int LdrDireito() {
_ValorLdrDireito = analogRead(_LDRfrontalDireito);
_ValorLdrDireito = map(_ValorLdrDireito, 0, 1023, 0, 100);
return (_ValorLdrDireito);
}
//Chama análise do Sensor Ultrassônico e se possível, movimenta o robô para frente.
void Anda(void) {
SensorUltrassonico(); //Obtém a distância dos obstáculos à frente
if (_DistanciaObstaculo > 40) {
AndaFrente(_Velocidade, _Velocidade);
delay(60);
_Contador++; //contador utilizado pelo anda AndaFrente.
_ContEngate++; //Contador utilizado pelo EvitaEngate.
//Chama a função EvitaEngate repassando como parâmetros: o contador de engate, a quantidade de vezes que desejamos antes que o primeiro teste seja realizado e o tamanho do delay que será utilizado pela Marcha Ré
EvitaEngate(_ContEngate, 12, 300);
}
else {
_Contador = 0; //Zera o contador utilizado pela função AndaFrente.
_ContEngate = 0; //Zera o contador do EvitaEngate
LuzDeFreio(); //Acende a luz de freio.
EscolheCaminho(); //Escolhe o melhor caminho
ApagaLuzDeFreio(); //Apaga a luz de freio
}
}
//Decide para qual lado virar, no momento da ré, na função EvitaEngate.
void EscolheLadoRe(int Dly) {
if (LadoEscolhido) {
ViraADireita(200, 200);
delay(Dly);
LadoEscolhido = !LadoEscolhido;
}
else {
ViraAEsquerda(200, 200);
delay(Dly);
LadoEscolhido = !LadoEscolhido;
}
}
/**
* O método EvitaEngate recebe como parâmetro o ContadorEngate,
* a quantidade de vezes que desejamos antes que o primeiro teste seja realizado e o tamanho do delay que será utilizado pela Marcha Ré
*/
void EvitaEngate(int ContadorEngate, int Quantidade, int Dly) {
if (ContadorEngate > Quantidade) {
int Media = 0;
//Faz três leituras no sensor ultrassônico e soma elas na variável Temporária;
for (int x = 0; x < 3; x++) {
SensorUltrassonico(); //Faz nova leitura no sensor ultrassônico
_DistanciaAnterior[x] = _DistanciaObstaculo; //Armazena cada leitura em um vetor
Media = _DistanciaObstaculo + Media; //Armazena todos as leituras em uma variável
}
//Calculando a média das leituras
Media = (Media / 3);
int Diferenca = 0; //Variável que acumulará a diferença entra a última leitura do sensor ultrassônico e a média das três leituras realizadas no teste.
//Se a media for maior que a última leitura do sensor ultrassônico
if (Media > _DistanciaAnterior[2]) {
//Encontra a diferença entra a média e a última leitura
Diferenca = Media - _DistanciaAnterior[2];
}
else {
Diferenca = _DistanciaAnterior[2] - Media;
}
//Entra neste if, se a diferença entre o último valor do sensor ultrassônico e média das cinco leituras, por um número menor que 2 % da média.
if (Diferenca <= (Media * 2/ 100)) {
MarchaRe(200, 200);
delay(Dly);
EscolheLadoRe(300);
}
else {
VetorEngateCurva[_ContaEngateCurva] = Media;
_ContaEngateCurva++;
if (_ContaEngateCurva == 2) {
int Diferenca = 0; //Variável que acumulará a diferença entra a última leitura do sensor ultrassônico e a média das cinco leituras realizadas no teste.
int Temp = (VetorEngateCurva[0] + VetorEngateCurva[1] + VetorEngateCurva[2]) / 3; //Temp recebe a média das últimas três médias
if (Temp > VetorEngateCurva[2]) {
Diferenca = Temp - VetorEngateCurva[2];
}
else {
Diferenca = VetorEngateCurva[2] - Temp;
}
if (VetorEngateCurva[0] == VetorEngateCurva[1] && VetorEngateCurva[0] == VetorEngateCurva[2]) {
MarchaRe(250, 250);
delay(Dly * 2);
EscolheLadoRe(300);
}
else if (Diferenca <= (Temp * 8/ 100)) {
MarchaRe(250, 250);
delay(Dly * 2);
EscolheLadoRe(300);
}
}
}
//Reseta o contador.
if (_ContaEngateCurva == 3) {
_ContaEngateCurva = 0;
}
_ContEngate = 0;
}
}
void EscolheCaminho(void) {
LdrEsquerdo(); //Retorna o valor do LDR Esquerdo
LdrDireito(); //Retorna o valor do LDR Direito
if (_ValorLdrEsquerdo > _ValorLdrDireito) { //Se a leitura do LDR esquerdo for maior que o direito, o robÔ vira a direita.
while (_DistanciaObstaculo < 41) {
_ContEngate++; //Incrementa contador do EvitaEngate
ViraADireita(200, 200);
delay(40);
Parado();
delay(25);
EvitaEngate(_ContEngate, 10, 300); //Repassa o contador como argumento e a quantidade de vezes
SensorUltrassonico();
}
}
//Se a leitura do LDR direito for maior ou igual ao esquerdo, o robô vira a esquerda
else if (_ValorLdrDireito > _ValorLdrEsquerdo || _ValorLdrDireito == _ValorLdrEsquerdo) {
while (_DistanciaObstaculo < 41) {
_ContEngate++;
ViraAEsquerda(200, 200);
delay(40);
Parado();
delay(25);
EvitaEngate(_ContEngate, 10, 300); //Repassa o contador como argumento e a quantidade de vezes
SensorUltrassonico();
}
}
_ContEngate = 0;
}
void LuzDeFreio(void) {
digitalWrite(_LedLuzTraseira, HIGH);
}
void ApagaLuzDeFreio(void) {
digitalWrite(_LedLuzTraseira, LOW);
}
//SENSOR ULTRASSONICO
int SensorUltrassonico() //Faz o disparo de pulsos e retorna o tempo em microssegundos
{
//Faz o disparo de pulsos e retorna o tempo em microssegundos
digitalWrite(TrigPin, LOW);
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(TrigPin, LOW);
unsigned long Duracao = pulseIn(EchoPin, HIGH);
_DistanciaObstaculo = Duracao / 58; //Acha a distancia em centímetros.
//Isto foi inserido, pois o sensor ultrassónico utilizado neste projeto só reconhece até 2 metros, acima disto ele retorna zero.
if (_DistanciaObstaculo == 0) {
_DistanciaObstaculo = 190;
}
return (_DistanciaObstaculo); //Retorna a distância do obstáculo.
}
//Anda para frente
void AndaFrente(char a, char b) {
analogWrite(MotorEsq1, a);
digitalWrite(MotorEsq2, LOW);
analogWrite(MotorDir1, b);
digitalWrite(MotorDir2, LOW);
Serial.println("Frente");
}
void MarchaRe(char a, char b) {
digitalWrite(MotorEsq1, LOW);
analogWrite(MotorEsq2, a);
digitalWrite(MotorDir1, LOW);
analogWrite(MotorDir2, b);
Serial.println("Marcha Re");
}
void ViraADireita(char a, char b) {
digitalWrite(MotorEsq1, LOW);
analogWrite(MotorEsq2, a);
analogWrite(MotorDir1, b);
digitalWrite(MotorDir2, LOW);
Serial.println("Direita");
}
void ViraAEsquerda(char a, char b) {
analogWrite(MotorEsq1, a);
digitalWrite(MotorEsq2, LOW);
digitalWrite(MotorDir1, LOW);
analogWrite(MotorDir2, b);
Serial.println("Esquerda");
}
void Parado(void) {
digitalWrite(MotorEsq1, LOW);
digitalWrite(MotorEsq2, LOW);
digitalWrite(MotorDir1, LOW);
digitalWrite(MotorDir2, LOW);
Serial.println("Parado");
}
void loop(void) {
//Fazendo leitura do potenciômetro e divide por 4, para poder aplicar este valor à função _velocidade, utilizada pelas portas PWM para controle da velocidade do robô
_Velocidade = analogRead(Potenciometro) / 4;
Anda();
} //Fim do loop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.