O objetivo deste projeto é desenvolver um simulador didático de distância de frenagem que possa ser utilizado em demonstrações em feiras de ciências e trabalhos escolares, tanto por estudantes do ensino fundamental quanto por estudantes do ensino médio. O simulador foi projetado tendo como base uma fita de LEDs RGB endereçáveis controlada por um sistema Arduino. Quanto ao código-fonte, foram utilizadas a linguagem de programação C padrão para Arduíno e a biblioteca Adafruit NeoPixel, esta que facilita o controle da fita de LEDs. O interessado pode montar o circuito eletrônico e inserir o código-fonte mesmo sem possuir conhecimentos em eletrônica ou programação.
Colisões traseiras são um dos tipos mais comuns de acidentes de trânsito ocorridos nas estradas no mundo todo. O motivo mais frequente de tais acidentes é exatamente o posicionamento incorreto do veículo em relação ao veículo da frente, sem que uma distância mínima de segurança seja guardada.
A colisão traseira ocasionada por distanciamento insuficiente é um tipo de acidente causado majoritariamente pela ação do motorista. Nesse caso, a prevenção depende pouco do estado do veículo, da condição da via ou da adequação da sinalização, mas depende principalmente da conscientização do motorista.
Este projeto apresenta um simulador didático de distância de frenagem para ser usado em demonstrações em feiras de ciências por alunos do ensino fundamental ou médio. Devido ao apelo visual, o objetivo do simulador é ser usado em campanhas de conscientização de trânsito. O desafio é manter uma distância mínima de segurança do veículo da frente de maneira a se conseguir parar sem provocar uma colisão no caso de uma frenagem brusca.
O simulador foi desenvolvido tendo como inspiração o projeto Open LED Race, uma iniciativa “maker” de código livre. A eletrônica é baseada em um sistema Arduino UNO, de fácil obtenção e relativamente baixo custo. O elemento visual é uma fita de LEDs RGB endereçáveis no padrão WS2812 ou WS2813, de qualquer quantidade de LEDs. Por fim, para facilitar o controle da fita, foi utilizada a biblioteca Adafruit NeoPixel.
Como funciona:
Um LED, sigla que significa Diodo Emissor de Luz, é um componente eletrônico que emite luz quando corretamente energizado. A luz produzida depende principalmente dos elementos químicos utilizados na construção do componente.
Um LED RGB, de LED Vermelho-Verde-Azul, é um tipo especial de LED que possui as três componentes básicas das cores em um único invólucro. Dependendo das tensões aplicadas entre os terminais, o LED emite luz na cor equivalente.
Por sua vez, uma fita de LEDs nada mais é do que uma associação de LEDs em paralelo. Com elas é possível obter-se efeitos de iluminação muito interessantes. Tais fitas estão disponíveis no mercado com LEDs de diversas cores, incluindo LEDs RGB, de maneira que a cor da fita possa ser personalizada.
Mais recentemente apareceram no mercado as fitas de LEDs RGB endereçáveis, que unem os efeitos obtidos com LEDs RGB e certa forma de automação, de maneira que cada LED possa ser configurado para brilhar em uma determinada cor, independente dos demais. As fitas mais conhecidas são no padrão WS2812 ou WS2813.
A maioria das fitas endereçáveis possuem três conexões: um terminal para a alimentação elétrica positiva, outro terminal comum e um terceiro terminal especial para conexão de dados. Essas fitas requerem, além da alimentação elétrica, um controlador digital. O funcionamento básico consiste em se usar um controlador para enviar pacotes de informações em formato digital pelo terminal lógico da fita. Os pacotes de dados devem conter, de maneira simplificada, o endereço do LED em relação ao começo da fita, as componentes de cor vermelho-verde-azul e as respectivas intensidades.
Cada fabricante possui controladores próprios para suas fitas, porém muitos fabricantes seguem os padrões WS2812 ou WS2813 de maneira que seus controladores e fitas são intercambiáveis. Isso também facilita a programação em caso de dispositivos como o Arduino. Nesse caso, existem disponíveis várias bibliotecas de funções prontas que facilitam o trabalho, como a famosa Adafruit NeoPixel.
Lista de materiais:
Os materiais usados neste projeto foram:
• Elegoo UNO R3 (compatível com Arduino)
• Chinly WS2812B LED Pixel Strip (144 leds)
• Amazon Basics Wall Charger 5V (carregador USB 2A)
• Arduino IDE 1.8.19
• Adafruit NeoPixel 1.10.3
• Resistor 440 ohms 1/4W
• Diversos: protoboard, botões, cabos, conectores...
Montagem:
A figura abaixo mostra o circuito eletrônico montado em uma protoboard. O alto-falante é opcional e não foi utilizado.
Antes de inserir o código fonte no Arduino, deve-se instalar a biblioteca Adafruit NeoPixel conforme as figuras abaixo.
Ao inserir o código-fonte, o Arduino começa a executá-lo automaticamente. Pressione repetidas vezes os botões para acelerar ou frear o veículo.
Prova e uso:
Após o código-fonte ser inserido, o Arduino pode ser desconectado do computador. Pode-se alimentar o circuito então com uma fonte de 5V capaz de fornecer corrente suficiente para acender os LEDs. No caso deste simulador, como apenas dois ou três LEDs serão acessos simultaneamente, um carregador USB comum é suficiente.
A simulação inicia com os veículos posicionados no início da fita. Nenhum veículo se move até que um botão seja pressionado. Pressione o acelerador ou o freio repetidas vezes para alterar a velocidade do veículo. A simulação termina se os veículos colidirem ou se ambos pararem sem que colidam. Um indicativo visual é mostrado e a simulação reinicia automaticamente após cinco segundos.
Referencias:
MAKER SOCIETY, Open LED Race Project, https://openledrace.net/, acessado em 08/12/2021.
ARDUINO, Arduino, https://www.arduino.cc/, acessado em 22/12/2021.
ARROW, Protocol for the WS2812B Programmable LED, https://www.arrow.com/en/research-and-events/articles/protocol-for-the-ws2812b-programmable-led, acessado em 22/12/2021.
Código-fonte completo:
#include
#define LEDS 144 // Quantidade de leds na fita.
#define PINO_LEDS A0 // Pino de dados da fita.
#define PINO_ACELERADOR 6 // Pino do botao do acelerador.
#define PINO_FREIO 7 // Pino do botao do freio.
#define VOLTAS_MIN 2 // Mimino antes do carrinho frear.
#define VOLTAS_MAX 5 // Maximo ate o carrinho frear.
#define FATOR_ACELERACAO 0.1 // Intensidade do acelerador.
#define FATOR_FRENAGEM 0.05 // Intensidade do freio.
#define VELOCIDADE_MAXIMA 0.15 // Maxima do carrinho azul.
#define PAUSA 5 // Taxa de atualizadao geral.
float velocidade_1 = 0;
float velocidade_2 = 0;
float distancia_1 = 0;
float distancia_2 = 0;
int voltas_percorridas = 0;
long distancia_sorteada = 0;
byte flag_acelerador = 0;
byte flag_freio = 0;
Adafruit_NeoPixel fita = Adafruit_NeoPixel(LEDS, PINO_LEDS, NEO_GRB + NEO_KHZ800);
void setup()
{
fita.begin();
pinMode(PINO_ACELERADOR, INPUT_PULLUP);
pinMode(PINO_FREIO, INPUT_PULLUP);
inicia_simulacao();
}
void inicia_simulacao()
{
for (int i = 0; i < LEDS; i++)
fita.setPixelColor(i, fita.Color(0, 0, 0));
velocidade_1 = 0;
velocidade_2 = 0;
distancia_1 = 1;
distancia_2 = 0;
voltas_percorridas = 0;
distancia_sorteada = random(LEDS * VOLTAS_MIN, LEDS * VOLTAS_MAX);
flag_acelerador = 0;
flag_freio = 0;
}
void loop()
{
for (int i = 0; i < LEDS; i++)
fita.setPixelColor(i, fita.Color(0, 0, 0));
if ((flag_acelerador == 1) && (digitalRead(PINO_ACELERADOR) == 0))
{
flag_acelerador = 0;
velocidade_1 = VELOCIDADE_MAXIMA;
velocidade_2 += FATOR_ACELERACAO;
}
if ((flag_acelerador == 0) && (digitalRead(PINO_ACELERADOR) == 1))
flag_acelerador = 1;
if ((flag_freio == 1) && (digitalRead(PINO_FREIO) == 0))
{
flag_freio = 0;
velocidade_1 = VELOCIDADE_MAXIMA;
if (velocidade_2 >= FATOR_FRENAGEM)
velocidade_2 -= FATOR_FRENAGEM;
else
velocidade_2 = 0;
}
if ((flag_freio == 0) && (digitalRead(PINO_FREIO) == 1))
flag_freio = 1;
if (distancia_1 >= distancia_sorteada)
velocidade_1 = 0;
distancia_1 += velocidade_1;
distancia_2 += velocidade_2;
if (distancia_2 > distancia_1)
{
fita.setPixelColor(10, fita.Color(255, 0, 0));
fita.setPixelColor(20, fita.Color(255, 0, 0));
fita.setPixelColor(30, fita.Color(255, 0, 0));
fita.show();
delay(5000);
inicia_simulacao();
}
if (distancia_1 > LEDS * voltas_percorridas)
voltas_percorridas++;
if ((voltas_percorridas > VOLTAS_MIN) && (distancia_2 > 0) && (velocidade_2 <= 0))
{
fita.setPixelColor(10, fita.Color(255, 0, 255));
fita.setPixelColor(20, fita.Color(255, 0, 255));
fita.setPixelColor(30, fita.Color(255, 0, 255));
fita.show();
delay(5000);
inicia_simulacao();
}
if (distancia_1 >= distancia_sorteada)
fita.setPixelColor(((word)distancia_1 % LEDS), fita.Color(255, 0, 0));
else
fita.setPixelColor(((word)distancia_1 % LEDS), fita.Color(0, 0, 255));
fita.setPixelColor(((word)distancia_2 % LEDS), fita.Color(0, 255, 0));
fita.show();
delay(PAUSA);
}