27 janeiro 2016

Semáforo com Arduino e Led Endereçável WS2812B RGB

Projetos de semáforo com Arduino são bastante comuns. A maioria usa leds convencionais para a montagem do projeto. Hoje eu vou mostrar um semáforo um pouco diferente, e que utiliza leds endereçáveis RGB WS2812B.

Semáforo com Arduino e Led Endereçável WS2812B


Mas o que são leds endereçáveis ?


O led endereçável WS2812B RGB


Os leds enderecáveis são dispositivos que reúnem em um mesmo componente um led RGB e o controlador WS2812B (datasheet), permitindo que cada led seja acessado individualmente. Cada led endereçável tem 6 pinos, sendo 3 de entrada e 3 de saída. 

Abaixo uma ligação básica de um led endereçável utilizando os 3 pinos de entrada: Vcc, GND e dados (Din):

Conexão Led Endereçável WS2812B


Repare que no lado esquerdo temos o pino Din (entrada), e no lado direito o pino Dout (saída). Esse esquema de ligação é o que permite que você ligue vários leds endereçáveis em um mesmo barramento: o pino Dout de um led vai ligado no Din do led seguinte, formando uma ligação em cascata:

WS2812B - Ligação em cascata


Dessa forma podemos ligar inúmeros leds ao microcontrolador utilizando apenas um fio, respeitando é claro as limitações de tensão e corrente para a quantidade de leds que formos utilizar. Cada led endereçável consome por volta de 60mA em brilho máximo, e recomenda-se o uso de uma fonte de alimentação externa no circuito.

Circuito Arduino e leds endereçáveis


O nosso sistema de semáforo utilizando leds endereçáveis usa 5 deles: 3 para o semáforo de carros e 2 para o semáforo de pedestres, além de um botão que o pedestre vai pressionar quando quiser atravessar a rua:

Circuito Arduino Uno - Leds endereçáveis WS2812B


O pino de dados dos leds será o pino 6 do Arduino, e para o botão vamos utilizar o pino 2. Lembre-se que o pino Dout de um led vai ligado ao pino Din do led seguinte. Um capacitor de 1000 µF entre os pinos GND e 5V serve como proteção contra variações de tensão que podem danificar os leds.

Programa semáforo com Arduino


Antes de copiar o programa, baixe a biblioteca Neopixel, da Adafruit (download). Descompacte a biblioteca e coloque-a dentro da pasta LIBRARIES da IDE do Arduino.

No inicio do programa definimos o pino de dados dos leds endereçáveis (linha 10), e também o número de leds que estão interligados (linha 15).

Para setar a cor de cada led, utilizamos o comando setPixelColor(), com a informação de qual led será aceso (o número do primeiro led é 0 (zero)), e também as informações RGB que irão acender o led na cor desejada, na seguinte sintaxe:
pixels.setPixelColor(<numero_led>, pixels.Color(R, G, B));
De uma forma bem simplificada, os valores de R, G e B definem a quantidade de luz vermelha, verde e azul serão utilizadas nos leds, formando a cor que desejamos. O vermelho, por exemplo, tem o valor 255 para o R (RED - vermelho), 0 para o verde e 0 para o azul. Usamos a mesma lógica para as outras cores, e você pode encontrar uma tabela básica com a relação de cores e valor RGB neste link.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//Programa: Semaforo com Arduino e led RGB WS2812B
//Autor: Arduino e Cia

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

//Pino de dados do Neopixel
#define PIN 6

#define PINO_BOTAO 2

//Numero de leds
#define NUMPIXELS 5

Adafruit_NeoPixel pixels=Adafruit_NeoPixel(NUMPIXELS,PIN,NEO_GRB+NEO_KHZ800);

int tempo_pedestre = 5000;

void setup()
{
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(PINO_BOTAO), pedestre, RISING);
  pixels.begin();
  //Utilize a linha abaixo para modificar o brilho dos leds
  pixels.setBrightness(50);
}

void loop()
{
  //*** Farol vermelho ***
  apaga(); 
  //Acende vermelho carros
  pixels.setPixelColor(4, pixels.Color(255, 0, 0));
  //Acende verde pedestre
  pixels.setPixelColor(0, pixels.Color(0, 255, 0));
  pixels.show();
  delay(tempo_pedestre);
  //Caso o botao tenha sido pressionado, volta ao
  //estado anterior (delay de 5000)
  if (tempo_pedestre == 10000)
  {
    tempo_pedestre = 5000;
  }

  //*** Farol amarelo ***
  apaga();
  //Acende vermelho pedestres
  pixels.setPixelColor(1, pixels.Color(255, 0, 0));
  //Acende amarelo pedestre
  pixels.setPixelColor(3, pixels.Color(255, 227, 17));
  pixels.show();
  delay(2000);
  
  //*** Farol verde ***
  apaga();
  //Acende vermelho pedestres
  pixels.setPixelColor(1, pixels.Color(255, 0, 0));
  //Acende verde carros
  pixels.setPixelColor(2, pixels.Color(0, 255, 0));
  pixels.show();
  delay(5000);
}

void apaga()
{
  //Apaga todos os leds
  for (int i = 0; i <= 5 ; i++)
  {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
    pixels.show();
  }
}

void pedestre()
{
  //Aumenta o tempo do farol vermelho
  for (int x = 0; x <= 5 ; x++)
  {
    Serial.println("Travessia de pedestre acionada");
    tempo_pedestre = 10000;
  }
}

O programa usa a interrupção 0, acionada por meio da porta 2 do Arduino, onde está ligado o botão. Ao ser pressionado, o botão gera uma interrupção, que chama a rotina pedestre(). Essa rotina aumenta o valor da variável tempo_pedestre para 10000, aumentando o tempo que o semáforo fica vermelho.

Em breve um vídeo do circuito em funcionamento. Não perca!

Nenhum comentário:

Postar um comentário