Básico - Projeto 27

Criando cores com Led RGB usando comunicação serial

Objetivo

Criar um circuito onde se pode gerar cores em um LED RGB através do teclado do computador. Neste projeto você controlará seu Led RGB, enviando comandos do PC para o microcontrolador, usando o Serial Monitor do IDE do Arduino. A comunicação serial é o processo de envio de dados, um bit de cada vez, por um link de comunicação.

Obs.: Fazendo o controle do brilho de cada um dos leds encapsulado em um Led RGB podemos misturar estes brilhos e produzir diversas cores diferentes. Combinando os valores de cada cor podemos criar até 16,7 milhões de cores diferentes (256 X 256 X 256).

Aplicação

Para fins didáticos, estudo do PWM (Pulse Width Modulation), valores RGB (Red, Green and Blue), comunicação serial e aplicações com LEDs.

Componentes necessários

Referência

Componente

Quantidade

Imagem

Observação

Protoboard Protoboard 830 pontos 1 Resultado de imagem para protoboard 830v Utilizar protoboard com 830 pontos
Led RGB Led RGB 5mm 1 Você poderá utilizar um LED RGB ânodo ou cátodo.

Você poderá utilizar também um LED RGB difuso ou de alto brilho.

Você poderá substituir o Led RGB por 3 Leds comuns, sendo 1 vermelho, 1 verde e um azul.
Resistor Resistor 3 2 Resistor de 150Ω
  1Resistores de 100Ω

Se precisar usar outros valores, calcule o resistor apropriado para o led utilizado - Calcular Resistor.
Arduino UNO R3 Arduino UNO 1  

Obs.: Utilizar também Cabos de ligação e uma folha de papel A4 para criar um difusor.

Montagem do Circuito

Conecte os componentes no Protoboard como mostra a figura abaixo. Verifique cuidadosamente os cabos de ligação antes de ligar seu Arduino. Lembre-se que o Arduino deve estar totalmente desconectado da força enquanto você monta o circuito.

Obs.: O Led RGB à esquerda poderá ser substituido por 3 leds comuns, sendo 1 vermelho, 1 verde e 1 azul.

Atenção:

1) O LED RGB nada mais é que três Leds em um só, formado por um led vermelho (R de red), um verde (G de green) e um azul (B de blue). Associando as cores e intensidade do brilho dos três Leds é possível se obter várias possibilidades de cores.

2) Lembre-se que existem 2 tipos de LED RGB, o ânodo comum e o cátodo comum. Observe que para cada uma das cores existe um terminal, e além disso o quarto terminal (maior) deverá ser conectado ao polo positivo (ânodo comum) e ao polo negativo (cátodo comum).

Esquema LED RGB

3) ATENÇÃO: Podem existir no mercado outros tipos de LED RGB com configurações dos terminais diferentes dos LEDs RGB comuns (veja a imagem abaixo). Por isso é importante verificar com o fornecedor o tipo de LED que irá adquirir. Caso o seu LED RGB tenha os pinos configurados conforme figura abaixo ou de outro tipo, basta ajustar as variáveis globais R, G e B do sketch do nosso projeto.

Resultado de imagem para rgb led pins

4) Para determinar os valores dos resistores para o seu LED RGB, utilize os dados do fabricante (datasheet). No nosso projeto, utilizamos um LED RGB tipo ânodo comum com as seguintes características:

A partir destes dados calculamos o valor dos resistores (ou determine através da tabela prática: Tabela prática de utilização de leds 3mm e 5m). Para calcular o valor dos resistores leia: Como calcular o resistor adequado para o led ou utilize o aplicativo: Calculador de Led.

Após os cálculos determinamos os seguintes resistores: 2 resistores de 100Ω (terminais cor verde e azul) e 1 resistor de 150Ω (terminal cor vermelho).

Obs: Se você não tiver os dados do fabricante, utilize como referência os valores dos resistores que mostramos acima, tanto para o LED alto brilho como para o LED difuso. Se não tiver os resistores com os valores exatos ao determinado, utilize resistores com valores mais altos. No nosso exemplo utilizamos 2 resistores de 100Ω (terminais cor verde e azul) e 1 resistor de 150Ω (terminal cor vermelho).

5) Veja na imagem abaixo como posicionamos o nosso LED RGB cátodo comum (conectado ao polo negativo GND) no protoboard.

6) Veja na imagem abaixo que utilizamos 1 LED RGB cátodo comum (conectado ao polo negativo GND) e que a montagem do circuito foi realizada em um protoboard com linhas de alimentação separadas. Verifique se o seu protoboard possui linhas de alimentação contínuas ou separadas - sabia mais em protoboard.

Obs 1: Caso tenha um LED RGB ânodo comum, conecte o terminal mais logo no 5V (polo positivo do Arduino).

Obs 2: Se você não tiver 1 LED RGB, substitua-o por 3 leds comuns, sendo 1 vermelho, 1 verde e 1 azul.

Testando a conexão do Led RGB

Para testarmos o circuito e verificar se o LED RGB está corretamente conectado, utilize o código abaixo:

/*******************************************************************************
*
*             Usando um LED RGB (TESTE)
*            http://squids.com.br/arduino
*
*******************************************************************************/
 
const int R = 3;
const int G = 5;
const int B = 6;

void setup(){
    pinMode(R, OUTPUT);
    pinMode(G, OUTPUT);
    pinMode(B, OUTPUT);
}
void loop(){
    digitalWrite(R, HIGH);
    digitalWrite(G, LOW);
    digitalWrite(B, LOW);
    delay(1000);
    digitalWrite(R, LOW);
    digitalWrite(G, HIGH);
    digitalWrite(B, LOW);
    delay(1000);
    digitalWrite(R, LOW);
    digitalWrite(G, LOW);
    digitalWrite(B, HIGH);
    delay(1000);
} 

Observe que a cada segundo (1000ms) aparecerá as cores vermelho, azul e verde sucessivamente, nesta ordem. Se o LED RGB não acender, inverta a conexão do terminal maior (de 5V para GND ou vice-versa dependendo do tipo LED que esteja utilizando, ânodo comum ou cátodo comum).

Esquema LED RGB

Se ao iniciar o programa e não aparecer a cor vermelho em primeiro lugar, possivelmente é porque o LED RGB que você está utilizando é um tipo configuração diferente dos LEDs mais comuns. Neste caso, altere as variáveis globais do probrama, como no exemplo abaixo:

const int R = 6;
const int G = 3;
const int B = 5;

Resultado de imagem para rgb led pins

Faça novamente o e ajuste o sketch até encontrar os valores corretos. Depois utilize esses valores para declarar as variáveis no nosso projeto a seguir.

Código do Projeto (sketch)

Neste projeto vamos criar diversas combinações de cores utilizando um LED RGB e o PWM (Pulse width modulation - Modulação). O controle de cores deverá ser feito através do teclado do computador onde utilizaremos a comunicação serial entre o microcontrolador e a IDE do Arduino.

Faça o dowload e abra o arquivo projeto27.ino no ambiente de desenvolvimento do Arduino:

Vídeo

Como o projeto deve funcionar

1. Após iniciar o programa no Arduino, o Led RGB ficará apagado.

2. Para inserir os dados que irão gerar as cores no Led RGB será necessário utilizar o monitor serial do IDE do Arduino. Clique no ícone como mostra a figura abaixo:

3. Digite os valores no campo indicado na figura abaixo:

4. Os valores poderão digitados utilizando as letras R, G e B em maiúsculas ou minúsculas, seguidas por um valor de 0 a 255. Você poderá digitar uma vírgula ou espaço entre os parâmetros, e pode digitar um, dois  ou três valores do Led RGB a qualquer momento, como por exemplo:

r255 b100
r127 b127 g127
G255, B100
b127,R0,g255

5. No nosso exemplo vamos gerar a cor cor Orchild2 (Tabela cores Visual Dicas), ou seja R = 238, G = 122 e B = 233. Então, podemos digitar da seguinte forma:

Depois clique no botão enviar ou digite a tecla [Enter].

6. Veja que o Led RGB gerou a cor referente aos dados digitados no seu computador.  O monitor serial irá informar os valores do brilho para cada cor do Led RGB:

7. Utilize um difusor (cilindro de papel A4, por exemplo) para que a mistura de cores fique mais agradável, fazendo com que você visualize melhor a cor resultante.

8. Repita a operação para gerar novas cores.

Observações:

a) Para que o Arduino possa se comunicar com o computador, é necessário que estejam conectados por um cabo USB.

b) Alternativamente, pode-se utilizar 3 LEDs comuns, sendo um vermelho, um verde e um azul para um ou para os dois LEDs RGB.

c) Combinando os valores do brilho de cada cor, vermelho, verde e azul, podemos criar até 16,7 milhões de cores diferentes (256 X 256 X 256).

PWM - Pulse With Modulation

Como demonstrado nos projetos Projeto 14 - Led com efeito dimmer usando potenciômetro e Projeto 18 - Efeito lâmpada pulsante, este experimento também utiliza o conceito o PWM (Pulse Width Modulation, em português, modulação por largura de pulso) no controle da luminosidade (intensidade do brilho dos LEDs).

O Arduino UNO, que utilizamos no exemplo, possui 6 saídas digitais que podem ser utilizadas como PWM, sendo elas: 11, 10, 9, 6, 5 e 3.

Para saber mais sobre PWM, leia o tutorial: O que é PWM e para que serve?

Valores RGB

Um valor RGB (255, 0, 0) é vermelho puro, enquanto um valor (0, 255, 0) é verde puro e (0, 0, 255), azul puro. Misturando esses valores você pode obter todas as cores. Mesmo se estivesse simplesmente acendendo e apagando os LEDs, sem utilizar luminosidades diferentes, ainda se conseguiria cores diferentes como mostramos na figura abaixo.

Cores disponíveis acendendo e apagando os LEDs em combinações diferentes

Ao ajustar o brilho utilizando PWM, variando de 0 a 255, você também pode obter outras cores. Colocando o LED RPG através de um cilindro de papel, por exemplo, o espectro de luz das três cores primárias e suas intensidades criará uma única cor. O número total de cores disponíveis, utilizando PWM com um intervalo de 0 a 255, é de 16.777.216 cores (256 x 256 x 256).

Explicando o Código do Projeto

Este projeto apresenta vários novos conceitos, incluindo comunicação serial, ponteiros e manipulação de strings.

1. Primeiro declaramos as constantes e as variáveis do projeto.

1.1. Observe que utilizamos constantes e variáveis tipo "int" e "char". Veja na tabela abaixo as diferenças nos tipos de constantes e variáveis:

Tipo Valores Válidos para Variáveis e Constantes
char letras e símbolos: 'a', 'b', 'H', '^', '*','1','0'
int de -32767 até 32767 (apenas números inteiros)
float de -3.4 x 1038 até +3.4 x 10+38 com até 6 dígitos de precisão (2 casas depois da vírgula)
double de -1.7 x 10308 até +1.7 x 10+308com até 10 dígitos de precisão

1.2. As constantes tipo inteiro RedPin, GreenPin e BluePin, se referem aos terminais do LED RGB conectados aos pinos 3, 5 e 6 do controlador Arduino (saídas utilizada como PWM).

1.3. A variável buffer[18] define um array de 18 caracteres (tipo char) para armazenar uma string de texto maior do que o máximo de 16 permitidos, evitando que não haja erros de estouro de buffer. Exemplo: Se você digitar -> r255, g255, b255 (obteremos 16 caracteres).

2. Através da estrutura void setup():

border:1px solid #000;

2.1. A função Serial.begin() serve para dizer ao Arduino que será coletado dados para o computador a partir da porta serial e o cabo USB. O número entre os parênteses significa qual é a taxa de dados que a placa vai se comunicar com o computador. Utilizaremos a taxa padrão de 9600bps (bits-per-second).

2.2. A função Serial.flush liberará caracteres que estejam na linha serial, deixando-a o buffer de entrada da porta serial vazia e pronta para entradas/saídas de dados. Isto é, qualquer chamada à Serial.read() ou Serial.avaiable somente retornarão dados recebidos após a última chamada à Serial.flush().

Obs.: Na prática, a função Serial.flush libera o campo para entrada de dados no monitor serial.

2.3. Escrevermos na tela do Monitor Serial uma única vez a frase "Digite valores para r, g, e b" através do comando Serial.println(). O comando println() diz ao monitor que se deve pular uma linha após escrever o valor definido entre parêntesis. 

2.2. Define-se as constantes RedPin, GreenPin e BluePin como saídas do controlador Arduino (OUTPUT) conectados aos pinos 3, 5 e 6 respectivamente.

3. Através da estrutura void loop(), obtemos:

3.1. O loop principal começa com a instrução if (Serial.available() >0). A variável do sistema Serial.available() retorna o número de bytes (caracteres) disponíveis para leitura através da porta serial (o buffer serial pode armazenar até 128 bytes).

3.2. Se os caracteres já tiverem sido recebidos, ou seja, o número de bytes é maior que 0, a condição é atendida e o código dentro do bloco de instruções if é executado (Isto é verificado após você digitar os dados e clicar no botão enviar do monitor serial):

3.2.1. Declara-se a variável inteira index igual a zero.

3.2.3. Através do comando delay(100), o programa espera 100ms. Isto é necessário para garantir que o buffer serial (local na memória em que os dados recebidos são armazenados, antes do processamento) esteja cheio antes de processar os dados. Caso você não faça isso, é possível que a função seja executada e inicie o processamento da string de texto antes de você receber todos os dados, pois as linha de comunicações seriais é muito lenta comparada à velocidade de execução do restante do código.

3.2.4. Declara-se a variável tipo inteira numChar igual ao valor retornado pela função Serial.available(), ou seja o número de caracteres digitado.

3.2.5. Através da condicional if, define-se o número máximo da variável numChar igual a 15. Isso garante que você não estoure a matriz char buffer[18] definida anteriormente.

3.2.6. Usando a instrução loop while, verifica se a variável numChar é diferente de zero. Observe que utilizamos a expressão (numChar--) criamos um decremento, ou seja, o número é subtraído de 1 depois de ser utilizado.

Obs.: Se utilizarmos a expressão (--numChar) o número seria diminuído antes de ser avaliado.

3.2.6.1. Se a variável numChar for diferente de zero, define-se que a variável buffer[index++] será igual à variável Serial.read(). A variável de sistema Serial.read() lê dados que estejam entrando pela porta serial, byte por byte, ou seja retorna o valor de um caractere de cada vez. Desta forma, todos os caracteres digitados que serão armazenados na matriz buffer[], começando por buffer[0] até ao índice máximo de 15, se numChar for maior que 15.

3.2.6.2. Assim, quando numChar atingir zero, lemos todo o comprimento da string digitada. A expressão também não atenderá mais ao comando while.

3.2.7. Após armazenar os valores dos caracteres na variável stray buffer[], o código chama a função splitString(buffer);

4. Através da função void splitString() que criamos, obteremos: