20 fevereiro 2014

NewTone - Alternativa à biblioteca tone do Arduino

Um leitor do site me escreveu , dizendo que ao tentar utilizar a biblioteca IRremote junto com o comando Tone do Arduino, o programa não compilava, apresentando a seguinte mensagem :


.....\arduino\cores\arduino/Tone.cpp:535: multiple definition of  `__vector_7'


Já havia acontecido comigo em algumas oportunidades, especialmente ao tentar utilizar o comando Tone junto com a biblioteca NewPing, usada para controlar múltiplos sensores ultrasônicos HC-SR04 (usei a NewPing no post Controle de estacionamento com o sensor HC-SR04).

A biblioteca tone do Arduino realmente apresenta alguns problemas de compatibilidade com outras biblioteca quando estas utilizam a mesma interrupção/timer.

Felizmente encontrei uma biblioteca bem simples, a NewTone, que pelo menos nos meus testes, não apresentou nenhum conflito. Inclusive utilizei os programas que eu já havia criado no post Sons no Arduino para me certificar que não seriam necessárias grandes alterações no código.

E realmente a utilização é simples. As únicas alterações no programa são o carregamento da biblioteca NewTone no início, e a substituição dos comandos Tone por NewTone, e noTone por noNewTone. E só.

 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
// Programa : Som no Arduino - Sirene - Teste biblioteca NewTone
// Autor : Arduino e Cia  
   
#include <NewTone.h>  
   
#define tempo 10  
int frequencia = 0;  
int Pinofalante = 10;  
   
void setup()  
{  
  pinMode(Pinofalante,OUTPUT); //Pino do buzzer  
}  

void loop()  
{  
  for (frequencia = 150; frequencia < 1800; frequencia += 1) 
  {  
    NewTone(Pinofalante, frequencia, tempo);   
    delay(1);  
  }  
  for (frequencia = 1800; frequencia > 150; frequencia -= 1) 
  {  
    NewTone(Pinofalante, frequencia, tempo);   
    delay(1);  
  }  
}  

Ao montar o circuito, ligue o buzzer na porta 10 do Arduino, e não se esqueça de ligar em série um resistor de pelo menos 100 ohms :

arduino buzzer tone newtone


Se você está enfrentando problemas de conflito com a biblioteca tone padrão do Arduino, esta pode ser a solução.

13 fevereiro 2014

Sensor de reconhecimento de cor TCS230 / TCS3200

O artigo de hoje fala sobre como utilizar o Arduino para montar um sistema de reconhecimento de cores usando o módulo TCS230 / TCS3200.

Modulo reconhecimento de cor TCS230 - TCS3200

Esse módulo usa o sensor TCS230 (datasheet), que é composto por 64 fotodiodos. Desses 64 fotodiodos, 16 tem filtros para a cor vermelha, 16 para a cor verde, 16 para a cor azul e 16 não tem filtro algum.

Distribuídos uniformemente sobre o sensor, esses sensores captam a luminosidade, filtrando as cores, e geram na saída um sinal de onda quadrada com as informações sobre a intensidade das cores vermelho (R = Red), verde (G = Green) e Azul (B = Blue).

Como no módulo mostrado acima, o sensor TCS230 geralmente vem montado em conjunto com quatro leds brancos para iluminação, e oito pinos para conexão.

O módulo aceita alimentação de 3 à 5 volts e são utilizados 5 pinos para conexão ao Arduino : os pinos de controle S0, S1, S2, S3, e o pino OUT, que é o responsável pelo envio das informações.

O pino OE (Output Enable, ou saída habilitada/ativada) deve ser ligado ao GND, já que o módulo vai enviar informações continuamente ao Arduino.

Circuito TCS230 - TCS3200 Arduino Uno

No circuito adicionei 3 leds nas cores correspondentes, para que acendam quando determinada cor for reconhecida pelo sensor. Apesar de trabalhar nesse experimento apenas com as 3 cores primárias, nada impede que outras combinações sejam usadas no programa, de acordo com os níveis do sinal RGB.

No programa, os pinos S0 e S1 são colocados em nível alto e então são alternados os estados dos pinos S2 e S3, que determinam qual fotodiodo será ativado. Veja na tabela abaixo as combinações que determinam o tipo de frequência de saída e também o padrão de ativação dos fotodiodos :

Tabela de ativação TCS230 / TCS3200


 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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Programa : Detector de cores usando modulo TCS230  
// Alteracoes e comentarios : Arduino e Cia  
//  
// Baseado no programa original de Martin Mason  
   
//Pinos de conexao do modulo TCS230  
const int s0 = 8;  
const int s1 = 9;  
const int s2 = 12;  
const int s3 = 11;  
const int out = 10;   
   
//Pinos dos leds  
int pinoledverm = 2;  
int pinoledverd = 3;  
int pinoledazul = 4;  
    
//Variaveis que armazenam o valor das cores  
int red = 0;  
int green = 0;  
int blue = 0;  
    
void setup()   
{  
  pinMode(s0, OUTPUT);  
  pinMode(s1, OUTPUT);  
  pinMode(s2, OUTPUT);  
  pinMode(s3, OUTPUT);  
  pinMode(out, INPUT);  
  pinMode(pinoledverm, OUTPUT);  
  pinMode(pinoledverd, OUTPUT);  
  pinMode(pinoledazul, OUTPUT);  
  Serial.begin(9600);  
  digitalWrite(s0, HIGH);  
  digitalWrite(s1, LOW);  
}  
    
void loop() 
{  
  color(); //Chama a rotina que le as cores  
  //Mostra no serial monitor os valores detectados  
  Serial.print("Vermelho :");  
  Serial.print(red, DEC);  
  Serial.print(" Verde : ");  
  Serial.print(green, DEC);  
  Serial.print(" Azul : ");  
  Serial.print(blue, DEC);  
  Serial.println();  

  //Verifica se a cor vermelha foi detectada  
  if (red < blue && red < green && red < 100)  
  {  
   Serial.println("Vermelho");  
   digitalWrite(pinoledverm, HIGH); //Acende o led vermelho  
   digitalWrite(pinoledverd, LOW);  
   digitalWrite(pinoledazul, LOW);  
  }  

  //Verifica se a cor azul foi detectada  
  else if (blue < red && blue < green)   
  {  
   Serial.println("Azul");  
   digitalWrite(pinoledverm, LOW);  
   digitalWrite(pinoledverd, LOW);  
   digitalWrite(pinoledazul, HIGH); //Acende o led azul  
  }  

  //Verifica se a cor verde foi detectada  
  else if (green < red && green < blue)  
  {  
   Serial.println("Verde");  
   digitalWrite(pinoledverm, LOW);  
   digitalWrite(pinoledverd, HIGH); //Acende o led verde  
   digitalWrite(pinoledazul, LOW);  
  }  
  Serial.println();  

  //Aguarda 2 segundos, apaga os leds e reinicia o processo  
  delay(2000);   
  digitalWrite(pinoledverm, LOW);  
  digitalWrite(pinoledverd, LOW);  
  digitalWrite(pinoledazul, LOW);  
 }  
    
void color()  
{  
  //Rotina que le 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);  
}

Carregue o programa e aproxime objetos de diferentes cores ao sensor. O led correspondente irá acender, e também é gerada uma saída como essa no serial monitor, onde você pode ver exatamente os níveis de sinal das cores detectadas :

Circuito TCS230 - Saida serial monitor



Em breve um vídeo demonstrando a utilização deste programa. Até lá !

Atualizado : Veja neste link o vídeo de demonstração deste experimento.