This is a simple color sensor using Atmega16 MCU and can sense Red ,Green and Blue color.
How it works:
the sensor consist from LDR sensor and RGB LED ,so when the object putted on the sensor the light that emitting from RGB LED will reflected from the object to LDR sensor and read it by ADC of ATMEGA16 as below sequence:
1-Turn on Blue in RGB LED and wait.
2-Read ADC and store it in the registry as blue.
3-Turn on Green in RGB LED and wait.
4-Read ADC and store it in the registry as green .
5-Turn on Red in RGB LED and wait.
6-Read ADC and store it in the registry as red.
7- if red >green>blue turn on Red LED display.
if green > red > blue turn on Green LED display.
if blue > red >green turn on Blue Led display.
Calibration :
The RGB LED emitting red ,blue and green in different intensity so to equalize them , variable resistors should be used with below steps :
1-put a white object on the sensor.
2-turn on Blue in RGB LED and read the voltage across the LDR sensor using voltmeter.
3-turn on Green in RGB LED and read the voltage across the LDR sensor using voltmeter.
4-turn on Red in RGB LED and read the voltage across the LDR sensor using voltmeter.
5-adjust the variable resistances to make all the voltage equalized when white object putted on the sensor.
Software (AVR studio 4):
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
void InitADC() //Initiate ADC
{
ADMUX=(1<<REFS0); // For Aref=AVcc;
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Rrescalar div factor =128
}
uint16_t ReadADC(uint8_t ch)
{
ch=ch&0b00000111;
ADMUX|=ch;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));
ADCSRA|=(1<<ADIF);
return(ADC);
}
void Wait()
{
uint8_t i;
for(i=0;i<1;i++)
_delay_loop_2(0);
}
void main()
{
DDRB =0xFF; // Define output for RGB LED
DDRD=0xFF; // Define output for display LEDs
uint16_t red;
uint16_t green ;
uint16_t blue ;
//Initialize ADC
InitADC();
while(1)
{
PORTD = 0b11111111; //turn off all the display LEDs
PORTB = 0b11111110; // Turn on Blue RGB
_delay_ms(2000); // wait 2s
blue=ReadADC(0); // Read Analog value and store it in blue
PORTB = 0b11111101; //Turn on Green RGB ;
_delay_ms(2000); //wait 2s
green = ReadADC(0); //Read Analog value and store it in green
PORTB = 0b011111011; //Red RGB;
_delay_ms(2000); //wait 2s
red = ReadADC(0); //Read Analog value and store it in red
if ((red > green) & (red > blue)) {PORTD =0b11111110; _delay_ms(4000);PORTD =0b11111111;} //Red Display
if ((green > red) & (green > blue)) {PORTD =0b11111011; _delay_ms(4000);PORTD =0b11111111;} //Green Display
if ((blue > green) & (blue > red)) {PORTD =0b11111101; _delay_ms(4000);PORTD =0b11111111;} //Blue Display
}
}