Introduction: Color Sensor

About: Electrical Engineer
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
}
}