Curso Robótica – #7 – LineFollower
Durante a sétima parte do curso de robótica, vamos lidar com LineFollower. As competições organizadas para estas construções podem ser chamadas de corridas da F1 World Robots!
Desta vez, os robots serão capazes de dirigir de forma completamente autónoma numa pista especial colada à fita de isolamento preta comum!
O que são LineFollower?
LineFollower, como o nome sugere, são construções que seguem a linha que marca o curso.
É claro que os veículos não são controlados remotamente,
por isso precisam encontrar o caminho na rota.
Um exemplo de um LineFollower:
Construção da linha seguidora
A rota em que as corridas acontecem é geralmente determinada por uma linha preta (15-20 mm de largura), que é colocada sobre um fundo branco. Uma verso reversa também possível, isto uma linha branca sobre um fundo preto – no entanto, esta variante no momento rara.
Para construir uma pista em casa, você precisará de:
- substrato : a variante ideal é painéis móveis de MDF/HDF branco. No entanto, no início, um papelão branco terá um bom desempenho. Como último recurso, pode haver até painéis ou outro piso duro e brilhante.
- linha preta: aqui, independentemente do substrato, use fita isolante preta que funciona perfeitamente para esta aplicação.
O segundo método de rota menos comum para os seguidores de linha é chamado “banners”.
Quanto ao caminho de impressão sobre o material de que são feitos os anúncios de grande formato,
que muitas vezes podem ser encontradas, por exemplo. Hedges.
No começo tem que começar com trilhas mais simples e pequenas. Vale a pena encontrar um pedaço de chão livre e colar a pista. Para começar, devemos começar com algo fácil – por exemplo, a partir de um retângulo com cantos arredondados ou uma elipse. Claro, isso não precisa ser feito perfeitamente – apenas o oposto.
Evite cantos afiados,
é melhor se concentrar em curvas no começo!
Um exemplo da minha faixa é mostrado abaixo. Eu escolhi um piso que não tem uma cor uniforme e pode causar problemas, porque significa que se o meu robot funcionar corretamente, não há opção para outras pessoas causarem problemas!
“Track” é feito de uma única peça de fita. Pode esticar suavemente a fita, que irá formar os arcos. No entanto, não exagere na esticá-lo, porque ele pode levar a estenose e descoloração. Nós também devemos-nos lembrar de não deixar a pista colada ao chão por um tempo muito longo. Depois de vários dias colada a fita adesiva pode deixar marcas difíceis de remover!
Sensores e o princípio da detecção de linha
Antes de chegarmos à montagem do sensor, vale a pena perceber como o robot “vê a linha”. Os veículos iluminam a rota (na luz visível ou IR) e, de seguida, verificam quanta luz foi refletida pela rota. Haverá muito mais luz da rota branca do que da linha preta.
Para esta tarefa, vamos usar sensores. Desta vez é necessário colocar os jumpers, que ligam os LEDs – eles acendem a rota!
Por meio do potenciómetro embutido no sensor, é possível ajustar o brilho do díodo.
- Porquê um LED colorido (em vez de IR)?
Isso torna muito mais fácil verificar se o sensor realmente funciona e onde a luz emitida pelo transmissor cai. - Porquê ajustar o brilho do díodo, não o divisor de tensão para o fotoresistência?
O efeito do ajuste é então simplesmente visível a olho nu. Os sensores deveriam ser simples e amigáveis para os iniciantes, para que os problemas pudessem ser rapidamente detectados.
Conexão de sensores ao robot
No início, os sensores devem estar conectados. Desta vez eles devem “olhar para baixo”, essa é a nossa rota. Eles também devem estar próximos uns dos outros (na largura da fita isolante), que marca o caminho. Os buracos preparados à frente do robot são ideais aqui:
Os cabos podem ser convenientemente passados pelos mesmos orifícios através dos quais os sinais são enviados para os motores. Obviamente, a conexão permanece inalterada (conectores ADC_L e ADC_R no eixo). Se alguém tem medo de muitos fios na vizinhança dos motores, eles podem ser pressionados contra o compensado usando um elástico regular, como mostrado abaixo:
Teste e calibração de sensores
É hora de verificar o funcionamento dos sensores na prática – temos que ensinar o robot a reagir à linha. Para isso, vamos precisar de um “pedaço da rota”, ou seja, um pedaço de papel com uma tira de fita isolante preta:
No começo, vamos começar com um teste simples. Tudo o que precisa de fazer é exibir informações sobre o valor lido pelo ADC. Eu sugiro, por enquanto, cuidar apenas de um sensor:
#define L_PWM 5 #define L_DIR 4 #define R_PWM 6 #define R_DIR 9 #define PWM_MAX 165 #define R_LINE_SENSOR A0 #define L_LINE_SENSOR A1 #define BUZZER 10 #define LED 13 void setup() { //Konfiguracja pinow od mostka H pinMode(L_DIR, OUTPUT); pinMode(R_DIR, OUTPUT); pinMode(L_PWM, OUTPUT); pinMode(R_PWM, OUTPUT); //Konfiguracja pozostalych elementow pinMode(BUZZER, OUTPUT); digitalWrite(BUZZER, 0); //Wylaczenie buzzera pinMode(LED, OUTPUT); digitalWrite(LED, 0); //Wylaczenie diody Serial.begin(9600); } void loop() { int odczytLewy = analogRead(L_LINE_SENSOR); Serial.print("Lewy czujnik: "); Serial.println(odczytLewy); delay(250); } void leftMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 0); //Kierunek: do przodu analogWrite(L_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 1); //Kierunek: do tyłu analogWrite(L_PWM, V); //Ustawienie predkosci } } void rightMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 0); //Kierunek: do przodu analogWrite(R_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 1); //Kierunek: do tyłu analogWrite(R_PWM, V); //Ustawienie predkosci } } void stopMotors() { analogWrite(L_PWM, 0); //Wylaczenie silnika lewego analogWrite(R_PWM, 0); //Wylaczenie silnika prawego }
Tudo depende das configurações dos sensores e do substrato no qual eles são testados. O mais importante é fazer a diferença entre as leituras feitas na superfície preta e branca visível. Já 50-100 unidades de ADC são suficientes para trabalhos futuros.
Em caso de problemas na obtenção de leituras apropriadas, deve começar com o ajuste do brilho com o qual o díodo acende. É claro que, para isso, usamos um potenciómetro embutido no sensor. Além disso, vale a pena proteger os fotoresistências com um pedaço de tubo termoencolhível.
Aplicá-lo (e apertá-lo delicadamente por aquecimento) nas fotoresistências deve aumentar a diferença entre as leituras. Esse tratamento também imunizará o robot contra fatores externos (por exemplo, a luz solar, que, ao passar pela janela, iluminará uma parte adicional da rota).
Antes de prosseguir, verifique se o segundo sensor também funciona corretamente! Registe os valores retornados pelo ADC quando o sensor estiver posicionado acima da linha e do lado de fora.
No meu caso, notei os seguintes valores (média para os dois sensores):
- sensor acima da linha: 930
- sensor fora da linha: 680
Implementação de um comparador simples
Agora o valor ADC deve ser selecionado manualmente, a partir do qual reconheceremos que o sensor detectou a linha. O robot irá se mover, por isso não podemos definir limites rígidos. As leituras do sensor mudam o tempo todo, por isso é melhor definir um valor limite.
Com base nas informações que eu havia anotado anteriormente, decidi que cada caso acima de 850 deveria ser identificado como uma linha preta. Depois de escolher o valor limite, é melhor adicionar imediatamente a constante apropriada ao programa:
#define GRANICA 850#
Por conveniência, vamos agora adicionar duas funções que retornarão informações sobre o estado dos sensores. É melhor assumir que 1 é uma linha e 0 está faltando. As funções, portanto, atuam como comparadores.
As funções retornam apenas 1 (verdadeiro) ou 0 (falso):
boolean leftSensor() { if (analogRead(L_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } } boolean rightSensor() { if (analogRead(R_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } }
Agora é necessário verificar se ambos os sensores funcionam corretamente. Para este propósito, no loop(), perguntamos aos sensores se eles vêem a linha. Para que o teste seja “mais móvel” além do UART, usaremos o sinal sonoro (para o sensor esquerdo) e o díodo (para o sensor direito).
O programa inteiro pode ser assim:
#define GRANICA 850 #define L_PWM 5 #define L_DIR 4 #define R_PWM 6 #define R_DIR 9 #define PWM_MAX 165 #define R_LINE_SENSOR A0 #define L_LINE_SENSOR A1 #define BUZZER 10 #define LED 13 void setup() { //Konfiguracja pinow od mostka H pinMode(L_DIR, OUTPUT); pinMode(R_DIR, OUTPUT); pinMode(L_PWM, OUTPUT); pinMode(R_PWM, OUTPUT); //Konfiguracja pozostalych elementow pinMode(BUZZER, OUTPUT); digitalWrite(BUZZER, 0); //Wylaczenie buzzera pinMode(LED, OUTPUT); digitalWrite(LED, 0); //Wylaczenie diody Serial.begin(9600); } void loop() { if (leftSensor() == 1) { //Jesli lewy czujnik widzi linie Serial.println("Linia pod lewym czujnikiem!"); digitalWrite(BUZZER, 1); //Wlacz buzzer } else { digitalWrite(BUZZER, 0); //Wylacz buzzer } if (rightSensor() == 1) { //Jesli prawy czujnik widzi linie Serial.println("Linia pod prawym czujnikiem!"); digitalWrite(LED, 1); //Wlacz LED } else { digitalWrite(LED, 0); //Wylacz LED } } boolean leftSensor() { if (analogRead(L_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } } boolean rightSensor() { if (analogRead(R_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } } void leftMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 0); //Kierunek: do przodu analogWrite(L_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 1); //Kierunek: do tyłu analogWrite(L_PWM, V); //Ustawienie predkosci } } void rightMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 0); //Kierunek: do przodu analogWrite(R_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 1); //Kierunek: do tyłu analogWrite(R_PWM, V); //Ustawienie predkosci } } void stopMotors() { analogWrite(L_PWM, 0); //Wylaczenie silnika lewego analogWrite(R_PWM, 0); //Wylaczenie silnika prawego }
Antes de prosseguir, certifique-se de que ambos os sensores funcionam corretamente! Para evitar muitos problemas mais tarde, precisa verificar se o GRANICA (LIMITE) atualmente configurado cumpre sua tarefa.
No momento, o correto funcionamento do programa é:
- ambos os sensores na superfície branca – campainha e díodo desligado
- ambos os sensores na superfície preta – campainha e díodo ligado
- linha sob o sensor esquerdo – buzina ligada , díodo desligado
- linha sob o sensor direito – campainha desligada, díodo ligado .
Agora vamos escrever 3 algoritmos simples
que permitirão que o robô siga a linha.
Variante 1: seguidor de linha com um sensor
Sim, eu sei que já temos 2 sensores no robot, mas vale a pena verificar como o robô rastreando a linha com um sensor se comportará. Esta tarefa é frequentemente medida por pessoas que constroem robots a partir de blocos LEGO (na maioria dos casos, existe apenas um sensor de linha).
Na verdade, é impossível rastrear a linha usando um sensor!
No entanto, pode seguir a borda da linha! Se colocarmos o robot ao lado da borda esquerda da linha, o programa deve executar as seguintes operações:
- Se o sensor vir uma linha: vá com um arco para a esquerda,
- Se o sensor não pode ver a linha: vá para a direita.
Graças a isso, o robot irá “saltar” da borda esquerda da linha!
Para o propósito do teste, destaquei o sensor direito (bastava soltar o cabo). O programa:
#define GRANICA 850 #define L_PWM 5 #define L_DIR 4 #define R_PWM 6 #define R_DIR 9 #define PWM_MAX 165 #define R_LINE_SENSOR A0 #define L_LINE_SENSOR A1 #define BUZZER 10 #define LED 13 void setup() { //Konfiguracja pinow od mostka H pinMode(L_DIR, OUTPUT); pinMode(R_DIR, OUTPUT); pinMode(L_PWM, OUTPUT); pinMode(R_PWM, OUTPUT); //Konfiguracja pozostalych elementow pinMode(BUZZER, OUTPUT); digitalWrite(BUZZER, 0); //Wylaczenie buzzera pinMode(LED, OUTPUT); digitalWrite(LED, 0); //Wylaczenie diody Serial.begin(9600); } void loop() { if (leftSensor() == 1) { //Jesli lewy czujnik widzi linie leftMotor(0); //Jazda łukiem w lewo rightMotor(40); } else { leftMotor(40); //Jazda łukiem w prawo rightMotor(0); } } boolean leftSensor() { if (analogRead(L_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } } boolean rightSensor() { if (analogRead(R_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } } void leftMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 0); //Kierunek: do przodu analogWrite(L_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 1); //Kierunek: do tyłu analogWrite(L_PWM, V); //Ustawienie predkosci } } void rightMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 0); //Kierunek: do przodu analogWrite(R_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 1); //Kierunek: do tyłu analogWrite(R_PWM, V); //Ustawienie predkosci } } void stopMotors() { analogWrite(L_PWM, 0); //Wylaczenie silnika lewego analogWrite(R_PWM, 0); //Wylaczenie silnika prawego }
O funcionamento do programa na prática é visível no seguinte vídeo:
Talvez seja um erro dizer que o robot no vídeo viaja tranquilamente… No entanto, ele certamente cumpre a sua tarefa, ou seja, ele segue a linha colada. É claro que, regulando a velocidade dos motores, ainda pode ajustar e melhorar os resultados do robot!
Variante 2: seguidor de linha com dois sensores
Agora vamos usar dois sensores, então reconectamos o cabo do sensor direito. Desta vez, vamos estender os sensores para o lado (de acordo com a foto abaixo) para que, quando o robot estiver perfeitamente na linha, nenhum dos sensores o tenha visto.
Graças a isso, a saída mínima da rota
“alertará” o Arduino que deve começar a girar!
Desta vez, o programa deve funcionar da seguinte maneira:
- Se nenhum dos sensores vir a linha: avançar.
- Se o sensor esquerdo vir a linha: vire à esquerda.
- Se o sensor direito vir a linha: gire a curva para a direita.
Olhando para o robot de cima , vai ficar assim:
Um programa que realiza essa tarefa pode parecer com:
#define GRANICA 850 #define L_PWM 5 #define L_DIR 4 #define R_PWM 6 #define R_DIR 9 #define PWM_MAX 165 #define R_LINE_SENSOR A0 #define L_LINE_SENSOR A1 #define BUZZER 10 #define LED 13 void setup() { //Konfiguracja pinow od mostka H pinMode(L_DIR, OUTPUT); pinMode(R_DIR, OUTPUT); pinMode(L_PWM, OUTPUT); pinMode(R_PWM, OUTPUT); //Konfiguracja pozostalych elementow pinMode(BUZZER, OUTPUT); digitalWrite(BUZZER, 0); //Wylaczenie buzzera pinMode(LED, OUTPUT); digitalWrite(LED, 0); //Wylaczenie diody Serial.begin(9600); } void loop() { if (leftSensor() == 0 && rightSensor() == 0) { //Jesli czujniki nie widza linii leftMotor(40); //Jazda prosto rightMotor(40); } else if (leftSensor() == 1) { //Jesli lewy czujnik widzi linie leftMotor(0); //Jazda po łuku w lewo rightMotor(40); } else if (rightSensor() == 1) { //Jesli prawy czujnik widzi linie leftMotor(40); //Jazda po łuku w prawo rightMotor(0); } } boolean leftSensor() { if (analogRead(L_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } } boolean rightSensor() { if (analogRead(R_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } } void leftMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 0); //Kierunek: do przodu analogWrite(L_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 1); //Kierunek: do tyłu analogWrite(L_PWM, V); //Ustawienie predkosci } } void rightMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 0); //Kierunek: do przodu analogWrite(R_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 1); //Kierunek: do tyłu analogWrite(R_PWM, V); //Ustawienie predkosci } } void stopMotors() { analogWrite(L_PWM, 0); //Wylaczenie silnika lewego analogWrite(R_PWM, 0); //Wylaczenie silnika prawego }
O funcionamento do programa na prática é visível no seguinte vídeo:
O robot pode ser melhor ajustado alterando o passo do sensor e a velocidade em que ele se move. Infelizmente, chegaremos rapidamente a uma situação em que o veículo não irá “compensar” a curva. Apesar de virar, ele seguirá a rota de qualquer maneira. Infelizmente, com a configuração atual depois de deixar a linha, ambos os sensores verão “fundo branco”, então… o robot irá direto!
Ao construir uma linha de seguidores, deve-se definitivamente evitar a variante,
quando o robot, estando perfeitamente na linha, não o vê com nenhum sensor!
A solução para este problema é outra configuração do robot!
Variante 3: seguidor de linha com dois sensores v2
Desta vez também usaremos dois sensores, mas tentaremos aproximá-los. Como resultado, ao viajar perfeitamente “na linha”, os dois sensores o verão. O desvio mínimo da trajetória correta fará com que o robot corrija seu movimento.
Desta vez, o programa deve funcionar da seguinte maneira:
- Se ambos os sensores virem a linha: dirigindo para frente.
- Se o sensor esquerdo não vir a linha: gire a curva para a direita.
- Se o sensor direito não conseguir ver a linha: vire à esquerda.
Olhando para o robot de cima, vai ficar assim:
Um programa exemplar realizando esta tarefa é visível abaixo:
#define GRANICA 850 #define L_PWM 5 #define L_DIR 4 #define R_PWM 6 #define R_DIR 9 #define PWM_MAX 165 #define R_LINE_SENSOR A0 #define L_LINE_SENSOR A1 #define BUZZER 10 #define LED 13 void setup() { //Konfiguracja pinow od mostka H pinMode(L_DIR, OUTPUT); pinMode(R_DIR, OUTPUT); pinMode(L_PWM, OUTPUT); pinMode(R_PWM, OUTPUT); //Konfiguracja pozostalych elementow pinMode(BUZZER, OUTPUT); digitalWrite(BUZZER, 0); //Wylaczenie buzzera pinMode(LED, OUTPUT); digitalWrite(LED, 0); //Wylaczenie diody Serial.begin(9600); } void loop() { if (leftSensor() == 1 && rightSensor() == 1) { //Jesli oba czujniki widza linii leftMotor(40); //Jazda prosto rightMotor(40); } else if (leftSensor() == 0) { //Jesli lewy czujnik nie widzi linii leftMotor(40); //Jazda po łuku w prawo rightMotor(10); } else if (rightSensor() == 0) { //Jesli prawy czujnik nie widzi linii leftMotor(10); //Jazda po łuku w lewo rightMotor(40); } } boolean leftSensor() { if (analogRead(L_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } } boolean rightSensor() { if (analogRead(R_LINE_SENSOR) > GRANICA) { //Jesli czujnik widzi linie, to return 1; //Zwroc 1 } else { //Jesli czujnik nie jest nad linią, to return 0; //Zwroc 0 } } void leftMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 0); //Kierunek: do przodu analogWrite(L_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(L_DIR, 1); //Kierunek: do tyłu analogWrite(L_PWM, V); //Ustawienie predkosci } } void rightMotor(int V) { if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia) V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 0); //Kierunek: do przodu analogWrite(R_PWM, V); //Ustawienie predkosci } else { V = abs(V); //Funkcja abs() zwroci wartosc V bez znaku V = map(V, 0, 100, 0, PWM_MAX); digitalWrite(R_DIR, 1); //Kierunek: do tyłu analogWrite(R_PWM, V); //Ustawienie predkosci } } void stopMotors() { analogWrite(L_PWM, 0); //Wylaczenie silnika lewego analogWrite(R_PWM, 0); //Wylaczenie silnika prawego }
O funcionamento do programa na prática é visível abaixo:
Outras configurações do robot
Durante a construção da linha seguidora, a colocação dos sensores tem grande influência no efeito final. Neste robot é muito fácil regular a colocação dos sensores para os espalhar lateralmente (como fizemos nos exemplos descritos).
Mudanças igualmente interessantes no comportamento também podem ser obtidas colocando sensores no outro lado do robot (trocando a frente das costas). Se o robot der o inverso, os sensores estarão localizados muito mais longe do eixo de tração. Graças a isso, movimentos menores das rodas são suficientes para direcionar o robot para o caminho certo.
Sumário
Espero que, após este artigo, todos saibam como o seguidor de linha acompanha a linha! Encorajo todos a testar e tentar definir a velocidade o mais rápido possível.
Os assuntos discutidos são apenas uma introdução. Para uma condução mais rápida e suave, são necessários mais sensores e algoritmos mais sofisticados. No futuro, haverá um conjunto de sensores adicionais para o nosso robot – então poderei dar um passo adiante!