Boa noite pessoal, 

Estou com um trabalho da faculdade para fazer e preciso montar um robozinho seguidor de linha, já montei o projeto abaixo: 

Já está andando só não consigo fazer ele seguir a linha branca, ele se perde na primeira curva, quando seguro ele reduzindo a velocidade ele faz a curva certo. Abaixo está o código q estou usando, se alguém puder dar uma dica eu agradeceria muito. 

Obs.: Os sensores são 3 QRE1113, mas no código estou usando apenas 2. 

int sensor_esq = A0;
int valor_esq;

int sensor_dir = A2;

int valor_dir;

int motor_esq_f = 2;
int motor_dir_f = 7;

int pwm_esq = 3;

int pwm_dir = 5;

void setup() {

Serial.begin(9600);

pinMode(motor_esq_f, OUTPUT);
pinMode(motor_dir_f, OUTPUT);
delay(1500);

}

void loop() {

valor_esq = analogRead(sensor_esq);
valor_dir = analogRead(sensor_dir);

if(valor_esq>500&&valor_dir>500){

digitalWrite(motor_esq_f, HIGH);
digitalWrite(motor_dir_f, HIGH);
analogWrite(pwm_esq, 70);
analogWrite(pwm_dir, 80);
}

if(valor_esq<500){
digitalWrite(motor_esq_f, LOW);
digitalWrite(motor_dir_f, HIGH);
analogWrite(pwm_esq, 0);
analogWrite(pwm_dir, 80);
}

if(valor_dir<500){
digitalWrite(motor_esq_f, HIGH);
digitalWrite(motor_dir_f, LOW);
analogWrite(pwm_esq, 80);
analogWrite(pwm_dir, 0);
}

if (valor_esq<500&&valor_dir<500){
digitalWrite(motor_esq_f, HIGH);
digitalWrite(motor_dir_f, HIGH);
analogWrite(pwm_esq, 80);
analogWrite(pwm_dir, 80);
}
}

Exibições: 1344

Responder esta

Respostas a este tópico

Olá

Observe como seu código está funcionando

  • LER sensor
  • Testa condição
  • LIGA motor (O motor não desliga totalmente - pelo menos um continua funcionando)
  • Testa Condição (pode testar mais de uma vez as condições sem atualizar o valor do sensor)
  • LER sensor ....

Pense no algoritmo, como ele deve funcionar e em "todas" as possibilidades de condição.

Complementando as observações do Flavio:

1) O primeiro IF, de acordo com as demais lógicas, deveria colocar os dois PWM em 0 (zero)

2) Organize seu código: Coloque comentários. Crie funções para cada tarefa.

Por exemplo, poderia ser criada a função

int lerSensores()

Essa função devolveria os seguintes valores:

0, se nenhum sensor está refletindo. Nesse caso o carro deveria dar "marcha  ré"

1, se os dois sensores estão refletindo. Nesse caso caroo deve seguir em frente

2, se somente o sensor da esquerda está refletindo. Nesse caso o carro deveria ir para a direita

3, se somente o sensor da direita está refletindo. Nesse caso o carro deveria ir para a esquerda

Criar também a funcão

void moverRobot(int valor)

Essa função iria configurar os motores de acordo com a parâmetro valor recebido:

0, Os dois motores para trás

1, Os dois motores para frente

2, Girar para direita

3, Girar para esquerda

Observações: Um erro comum que os alunos cometem em relação ao if/else é que muitas vezes os IFs deveriam ser aninhados para evitar que mais de uma condição seja satisfeita.

Um IF aninhado é o que usa a cláusula else if.

No seu exemplo, se o valor_dir for menor que 500 os 2 últimos IFs PODERIAM ser executados

Ok, obrigado aos amigos já pelas dicas, tentei fazer como me disseram criei duas funções uma pra ler os sensores e retornar um número correspondente de acordo com a condição dos sensores, e outra pra acionar os motores de acordo com o número retornado na primeira função, carrguei mas não deu resultado, os motores não estão acionando em momento nenhum.

Acho que na hora de passar o return da primeira função pra segunda eu não estou fazendo certo, esse foi o código que estou usando:

 

int sensor_esq = A0;
int valor_esq;

int sensor_cen = A1;
int valor_cen;

int sensor_dir = A2;
int valor_dir;

int motor_esq_f = 2;
int motor_esq_t = 4;

int motor_dir_f = 7;
int motor_dir_t = 12;

int pwm_esq = 3;
int pwm_dir = 5;

void setup() {

Serial.begin(9600);

pinMode(motor_esq_f, OUTPUT);
pinMode(motor_esq_t, OUTPUT);
pinMode(motor_dir_f, OUTPUT);
pinMode(motor_dir_t, OUTPUT);

delay(1500);
}

void loop() {

int x = ler_sensores();

int aciona_motores();

}

int ler_sensores(){

valor_esq = analogRead(sensor_esq);
valor_cen = analogRead(sensor_cen);
valor_dir = analogRead(sensor_dir);

if(valor_esq>500&&valor_cen<500&&valor_dir>500){ //carro sobre a linha, sensores esquerdo e direito sobre a área preta

return 1;
}

if(valor_esq<500&&valor_dir>500){ //carro saindo para a direita, sensor esquerdo sobre a faixa e direito sobre a área preta

return 2;
}

if(valor_esq>500&&valor_dir<500){ //carro saindo para a esquerda, sensor esquerdo sobre a área preta e direito sobre a faixa

return 3;
}

if(valor_esq<500&&valor_cen<500&&valor_dir<500){ //carro passando em um cruzamento, todos os sensores sobre a faixa branca

return 4;
}

if(valor_esq>500&&valor_cen>500&&valor_dir>500){ //carro completamente fora da faixa, todos os sensores sobre a área preta

return 5;
}
}

int aciona_motores(int x){

if(x=1){ //aciona os 2 motores para frente
digitalWrite(motor_esq_f, HIGH);
digitalWrite(motor_dir_f, HIGH);
analogWrite(pwm_esq, 80);
analogWrite(pwm_dir, 80);
}

if(x=2){ //aciona apenas o motor direito
digitalWrite(motor_esq_f, LOW);
digitalWrite(motor_dir_f, HIGH);
analogWrite(pwm_esq, 0);
analogWrite(pwm_dir, 80);
}

if(x=3){ //aciona apenas o motor esquerdo
digitalWrite(motor_esq_f, HIGH);
digitalWrite(motor_dir_f, LOW);
analogWrite(pwm_esq, 80);
analogWrite(pwm_dir, 0);
}

if(x=4){ //aciona os 2 motores para frente
digitalWrite(motor_esq_f, HIGH);
digitalWrite(motor_dir_f, HIGH);
analogWrite(pwm_esq, 80);
analogWrite(pwm_dir, 80);
}

if(x=5){ //aciona os 2 motores para trás
digitalWrite(motor_esq_t, HIGH);
digitalWrite(motor_dir_t, HIGH);
analogWrite(pwm_esq, 80);
analogWrite(pwm_dir, 80);
}
}

Anexos

Muito bom! O programa ficou mais organizado, mas ainda apresenta alguns erros.

Vamos lá:

1) A assinatura da função aciona_motores, o certo é

void aciona_motores(intx)

Nesta função, o IF está errado. O certo é 

if(x==1) e não if(x=1)

Os demais ifs também precisam ser corrigidos

2) Na função loop, o correto é:

int x = ler_sensores();

aciona_motores(x);

Reparei que você agora está lendo 3 sensores e existem 5 possibilidades para eles. Não verifiquei todas, mas faça essas correções e veja o que precisa ser adaptado. Poste o resultado depois.

Obrigado José Augusto, não tinha percebido o detalhe do if, eu estou fazendo uma comparação e não atribuindo um valor. Corrigi conforme me indicou, agora já consegui algum resultado, mas o carro está parando, ele começa a fazer a primeira curva certo mas para no meio.

Fiquei em dúvida se o fato de não ter levado em consideração o sensor central nas condições 2 e 3 se isso afeta o funcionamento pois parece que o carro para quando o sensor central muda da linha branca pra parte preta da pista. Amanhã eu tento mais, se tiver mais alguma dica eu agradeço.

Alan, Algumas coisas que você pode tentar:

1 - Na função aciona_motores o código 1 e 5 estão fazendo a mesma coisa. Quando o carro estiver totalmente fora da faixa ele deve dar "marcha ré".


2 - Posicione os 3 sensores de acordo com a largura da linha. Coloque todos dentro dela.


3 - Verifique os testes das funções ler_sensores() e aciona_motores()


4 - Na função ler_sensores() use else if para que a rotina entre somente em uma condição:

if(valor_esq>500&&valor_cen<500&&valor_dir>500){
  return 1;
}
else if(valor_esq<500&&valor_dir>500) {
....
else if....


5 - Qual o driver motor (módulo ou shield)  você está usando? Coloque uma imagem dele aqui.

Mais uma vez obrigado José Augusto,

Na condição 1 seria quando o carro estiver perfeitamente em cima da linha, em uma reta por exemplo, neste caso os sensores esquerda e direita vão estar sobre a área preta da pista e o central sobre a faixa branca e o carro deve andar para frente de forma igual acionando os dois motores. Já na condição 5 seria quando o carro está totalmente fora da faixa branca, todos os sensores estão sobre a área preta da pista acionando a ré para tentar voltar para a faixa branca.

Eu coloquei os sensores como na figura abaixo pois a faixa branca, segundo especificações do professor, terá aproximadamente 19mm como os sensores tem 10mm não daria pra colocar os 3 sensores sobre a faixa.

Verifiquei o acionamento dos motores com o carro fora da pista com as rodas suspensas e o comportamento foi o mesmo, ele responde corretamente aos sensores acionando os motores de forma a corrigir a rota, porém depois para e não responde mais nada.

Vou mudar os ifs para else if quando estiver em casa e testar de novo.

Estou usando o driver LN298N, eu testei ele também acionando o comando dos motores diretamente com o 5V do arduino, todos funcionaram perfeitamente tanto para trás como para frente.

Alan tem um erro nos comandos que acionam os motores

De acordo com esse tutorial sobre o driver l298n, para cada motor, é necessário usar 2 pinos.

Os pinos pwm controlam somente a velocidade e só precisam ser utilizados se você retirar os jumpers, caso contrário eles não terão efeito

No seu código, você só está utilizando um pino para cada motor.
No seu caso, para fazer o motor girar para frente, teria que ser usado o seguinte comando:

if(x==1){ //aciona os 2 motores para frente
    digitalWrite(motor_esq_f, HIGH);

    digitalWrite(motor_esq_t, LOW);

    digitalWrite(motor_dir_f, HIGH);
    digitalWrite(motor_dir_f, LOW);
}

Faça o teste. Se você colocar todos os pinos em HIGH, o motor vai parar. Por isso que o robot está parando em determinadas condições.

Revise os comandos do motor de acordo com o link que te passei. São 4 pinos setados para cada movimento. Retire os comandos dos pinos PWM (pwm_esq e pwm_dir), ou deixe sempre em 200. A velocidade máxima é 255.

Ok, vou acertar isso, na verdade eu sei que precisa usar 2 pinos para controlar cada motor, só que achei que quando estivesse acionando os motores para frente, por exemplo, não fosse necessário colocar os pinos que acionam pra trás em LOW. Agora entendi que sempre tenho que declarar a condição de todos os pinos, mesmo os que não estiverem sendo usados em determinada ação. Quando ao PWM eu já tirei o jumper. Eu estou usando os pinos do arduino assim:

Pino 2 - controla o motor esquerdo para frente;
Pino 4 - controla o motor esquerdo para trás;

Pino 7 - controla o motor direito para frente;
Pino 12 - controla o motor direito para trás;

Pino 3 - controla o pwm do motor esquerdo;
Pino 5 - controla o pwm do motor direito;

Caro

 Após corrigir os problemas de lógica do seu programa, sugiro incluir um controle PID. É a forma mais utilizada para problemas dessa natureza.

Para ajudar com o pontapé inicial selecionei esse artigo:

http://siaiap32.univali.br/seer/index.php/acotb/article/viewFile/53...

Aviso: vai ter que estudar mais, mas o resultado vai compensar

Olá Marco, obrigado pela dica, eu já conhecia o controle PID, o artigo que você enviou parece ser muito bom eu vou olhar com calma assim que der. No meu projeto não vai dar pra implementar PID porque é pra daqui a 2 semanas.

Graças a ajuda de vocês já consegui fazer alguma coisa, ainda está meio instável mas já é um começo. Agradeço a ajuda de todos, em especial do José Augusto. 

https://www.youtube.com/watch?v=tRMNviPs0-o

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço