Aprendendo a identificar cores com Arduino e o sensor TCS320

Fala galera, tudo bem com vocês? Eu espero que sim! Hoje vamos aprender a identificar cores usando o Arduino e o sensor TCS320! Nós já temos um tutorial sobre este sensor aqui em nosso blog, confira este tutorial clicando aqui! Mas como sempre trazemos novidades aqui no blog Arduino Ômega, e desta vez não poderia ser diferente, vamos iniciar neste post um grande projeto de Automação Industrial, e para começar iremos revisitar o uso do sensor TCS320.  Iremos ensinar a programar o sensor de cor com o Arduino, porém além do método tradicional, vamos aprender uma segunda abordagem que é usando uma biblioteca desenvolvida para o sensor de cor TCS320. Então vamos fazer assim, primeiro apresentamos o código tradicional e depois o código usando a biblioteca.

Montando o projeto

Abaixo segue a lista dos materiais usando no projeto:

E na imagem abaixo podemos conferir como ficou a ligação do sensor no Arduino:

 Infelizmente o sensor é grande demais para caber em apenas 01 protoboard mini, neste caso, utilize 02 como mostrado na figura.

Desenvolvendo com código tradicional sem biblioteca

Quando olhar para esse código tradicional e o com biblioteca você não notará muita diferença em número de linhas escritas, mas verá a questão de semântica, é mais fácil ler o código com biblioteca do que o sem, porém esse é um exemplo básico, quando partir para um projeto mais robusto sentirá a diferença na calibração do sensor, ai sim a biblioteca fará grande diferença.

Abaixo podemos ver a primeira parte do código sem a biblioteca:

//Pinos de conexao do modulo
const byte s0 = 8, s1 = 9, s2 = 12, s3 = 11, out = 10;
 
//Variaveis cores
int vermelho = 0, verde = 0, azul = 0;
 
void setup(){
  Serial.begin(9600);
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(out, INPUT);
  digitalWrite(s0, HIGH);
  digitalWrite(s1, LOW);
}
 
void loop(){
    //Função responsável por detectar a cor
  color();
    //Mostra valores no serial monitor
  Serial.print("Vermelho :"); Serial.print(vermelho, DEC);
  Serial.print(" Verde : ");  Serial.print(verde, DEC);
  Serial.print(" Azul : ");   Serial.print(azul, DEC);
  Serial.println();
 
    //Verifica se a cor vermelha foi detectada
  if (red < blue && red < green && red < 100) Serial.println("Vermelho"); 
    //Verifica se a cor azul foi detectada
  else if (blue < red && blue < green && blue < 1000) Serial.println("Azul"); 
    //Verifica se a cor verde foi detectada
  else if (green < red && green < blue) Serial.println("Verde");
  else Serial.println("Cor não detectada!");
}
 
void color(){
    //Lê o valor das cores
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
    //count OUT, pRed, RED
  red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  digitalWrite(s3, HIGH);
    //count OUT, pBLUE, BLUE
  blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  digitalWrite(s2, HIGH);
    //count OUT, pGreen, GREEN
  green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
}

Mergulhando no código tradicional sem biblioteca

Vamos conferir como ficou as declarações de variáveis e a função setup:

//Pinos de conexao do modulo
const byte s0 = 8, s1 = 9, s2 = 12, s3 = 11, out = 10;
 
//Variaveis cores
int vermelho = 0, verde = 0, azul = 0;
 
void setup(){
  Serial.begin(9600);
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(out, INPUT);
  digitalWrite(s0, HIGH);
  digitalWrite(s1, LOW);
}

A primeira parte do código consiste na declaração das variáveis referente às portas do Arduino, observe que os nomes s0, s1, s2, s3 e out fazem referência a pinagem do sensor, tente seguir esse padrão de desenvolvimento, assim seu desenvolvimento e manutenção do código será mais fácil.

No setup, define que os pinos s’s são de saída e o out de entrada e logo em seguida liga o pino s0 e desliga o s1.

Abaixo podemos conferir a função loop:

void loop(){
    //Função responsável por detectar a cor
  color();
    //Mostra valores no serial monitor
  Serial.print("Vermelho :"); Serial.print(vermelho, DEC);
  Serial.print(" Verde : ");  Serial.print(verde, DEC);
  Serial.print(" Azul : ");   Serial.print(azul, DEC);
  Serial.println();
 
    //Verifica se a cor vermelha foi detectada
  if (red < blue && red < green && red < 100) Serial.println("Vermelho"); 
    //Verifica se a cor azul foi detectada
  else if (blue < red && blue < green && blue < 1000) Serial.println("Azul"); 
    //Verifica se a cor verde foi detectada
  else if (green < red && green < blue) Serial.println("Verde");
  else Serial.println("Cor não detectada!");
}

Logo no início do loop tem a chamada da função color(), essa função foi definida por nós, você pode usar o nome que desejar, mas sugiro que esse nome faça sentido para o seu código. Não vamos falar dela agora, deixaremos pro próximo bloco, porém quando o código retorna desta função ele já traz 03 valores que são referente às incidência das cores vermelho, verde e azul, esse valores são apresentados nas linhas 22, 23 e 24 e logo em seguida tem uma lógica if para apresentar qual cor que o sensor detectou, no nosso caso usamos o Serial.println() para imprimir na tela o valor detectado,  mas você poderia ligar o LED RGB na cor que foi detectada, ou usar qualquer outra lógica a partir da cor obtida, como por exemplo, separar itens em esteira de produção, baseado na cor que foi encontrada, que será o nosso próximo projeto aqui no blog, fiquem ligados!

Abaixo segue o código da função color:

void color(){
    //Lê o valor das cores
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
    //count OUT, pRed, RED
  red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  digitalWrite(s3, HIGH);
    //count OUT, pBLUE, BLUE
  blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  digitalWrite(s2, HIGH);
    //count OUT, pGreen, GREEN
  green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
}

 A instrução principal para ler o valor das cores é usando a interrupção pulseIn com o pino 10 do Arduino declarado como “out”, e para isso precisa-se ligar/desligar os leds s2 e s3 para gerar a interrupção por borda de subida através da leitura digitalRead(out), então basicamente seria assim:

  1. Desliga os leds s2 e s3, lê o pino out;
  2. Mantém desligado o led s2 e liga o s3, lê o pino out;
  3. Liga o pino s2, lê o pino out.

De acordo com o valor lido pelo pino out, será o reflexo da cor que está a frente do sensor, e esses valores serão enviados de volta ao void loop() conforme já estudamos.

Desenvolvendo o código com a biblioteca MD_TCS230

O código completo usando a biblioteca ficou assim:

#include <MD_TCS230.h>
#include <FreqCount.h>

// Definição dos pinos
#define  S2_OUT  12
#define  S3_OUT  13
#define  OE_OUT   2    // LOW = ATIVADO 

MD_TCS230  CS(S2_OUT, S3_OUT, OE_OUT);

void setup() {
  Serial.begin(57600);
  Serial.println("[TCS230 Exemplo de BLOQUEIO Simples]");
  Serial.println("Mova o sensor para uma cor diferente para ver o valor");
  Serial.println("Nota: Esses valores estão sendo lidos sem calibração do sensor");
  Serial.println("e provavelmente estão longe da realidade");

  CS.begin();
  CS.setEnable(true);
  CS.setFilter(TCS230_RGB_X);
  CS.setFrequency(TCS230_FREQ_HI);
  CS.setSampling(10);
}

void readSensor(){
	static  bool  waiting; 
  if (!waiting){
    CS.read(); waiting = true;
  }
  else{
    if (CS.available()){
      colorData  rgb;     
      CS.getRGB(&rgb);
      Serial.print("RGB ["); 
      Serial.print(rgb.value[TCS230_RGB_R]); Serial.print(",");
      Serial.print(rgb.value[TCS230_RGB_G]); Serial.print(",");
      Serial.print(rgb.value[TCS230_RGB_B]); Serial.println("]");      
      waiting = false;
    }
  }
}

void loop() {
  readSensor();
}

Mergulhando no código usando a biblioteca

Agora é hora de identificar cores com Arduino e o sensor TCS320 usando a biblioteca! E ai o negócio é mais estiloso, primeiro baixe a biblioteca MD_TCS230.h neste link, ela tem uma dependência de outra biblioteca que é a FreqCount.h, porém se você baixar exatamente a biblioteca que estamos disponibilizando ela já virá com a outra junta, caso você tente baixar em outro site, pode ser que precise baixar as duas de forma independente, mais trabalho não acha?

Agora a coisa já começa a ficar mais fácil, você só precisa declarar 03 pinos, o S2, S3 e out e instanciar a classe MD_TCS230 com o objeto CS passando como parâmetros as variáveis criadas referentes aos pinos do Arduino, como pode ser visto no treco abaixo:

#include <MD_TCS230.h>
#include <FreqCount.h>

// Definição dos pinos
#define  S2_OUT  12
#define  S3_OUT  13
#define  OE_OUT   2    // LOW = ATIVADO 

MD_TCS230  CS(S2_OUT, S3_OUT, OE_OUT);

No setup você precisa fazer basicamente 05 instruções, inicializar a biblioteca, habilitar a leitura do sensor, setar o filtro do sensor, setar a frequência de operação e em seguida a quantidade de amostragem.

void setup() {
  Serial.begin(57600);
  Serial.println("[TCS230 Exemplo de BLOQUEIO Simples]");
  Serial.println("Mova o sensor para uma cor diferente para ver o valor");
  Serial.println("Nota: Esses valores estão sendo lidos sem calibração do sensor");
  Serial.println("e provavelmente estão longe da realidade");

  CS.begin();
  CS.setEnable(true);
  CS.setFilter(TCS230_RGB_X);
  CS.setFrequency(TCS230_FREQ_HI);
  CS.setSampling(10);
}

Agora vem a função readSensor. O available(linha 31 do código completo) já é uma função conhecida nossa, onde se houver um valor válido entra na condicional e obtém a leitura das 03 cores, RGB, através do objeto CS e atribuindo a variável rgb que será outro objeto.

Nas linhas 35, 36 e 37 (do código completo), se separa as cores RGB, onde o objeto “rgb” através da função “value()” apresenta o valor das cores vermelha, verde e azul respectivamente.

void readSensor(){
	static  bool  waiting; 
  if (!waiting){
    CS.read(); waiting = true;
  }
  else{
    if (CS.available()){
      colorData  rgb;     
      CS.getRGB(&rgb);
      Serial.print("RGB ["); 
      Serial.print(rgb.value[TCS230_RGB_R]); Serial.print(",");
      Serial.print(rgb.value[TCS230_RGB_G]); Serial.print(",");
      Serial.print(rgb.value[TCS230_RGB_B]); Serial.println("]");      
      waiting = false;
    }
  }
}

E por fim chamamos a função readSensor no loop:

void loop() {
  readSensor();
}

Simples não é? Esse é o poder da biblioteca, e se você não sabe, já ensinamos aqui a fazer uma biblioteca do zero e depois trabalhamos com outra biblioteca própria para um projeto de um carro com 04 motores <link>, ou seja, nosso blog é muito rico e os projetos sempre se interligam, se você desbravar por nossos posts terá praticamente um curso completo de robótica inclusive com possibilidade de montar um projeto que poderia ser aprovado em vários eventos. 

Se não acredita, confere lá.

Conclusão

Como foi visto ao longo desse tutorial, identificar cores com Arduino e o sensor TCS320 não é algo difícil, podemos fazer usando a biblioteca ou podemos fazer de modo mais “manual”, mas não é algo complexo, e mesmo os iniciantes vão conseguir fazer este exemplo se grandes dificuldades!

No próximo post vamos integrar esse sensor no braço robótico, que irá analisar a cor de um objeto e tomará a decisão de pegar ou não objeto baseado na cor! Então não perca o próximo projeto, até lá.

Sobre Sandro Mesquita 20 artigos
Prof. Sandro Mesquita, Msc. Eng de Software, CREA - 44680 .

Seja o primeiro a comentar

Deixe uma resposta

O seu endereço de email não será publicado.


*