Projeto | Controlador de Semáforo com Micropython

Este post faz parte da série Raspberry Pi Pico com MicroPython

Introdução

Os microcontroladores podem ser encontrados em quase todos os dispositivos eletrônicos utilizados diariamente, incluindo os semáforos. Um controlador de semáforo é um sistema construído para mudar as luzes com o uso de um temporizador, observar os pedestres que desejam atravessar e até mesmo pode ajustar o tempo das luzes dependendo do volume de tráfego – comunicando-se com os sistemas de semáforos próximos para garantir que toda a rede de tráfego flua suavemente.

Embora a construção de um sistema de gerenciamento de tráfego em larga escala seja um projeto bastante avançado, é muito simples construir um pequeno simulador usando um Raspberry Pi Pico. Assim, neste artigo, vamos criar um mini sistema de semáforos.

Um projeto simples de um Controlador de Semáforo com Micropython

Materiais necessários

Para esse projeto vamos precisar de:

  • 1 x Raspberry Pi Pico
  • 1 x Protoboard
  • 1 x Led verde
  • 1 x Led amarelo
  • 1 x Led vermelho
  • 3 x Resistores de 1kΩ 
  • 1 x Botão de pressão (push-button)
  • 1 x Buzzer
  • 1 x Cabo micro USB
  • Jumper

Circuito

Com a protoboard em mãos e a placa Raspberry Pi Pico já inserida nela, siga as instruções abaixo para conectar o LED vermelho:

Pegue o LED vermelho e insira-o na protoboard de forma que um terminal fique à direita da divisão central e o outro à esquerda.

O terminal mais longo do LED, chamado de ânodo, será conectado ao resistor.

Conecte o resistor ao pino GP15 (pino 20) da placa Raspberry Pi Pico.

Para se orientar quanto aos pinos da Pico, basta visualizar o pinout da placa na Figura 1.

Nota: É importante lembrar de tomar cuidado com a polaridade do LED. O terminal mais longo (ânodo) deve ser conectado ao lado positivo da alimentação (pino GP15), e o terminal mais curto (cátodo) ao lado negativo (terra ou GND).

Figura 1 – Raspberry Pi Pico pinout.

Com um jumper, conecte o terminal mais curto (cátodo) do LED vermelho à trilha de terra (GND) da protoboard. Em seguida, pegue outro jumper e conecte a trilha de terra a um dos pinos GND da placa Pico, optando por conectar no pino 38.

Agora, você tem o LED vermelho devidamente conectado à sua placa Pico. No entanto, um semáforo real possui pelo menos mais dois LEDs. Então, pegue o LED amarelo e conecte-o à sua placa Pico da mesma forma que fizemos com o LED vermelho, mas desta vez conecte a perna mais longa (sem se esquecer do resistor) ao pino ao lado do que conectamos o LED vermelho, GP14.

Por fim, pegue o LED verde e conecte-o da mesma maneira ao pino GP13. Mas se atente, pois este não é o pino imediatamente ao lado do pino GP14. Observe a Figura 1 para se orientar nas posições corretas dos pinos.

Por fim, na Figura 2 temos a montagem da protoboard e na Figura 3 a montagem física.

Nota: Certifique-se de seguir corretamente a polaridade dos LEDs, conectando o terminal mais longo (ânodo) ao lado positivo da alimentação (pino GP13 e GP14), e o terminal mais curto (cátodo) ao lado negativo (terra ou GND).

Controlador de Semáforo com Micropython
Figura 2 – Montagem do projeto no Fritzing

Controlador de Semáforo com Micropython
Figura 3 – Montagem do projeto com componentes físicos.

Programa para controlar LEDs do semáforo

Como nos demais programas feitos nos exemplos anteriores, vamos utilizar a IDE Thonny. Para isso, começaremos com “import machine.Pin” para acessar os pinos da placa. Além disso, adicionaremos a biblioteca “utime” para inserir atrasos e controlar o acendimento e apagamento dos LEDs.

Assim como nos programas anteriores em que utilizamos os GPIOs do Pico, é necessário configurar cada pino antes de controlá-lo. Além disso, o semáforo não deve parar nunca; faremos um loop utilizando o ‘while’. Abaixo temos o código do semáforo.

from machine import Pin
import utime

led_red= Pin(15,Pin.OUT) #definindo o pino 15 como saída
led_yellow= Pin(14,Pin.OUT) #definindo o pino 14 como saída
led_green= Pin(13,Pin.OUT) #definindo o pino 13 como saída

while True:
    led_red.value(1)
    utime.sleep(5) #led vermelho fica aceso por 5s
    led_red.value(0) #led vermelho apaga
    led_green.value(1)
    utime.sleep(5) #led verde fica aceso por 5s
    led_green.value(0) #led verde apaga
    led_yellow.value(1)
    utime.sleep(3) #led amarelo fica aceso por 3s
    led_yellow.value(0) #led amarelo apaga

Utilizando o loop “while True” o LED vermelho é aceso por 5 segundos, depois é desligado. Em seguida, o LED verde é aceso por 5 segundos e desligado. Por fim, o LED amarelo é aceso por 3 segundos e desligado. O ciclo continua repetindo-se indefinidamente.

Lembrando que é apenas uma simulação, em um semáforo real apenas 5 segundos impossibilitaria o fluxo de carros.

Se você não possui os componentes físicos para o projeto, é possível testar o programa utilizando o simulador Wokwi. Abaixo temos a simulação virtual:

Programa para controlar sistema “puffin crossings”

No Reino Unido, o tipo mais comum de semáforos para pedestres é conhecido como “puffin crossings“, que são passagens de pedestres operadas pelos próprios pedestres. Dessa forma, quando um pedestre pressiona o botão de solicitação de travessia, o “puffin crossing” avaliará a situação atual do tráfego e determinará o momento adequado para parar o tráfego veicular e permitir que os pedestres atravessem com segurança. Além disso, eles podem possuir recursos adicionais, tais como sinal sonoro (buzzer), para indicar quando é seguro atravessar.

Para transformar nosso sistema de semáforos em uma passagem de pedestres “puffin crossing”, precisaremos adicionar dois componentes ao nosso circuito, um push-button, para que o pedestre possa solicitar que os semáforos permitam a travessia da rua, e um buzzer, para que o pedestre saiba quando é a vez de atravessar.

Conforme mostrado na Figura 3, o push-button será conectado no pino GP11 e ao GND da protoboard, e o buzzer será conectado no pino GP12 e à GND da protoboard.

Controlador de Semáforo com Micropython
Figura 4 – Montagem do projeto no Fritzing

Controlador de Semáforo com Micropython
Figura 5 – Montagem do projeto com componentes físicos.

Agora é preciso configurar os novos pinos utilizados para poder controlá-los. Em seguida, precisamos determinar uma maneira do programa monitorar constantemente o valor do botão.

Entretanto, é importante destacar que, para um “puffin crossing”, o programa precisa ser capaz de registrar se o botão foi pressionado sem que essa ação interrompa o programa do acendimento dos semáforos. Para alcançar esse objetivo, precisaremos utilizar a biblioteca _thread.

Uma thread, ou fluxo de execução, é um programa parcialmente independente. Por exemplo, podemos pensar no loop escrito anteriormente como a thread principal do programa, e com o uso da biblioteca “_thread”, podemos criar uma thread adicional que executa ao mesmo tempo.

Antes de criar outra thread, é preciso ter uma maneira para que a nova thread se comunique com a thread principal – e isso pode ser feito usando variáveis globais. Como uma variável global funciona em todos os lugares, uma thread pode alterar o valor e outra pode verificar se foi alterado.

Portanto, vamos criar uma variável global chamada “button_pressed” e atribuir a ela o valor padrão False. Isso significa que, quando o programa é iniciado, o botão ainda não foi pressionado. Com isso, o próximo passo é definir a sua thread.

Abaixo temos o programa completo.

from machine import Pin
import utime
import _thread


led_red= Pin(15,Pin.OUT) #definindo o pino 15 como saida
led_yellow= Pin(14,Pin.OUT) #definindo o pino 14 como saida
led_green= Pin(13,Pin.OUT) #definindo o pino 13 como saida
button = Pin(16, Pin.IN, Pin.PULL_DOWN) #definindo o pino 11 como entrada
buzzer = Pin(12, Pin.OUT) #definindo o pino 16 como saida

global button_pressed
button_pressed = False

def button_reader_thread(): #definindo o novo valor de button_pressed
    global button_pressed
    while True:
        if button.value() == 1:
            button_pressed = True
        utime.sleep(0.01)
       
_thread.start_new_thread(button_reader_thread, ())

while True:
    if button_pressed == True:
        led_red.value(1)
        for i in range(10): #definindo período de toque do buzzer
            buzzer.value(1)
            utime.sleep(0.2)
            buzzer.value(0)
            utime.sleep(0.2)
        global button_pressed
        button_pressed = False
       
    led_red.value(1)
    utime.sleep(5) #led vermelho fica aceso por 5s
    led_red.value(0) #led vermelho apaga
    led_green.value(1)
    utime.sleep(5) #led verde fica aceso por 5s
    led_green.value(0) #led verde apaga
    led_yellow.value(1)
    utime.sleep(3) #led amarelo fica aceso por 3s
    led_yellow.value(0) #led amarelo apaga

Se você não possui os componentes físicos para o projeto, é possível testar o programa utilizando o simulador Wokwi. Abaixo temos a simulação virtual:

O programa “button_reader_thread()” instrui a biblioteca _thread a iniciar a thread que você definiu. A thread começará a ser executada e entrará rapidamente no seu loop – verificando o botão milhares de vezes por segundo para verificar se ele já foi pressionado. Enquanto isso, a thread principal continuará com a parte principal do seu programa.

Ao testar, veremos que inicialmente o programa será executado normalmente: as luzes de trânsito acenderão e apagarão no padrão usual. No entanto, ao pressionar o botão, se o programa estiver atualmente no meio do seu loop, nada acontecerá até que ele chegue ao fim e faça um novo ciclo. Nesse momento, a luz ficará vermelha, e o buzzer emitirá um bip para indicar que é seguro atravessar a rua.

Após isso, o padrão se repetirá normalmente, com o LED vermelho permanecendo aceso por mais cinco segundos, além do tempo em que ficou aceso enquanto o buzzer estava tocando. Isso simula o funcionamento de um verdadeiro puffin crossing: a luz vermelha permanece acesa mesmo depois que o buzzer parou de tocar, para que qualquer pessoa que tenha começado a atravessar a rua enquanto o buzzer estava tocando tenha tempo suficiente para chegar ao outro lado antes que o tráfego seja liberado.

Conclusão

Com este projeto, nós aprendemos como controlar vários LEDs, definir diferentes temporizações e monitorar uma entrada de botão enquanto o restante do programa continua em execução usando uma técnica conhecida como threading (encadeamento).

Raspberry Pi Pico com MicroPython

Raspberry Pi Pico: Timer One Shot com MicroPython Projeto | Medidor de temperatura com MicroPython
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
0 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Home » Software » Projeto | Controlador de Semáforo com Micropython

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: