1. Introdução
Esse projeto visa construir um detector de cores usando componentes baratos e fáceis de encontrar e uma placa Arduino. Eu usarei o Mega nesse projeto, porque é o que tenho disponível, mas o Uno já atende perfeitamente.
2. Teoria
Talvez a idéia de detectar cores com um LDR possa parecer estranha a uma primeira vista, mas veremos que é algo possível e relativamente fácil. Ao final, teremos um detector com um bom nível de precisão e a um preço bastante acessível.
2.1 Foto-resistores
Um foto-resistor - também chamado de LDR (Light Dependent Resistor) - é um tipo de resistor que varia sua resistência de acordo com a quantidade de luz que chega a ele. A resistência é inversamente proporcional a quantidade de luz, ou seja, quanto mais luz, menor a resistência elétrica. Os foto-resistores são muito usados em células fotoelétricas para a automatização de postes de iluminação pública e luzes de emergência. Abaixo a imagem real de um LDR e sua representação simbólica.2.2 O Sistema de Cores RGB
RGB é a abreviatura de Red/Green/Blue. Esse sistema se baseia no fato que todas as cores podem ser formadas a partir dessas três cores básicas e é usado em inúmeros dispositivos atuais como monitores, televisores, projetores multimídia, máquinas fotográficas etc.Sistema de Cores RGB |
2.3 Um pouco de Ótica
Sabemos que o que forma as cores para a nossa percepção é a reflexão de certas ondas luminosas. Um objeto verde reflete as frequências de onda correspondentes ao verde. Os tons de vermelho também tem sua faixa de frequência específica, bem como o azul. A faixa visível varia da frequência 400THz (tons vermelhos) até 790THz (tons violeta).A idéia básica do tipo de detector que buscamos construir é associar a emissão de luz no sistema RGB, feita pelos LED's e a reflexão da mesma por amostras de cor. Por exemplo, se acionarmos um LED vermelho próximo a uma amostra vermelha, a quantidade de luz refletida será razoavelmente grande. Se a amostra for azul ou verde, a luz refletida será bem menor. Se colocarmos um LDR para "sentir" a luz refletida, poderemos detectar quando a amostra vermelha é testada.
Por fim, se conseguirmos associar três LED's, sendo um vermelho, um verde e um azul, poderemos detectar qualquer das cores básicas do RGB. E se armazenarmos cada valor RGB, poderemos até replicar a exata cor da amostra, bastando reunir os valores detectados de vermelho, verde e azul!
3. Montagem do Detector
Vamos partir agora para a construçao do sistema em uma protoboard ou PCB.
3.1 Componentes Necessários
- 1 protoboard (ou se preferir soldar, uma PCB)
- 1 sensor LDR
- 3 LED's: Um azul, um verde e um vermelho (preferencialmente pode-se usar um único LED RGB)
- 1 pushbutton
- 1 buzzer
- 4 resistores de 350 Ohms
- 1 resistor de 10KOhms
3.2 Esquema de Montagem
Usei o Fritzing para desenhar o modelo abaixo. Trata-se de um excelente software livre. Pode ser baixado gratuitamente em http://fritzing.org.Recomendamos fortemente que seja montada uma pequena câmara escura que proteja o detector (o conjunto dos três LED's + LDR) das emissões de luz do ambiente externo. Se não for usada essa câmara, haverá muita interferência de luz externa. Abaixo o sistema real já montado. Note a câmara escura com os três LED's e o LDR dentro.
4. Codificação
O código a seguir não foi totalmente criado por mim. Encontrei diversas referências e trechos na Internet e montei o meu fazendo as adaptações que achei pertinentes e que melhor serviam a mim. Na sessão de referências há links para os sites de onde me baseei.Agora abra a IDE do Arduino e digite isso.
/* RGB SENSOR */ const int LDR = 0; // ldr sensor on analog pin 0 const int redLed = 2; const int greenLed = 3; const int blueLed = 4; int ledArray[] = {redLed, greenLed, blueLed}; const int buzzer = 8; int buzzTone=200; const int button = 7; int buttonState = 0; float colorArray[] = {0,0,0}; float whiteArray[] = {0,0,0}; float blackArray[] = {0,0,0}; //int avgRead; int ldrvalue = 0; // Values for detected colors int redval = 0; int greenval = 0; int blueval = 0; boolean balanced = false; void setup () { Serial.begin (9600); pinMode (redLed, OUTPUT); pinMode (greenLed, OUTPUT); pinMode (blueLed, OUTPUT); pinMode (button, INPUT); pinMode (buzzer, OUTPUT); Serial.println ("Press button to start"); beepBuzzer (1); } void loop () { waitButton(); //buttonState = digitalRead (button); //if (buttonState == HIGH) { if (!balanced) { blinkLeds (3); Serial.println ("Performing Balance..."); rgbBalance(); } else { rgbSense(); printColors(); beepColor(); } } void rgbBalance() { // White Balance: operador deve colocar amostra branca sobre o sensor. Serial.println ("White balance [press button to start] ..."); waitButton(); delay(500); // Le os valores red/green/blue para a amostra branca. Serial.print ("White Array: ["); for (int i=0;i<3;i++) { digitalWrite (ledArray[i], HIGH); delay(100); whiteArray[i] = getAvgRead(5); digitalWrite (ledArray[i], LOW); Serial.print (whiteArray[i]); delay(100); } Serial.println ("] OK"); // Black Balance: operador deve colocar amostra preta sobre o sensor. Serial.println ("Black balance [press button to start] ..."); waitButton(); delay(500); // Espera oito segundoa para usuario posicionar a amostra negra. // Le os valores red/green/blue para a amostra negra. Serial.print ("Black Array: ["); for (int i=0;i<3;i++) { digitalWrite (ledArray[i], HIGH); delay(100); blackArray[i] = getAvgRead(5); digitalWrite (ledArray[i], LOW); Serial.print (blackArray[i]); delay(100); } Serial.println ("] OK"); balanced = true; delay(2000); } void rgbSense () { float greyDiff=0; for (int i=0; i<3;i++) { digitalWrite (ledArray[i], HIGH); delay(100); colorArray[i] = getAvgRead(5); greyDiff = whiteArray[i] - blackArray[i]; colorArray[i] = (colorArray[i] - blackArray[i]) / greyDiff*255; digitalWrite (ledArray[i], LOW); delay(100); } } int getAvgRead (int times) { int value=0; int summ=0; int avg=0; for (int i=0;i<times;i++) { value = analogRead(LDR); summ = value + summ; delay(10); } avg = summ/times; return avg; } void blinkLeds (int times) { for (int i=0;i<times;i++) { digitalWrite (redLed, HIGH); digitalWrite (greenLed, HIGH); digitalWrite (blueLed, HIGH); delay(500); digitalWrite (redLed, LOW); digitalWrite (greenLed, LOW); digitalWrite (blueLed, LOW); delay(500); } } void beepBuzzer (int times) { for (int i=0;i<times;i++) { tone (buzzer, 2000); delay(100); noTone (buzzer); delay(100); } } void printColors () { Serial.print ("R: "); Serial.println(int(colorArray[0])); Serial.print("G = "); Serial.println(int(colorArray[1])); Serial.print("B = "); Serial.println(int(colorArray[2])); Serial.println(); } void beepColor ( ) { // Red: 1 beep; Green: 2 beeps; Blue: 3 beeps int beeps=0; int color; if (colorArray[0]>colorArray[1]) { color = colorArray[0]; beeps=1; } else { color = colorArray[1]; beeps=2; } if (color<colorArray[2]) { beeps=3; } beepBuzzer(beeps); } void waitButton () { while (true) { buttonState = digitalRead (button); if (buttonState == HIGH) { beepBuzzer(1); break; } } } |
5. Operação
Para que o sistema funcione adequadamente é necessário realizar o balanço inicial de luz para amostras brancas e pretas. Será necessário usar a interface serial da IDE do Arduino para se familiarizar com o funcionamento. Através da interface serial, o sistema dará as instruções básicas de operação, que consistem no que está descrito abaixo.Após ligar, o sistema solicitará que o operador coloque a amostra branca sobre o detector (o conjunto dos LED's + o LDR) e pressione o botao. Após isso ele deverá colocar a amostra preta sobre o detector e pressionar novamente o boato. Nesse momento o balanceamento foi feito e o sistema está pronto para uso.
Coloque qualquer amostra de cor sobre o detector e pressione o botao. O sistema lerá a a cor predominante (vermelho, verde ou azul) da amostra e emitirá bips da seguinte forma:
- 1 bip: vermelho
- 2 bips: verde
- 3 bips: azul
Nos testes que fiz, o sistema se mostrou bem eficiente. Muitas melhorias podem ainda ser feitas. Pode-se trocar o conjunto de três LED's por um único LED RGB. Outra melhoria é colocar ainda outro LED RGB e tentar "imitar" a cor lida.
Caso você faça melhorias nesse sistema, peço que mantenha vivo o espírito do software/hardware livre e compartilhe o que foi feito com o público em geral.
6. Referências
http://www.instructables.com/id/Using-an-RGB-LED-to-Detect-Colours/?ALLSTEPShttp://www.georgegardner.info/arduino/photoresistor-color-sensing-with-the-arduino.html