Neste artigo apresento uma ideia de um funcionamento básico de um joystick virtual no controle de dois motores, muito utilizado na construção de pequenos robôs de combates, mas útil para diversos tipos de controles que necessitam de duas ou três variáveis.
Utilizei neste projeto uma Pi Pico 2W, pois é necessário uma conexão Bluetooth para conectar o aplicativo com a Raspberry Pi Pico. O módulo de controle dos motores eu utilizei o L298N e os motores o comum chamado de “amarelinho”. Todo o sistema é alimentado por 4 pilhas de 1,5 V como apresentado na figura 1.
O Aplicativo
Para a criação do aplicativo, utilizei o App Inventor que é gratuito e simples de usar, sem a necessidade de digitar as linhas de código, pois o mesmo utiliza o recurso de blocos. A maior carga de processamento fica a encargo do microcontrolador da Pi Pico 2W.
Como o intuito aqui é apresentar a lógico do joystick virtual, pularei a parte da conexão entre o aplicativo e a Pi Pico 2W, mas deixo um link para um vídeo onde mostro o passo a passo para realizar esta conexão. Explicando de forma geral , na parte onde configuramos a tela e puxamos os elementos necessários, puxei para a tela dois elementos para a tela.
O primeiro é um item chamado “pintura”, pois sobre esta área é que colocaremos outro elemento chamado “Bola”. A “Bola” tem que deslizar sobre a “Pintura”, e dentro dela é estipulado os limites onde a “Bola” irá correr. Para facilitar os nossos cálculos, vamos estipular a “Altura” e a “Largura” da área, colocando 200 pixels para cada lado, assim teremos um centro de 100 pixels até o centro deste quadrado, mas caso a aplicação precise de mais área, é só converter esta área em porcentagem. O elemento “Bola”, para ficar no centro da imagem que tem 200 pixels de largura e altura, colocamos a posição de 95 x 95 pixels, levando em conta que ela tem 10 pixels. Na figura 2 temos a aparência destes elementos.
Um outro bloco criado foi o “ToqueParaCima”, para mover o elemento “Bola” para o centro do elemento “Pintura”, quando o usuário tirar o dedo da tela. Na figura 3 temos a imagem dos blocos utilizados.
A Lógica do Joystick
Imagine um plano cartesiano de X e Y, o Y temos o movimento de andar para frente e para trás , e o eixo X o movimento para direita e esquerda. Você pode saber em qual “quadrante” o curso r, ou o elemento “Bola” está neste plano cartesiano, e assim mover os motores da forma correta, levando o robô para o local sentido certo, mas é preciso saber a aceleração correta, ou seja, quanto mais para as bordas o usuário leva o elemento “Bola”, maior deverá ser a aceleração, quando mais ao centro este elemento estiver, menor deverá ser a aceleração. Se pensarmos que a aceleração depende da distância que o cursor se encontra do centro do plano cartesiano, temos que calcular a tangente de um triângulo, como podemos ver na figura 4.
O Programa
Abaixo deixo o código fonte utilizado, com os comentários das linhas importantes, mas fazendo um resumo, criei duas variáveis “ondeD” e “ondeE”, onde calculo o tamanho da tangente e descubro quantos por cento é de 141, o tamanho máximo da tangente quando X e Y alcançam só extremos do elemento “Pintura”. Limitei a potência dos motores nas variáveis “Vmax” e “Vmin”, baseado nos testes que fiz nos motores que tinha em mãos, e criei mais duas variáveis para corrigir eventual diferença de potência entre os motores.
Feito estes cálculos, basta saber se o robô vai para frente ou para trás e aplicar a potência calculada.
from machine import Pin, PWM
from L298N_motor import L298N
import bluetooth
from ble_simple_peripheral import BLESimplePeripheral
import time
import math
ena_pin = Pin(0)
ENA = PWM(ena_pin)
ENA.freq(1000)
enb_pin = Pin(5)
ENB = PWM(enb_pin)
ENB.freq(1000)
IN1 = Pin(1, Pin.OUT)
IN2 = Pin(2, Pin.OUT)
IN3 = Pin(3, Pin.OUT)
IN4 = Pin(4, Pin.OUT)
motor2 = L298N(ENA, IN1, IN2)
motor1 = L298N(ENB, IN3, IN4)
# Criando um objeto BLE (Bluetooth Low Energy)
ble = bluetooth.BLE()
# Criando uma instancia da classe BLESimplePeripheral com o Objeto ble
sp = BLESimplePeripheral(ble,"Mooca")
led = Pin("LED", Pin.OUT)
def update_traffic(data):
decoded_data = data.decode('utf-8').rstrip('\r\n')
decoded_data = decoded_data.rstrip('\x00')
posicao = decoded_data.split("#")
direcao = int(posicao[1])
lado = int(posicao[0])
print("X = ", posicao[0])
print("Y = ", posicao[1])
desvMotorE = 0
desvMotorD = 0
Vmax = 60000
Vmin = 45000
corretorE = 10000
corretorD = 10000
potencia = ((100 * math.sqrt((100-direcao)**2 + (100-lado)**2) )/141) / 100
ondeE = 0
ondeD = 0
if lado < 94:
ondeD = round( Vmin + ((Vmax-Vmin) * potencia) + corretorD )
if lado > 74:
ondeE = ondeD
else:
ondeE = round( Vmin )
elif lado > 96:
ondeE = round( Vmin + ((Vmax-Vmin) * potencia) + corretorE)
if lado < 116:
ondeD = ondeE
else:
ondeD = round( Vmin )
else:
ondeE = Vmin
ondeD = Vmin
if direcao < 93: #Y
motor = Vmax * potencia
print("frente-> direcao: ", direcao, "motor esq: ", ondeE, " motor dir: ", ondeD, " Motor: ", motor, " Pot : ", potencia)
motor1.forward()
motor2.forward()
motor1.setSpeed(ondeE)
motor2.setSpeed(ondeD)
elif direcao > 97:
motor = Vmax * potencia
motor1.backward()
motor2.backward()
motor1.setSpeed(ondeE)
motor2.setSpeed(ondeD)
print("traz-> direcao: ", direcao, "motor esq: ", ondeE, " motor dir: ", ondeD, " Motor: ", motor, " Pot : ", potencia)
else:
motor1.stop()
motor2.stop()
print("parou-> direcao: ", direcao)
# Define a callback function to handle received data
def on_rx(data):
decoded = data.decode('utf-8').rstrip('\x00')
print("----------\n Valor recebido: ",decoded) # Mostra no shell o valor recebido
update_traffic(data)
# Start an infinite loop
while True:
if sp.is_connected(): # Verifica se foi estabelecida a conexão BLE
sp.on_write(on_rx) # Configura a função callback para a recepção de dados
Conclusão
Neste artigo pudemos ver como é possível utilizar o conhecimento matemático para o uso em aplicações práticas. Conheço algumas aplicações existente para download, onde o controle não tem o controle de velocidade, tornando os movimentos dos robôs e carrinhos de combate de forma “seca” e direta. Aqui podemos fazer curvas suaves, sem trancos e assim dar mais mobilidade para os projetos.
Referências:
Vídeo de conexão Bluetooth da Pi Pico 2W.
Usando o L298N



















