Para montar um robô segue linha você precisará logicamente de uma Raspberry Pi Pico (qualquer versão), um módulo drive de controle de motor, o L298N, 2 motores amarelinhos, 4 pilhas com o seu devido suporte, dois sensores IR TCRT5000, fios e solda, além da base do robô que pode ser impressa ou usar as plataformas de acrílicos prontas de mercado.
Vamos começar com a parte eletrônica, onde na figura 1 temos o esquema elétrico da montagem. Pode parecer meio confuso , mas é possível notar que os pinos de 1 a 6, ou seja, as GPIOS 0 a 5, estão ligadas no drive L298N, onde as GPIOS 0 e 5 ficam ligadas nas portas ENA e ENB (Enable A e B) do drive, por onde é possível controlar a velocidade dos motores através do PWM gerada na Pi Pico. As GPIOS 1 a 4 temos o sentido de cada motor, onde as GPIOS 1 e 2 direcionam o sentido da rotação do motor 1 e as GPIOS 3 e 4 do motor 2.
Como usaremos as pilhas para fornecer a energia para todo o sistema, ligamos o positivo da bateria no pino 6 a 12 V da L298N, o GND ao meio e pino de 5 V conectamos ao pino VSYS da Pi Pico. Mas aqui fica um lembrete: Não ligue a bateria à Pi Pico enquanto a mesma estiver conectada ao 5 V do computador, pois podemos queimar a placa. Atrás deste conector, temos um jumper que devemos deixar conectado, pois ele ativa a saída de 5 V que irá alimentar a Pi Pico.
Ligamos os motores amarelinhos nos conectores correspondentes no L298N, cada lado do módulo temos a ligação de um motor. Aqui o positivo e o negativo do motor deverão estar de acordo com o sentido de rotação, se é pra frente ou para trás. Se depois de rodar o código o motor girar no sentido inverso, você poderá inverter os pólos do motor, ou trocar no código o acionamento de cada um, para que o motor gire no sentido correto quando for acionado.
Os sensores IR (TCRT5000) possuem 4 pinos, o A0, D0, GND e o VCC. O VCC ligamos no 3,3 V OUT da Pi Pico, o GND ao GND da placa e aqui temos duas formas de obter os sinais, de forma analógica (A0) ou digital (D0). Vamos utilizar a forma analógica, porém vamos conectar tanto o A0 como o D0 caso você precise modificar algo. O sensor do lado direito conectamos o A0 ao ADC1 e o D0 ao GPIO22, o do lado esquerdo o A0 ao ADC0 e o D0 ao GPIO21.
O Funcionamento
Para facilitar a nossa vida, é aconselhável colocar um botão liga/desliga entre as pilhas e o Módulo L298N. Quando a Pi Pico começa o seu programa, ela verifica se os sensores IR estão sobre uma parte branca, recebendo a luz. Quando ambos os sensores recebem a luz, é sinal que ambas estão sobre uma parte branca (reflexiva), quando um dos sensores passa sobre uma faixa preta, o sensor IR para de receber a luz que ela mesma emite, e no código paramos o motor do mesmo lado para que o robô gire até o momento que o sensor começa a receber a luz novamente, indicando que a faixa preta está entre os sensores. O mesmo acontece do outro lado, fazendo que o robô ande sobre a faixa preta. A pista pode ser feita sobre um chão claro e a faixa preta pode ser pintada ou usar fita isolante.

Figura 1 - Esquema elétrico do sistema
O Código
Usamos o Thonny para digitar o nosso código em micropython, para facilitar o entendimento do código usamos um outro código onde incluímos ele no código principal ( o main.py ). No código podemos ver que se ambos os sensores estão sobre uma parte branca, ambos os motores rodam normalmente, quando o sensor da esquerda passa sobre a faixa preta, o sinal enviado vai para zero e o motor da esquerda é paralisado e o motor da direita vira mais rápido, fazendo a curva. O mesmo procedimento é feito do lado inverso.
from machine import Pin, PWM, ADC
from L298N_motor import L298N
import time
#Pinos do sensor IR 1
pino_IR_D0 = 22
IR_D0 = machine.Pin(pino_IR_D0, machine.Pin.IN) #sem PULL UP
IR_A0 = ADC(1)
#Pinos do sensor IR 2
pino_IR_D1 = 21
IR_D1 = machine.Pin(pino_IR_D1, machine.Pin.IN) #sem PULL UP
IR_A1 = ADC(0)
CorteLinha = 1
# Inicializa o PWM e define a frequência para 1000Hz (padrão para motores)
#Pinos do módulo L298N
ena_pin = Pin(0)
ENA = PWM(ena_pin)
ENA.freq(1000) # <--- ISSO É CRUCIAL
enb_pin = Pin(5)
ENB = PWM(enb_pin)
ENB.freq(1000) # <--- ISSO É CRUCIAL
IN1 = Pin(1, Pin.OUT)
IN2 = Pin(2, Pin.OUT)
IN3 = Pin(3, Pin.OUT)
IN4 = Pin(4, Pin.OUT)
motor1 = L298N(ENA, IN1, IN2)
motor2 = L298N(ENB, IN3, IN4)
# Defina a velocidade (ajuste para testar, experimente valores maiores se não girar)
velocidade_reta = 49000
velocidade_curva = 54000
def frente():
motor1.forward()
motor2.forward()
motor1.setSpeed(velocidade_reta)
motor2.setSpeed(velocidade_reta)
def parar():
motor1.stop()
motor2.stop()
def esquerda():
motor1.forward()
motor2.stop()
motor1.setSpeed(velocidade_curva)
def direita():
motor2.forward()
motor1.stop()
motor2.setSpeed(velocidade_curva)
try:
while True:
#analisamos a tensão da porta analógica do sensores
tensao_IR_A0 = IR_A0.read_u16() * (3.3 / 65535.0)
tensao_IR_A1 = IR_A1.read_u16() * (3.3 / 65535.0)
#analisamos se algum sensor está sobre a faixa preta
na_linha_esq = tensao_IR_A1 > CorteLinha
na_linha_dir = tensao_IR_A0 > CorteLinha
if na_linha_esq and not na_linha_dir:
esquerda()
elif na_linha_dir and not na_linha_esq:
direita()
elif not na_linha_esq and not na_linha_dir:
frente()
else:
frente()
except KeyboardInterrupt:
print("Programa interrompido. Parando motores.")
parar()
Abaixo temos o código do módulo L298n
"""
MicroPython driver for L298N Motor Driver module:
https://github.com/ramjipatel041/Micropython-Driver-for-L298N-Motor-Driver.git
MIT License
Copyright (c) 2023 Ramji Patel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
import time
from machine import Pin
class L298N:
def __init__(self, ENA, IN1, IN2):
self.IN1 = IN1
self.IN2 = IN2
self.pwm = ENA
self.speed = 40000
self.ismoving = False
self.direction = 'STOP'
self.time = 0
def forward(self):
self.IN1.value(1)
self.IN2.value(0)
self.ismoving = True
self.direction = 'FORWARD'
def backward(self):
self.IN1.value(0)
self.IN2.value(1)
self.ismoving = True
self.direction = 'BACKWARD'
def stop(self):
self.IN1.value(0)
self.IN2.value(0)
self.ismoving = False
self.Direction = 'STOP'
def setSpeed(self, speed):
self.pwm.freq(15000)
self.speed = speed
self.pwm.duty_u16(speed)
def getSpeed(self):
return self.speed
def getDirection(self):
return self.direction
def run(self, direction):
self.direction = direction
if self.direction == 'FORWARD':
self.forward()
elif self.direction == 'BACKWARD':
self.backward()
elif self.direction == 'STOP':
self.stop()
else:
pass
def forwardFor(self, Time):
self.time = Time
self.forward()
time.sleep(self.time)
self.stop()
def backwardFor(self, Time):
self.time = Time
self.backward()
time.sleep(self.time)
self.stop()
def runFor(self, direction, Time):
self.direction = direction
self.time = Time
if self.direction == 'FORWARD':
self.forward()
time.sleep(self.time)
self.stop()
elif self.direction == 'BACKWARD':
self.backward()
time.sleep(self.time)
self.stop()
elif self.direction == 'STOP':
self.stop()
time.sleep(self.time)
else:
pass
def isMoving(self):
if self.ismoving == True:
print('True')
elif self.ismoving == False:
print('False')
else:
pass
Conclusão
O robô segue linha é um dos exercícios de robótica mais utilizados nas escolas e competições, porém a maioria utiliza o Arduino , e aqui temos uma versão usando o Raspberry Pi Pico, mais enxuta e econômica. Utilizando a versão “W” da Pi Pico é possível coletar informações ou controlar este mesmo robô.
Nas referências deixo diversos links caso queira conhecer um pouco mais de cada módulo utilizado aqui.
Referencias:
Usando o L298N
https://www.youtube.com/watch?v=-9Dr0BeyIMA
O Sensor IR TCRT5000
https://www.youtube.com/watch?v=JUW_CSlDaDY















