Get Adobe Flash player
FacebookTwitterGoogle+
English Arabic French German Italian Portuguese Russian Spanish

Did you know?

Currents of approximately 0.2 A are potentially fatal, because they can make the heart fibrillate, or beat in an uncontrolled manner
 

Help us stay online:

small donate

 

Color sensor AVR ATmega8 RGB HSVIn this project we used ADJD E622 QR999 light to voltage converting sensor to detect color of surface in front of our PCB board. This kind of sensors are often used in robotics and where color detection is needed. Complete source code and schematic with PCB design is provided below.

More about ADJD E622 QR999 light to voltage converting sensor can be read in this article.

 

 

 


Hardware    
Hardware consists of two simple PCBs. First one is only adapter for sensor since it is small SMD package. This PCB is displayed on picture below

ADJD E622 QR999 color sensor Electronics-Base comADJD E622 QR999 color sensorPCB Electronics-Base com

Main PCB with AVR Atmega8 microcontroller is very simple.You can see schematic on picture below.
ADJD E622 QR999 color sensor Schematic AVR Electronics-Base com

Atmega8 is used to readout sensor output via ADC input pins. Four bright light LEDs are used to provide enough light for color readout so it is not dependable on ambient light. Bright light LEDs are optional and can be switched off with jumper JP1. Three digital outputs are used to indicate detected color by turning on RED  GREEN or BLUE LED conected to it. Same pins can also be used to trigger other modules since they are TTL digital output pins. 6MHz oscillator must be used to get correct baud rate or you can simply adjust baud rate settings for different clock frequency. For debugging purposes UART port is connected to three pin header P2. Complete Altium Project containing schematic and PCB can be downloaded here for sensor board and for microcontroller ATmega8 AVR board.

Firmware

Complete code is listed below:

/*********************************************
This program was produced by the
CodeWizardAVR V1.24.0 Standard
Automatic Program Generator
Project :  Color detection with ADJD E622 QR999 light to voltage converting sensor 
Author  : www.Electronics-Base.com                         
                               
Comments: For more details, complete code, comments, schematic, PCB files and support 
        visit Complete projects section of www.Electronics-Base.com     
Chip type           : ATmega8
Program type        : Application
Clock frequency     : 6.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*********************************************/
#include <mega8.h>
// Standard Input/Output functions
#include <stdio.h>
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
#define GSRED2    PORTB.3
#define GSRED1    PORTB.2
#define GSRED0    PORTB.1
#define GSGRN2  PORTB.5
#define GSGRN1    PORTB.4
#define GSGRN0    PORTC.3
#define GSBLUE2    PORTC.4
#define GSBLUE1    PORTC.5
#define GSBLUE0    PORTB.0
#define LEDRED    PORTD.5
#define LEDBLUE    PORTD.7
#define LEDGREEN    PORTD.6
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
    long RED,GREEN,BLUE;
    long MIN,MAX,H,S,V;
    int i;
// Input/Output Ports initialization
// Port B initialization
// Func0=Out Func1=Out Func2=Out Func3=Out Func4=Out Func5=Out Func6=In Func7=In 
// State0=0 State1=0 State2=0 State3=0 State4=0 State5=0 State6=T State7=T 
PORTB=0x00;
DDRB=0x3F;
// Port C initialization
// Func0=In Func1=In Func2=In Func3=Out Func4=Out Func5=Out Func6=In 
// State0=T State1=T State2=T State3=0 State4=0 State5=0 State6=T 
PORTC=0x00;
DDRC=0x38;
// Port D initialization
// Func0=In Func1=Out Func2=In Func3=In Func4=In Func5=Out Func6=Out Func7=Out 
// State0=T State1=T State2=T State3=T State4=T State5=1 State6=1 State7=1 
PORTD=0xE2;
DDRD=0xE0;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x26;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 187.500 kHz
// ADC Voltage Reference: AREF pin
// ADC High Speed Mode: Off
// ADC Auto Trigger Source: None
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x85;
SFIOR&=0xEF;
//RED:    ADC0
//GREEN:ADC1
//BLUE: ADC2 
    
//Gain selection:
GSRED2 = GSRED1 = GSRED0 = 1;
GSGRN2 = GSGRN1 = GSGRN0 = 1;
GSBLUE2 = GSBLUE1 = GSBLUE0 = 1;
    while (1)
    {
        // Place your code here  
        
        //digital filtering of COLOR components:    
        RED=GREEN=BLUE=0;
        for (i=0; i<128; i++)
        {
            RED+=    read_adc(0);
            GREEN+=    read_adc(1);
            BLUE+=    read_adc(2);
        }
        RED/=128;
        GREEN/=128;
        BLUE/=128;
                                      
        //****************************
        //HSV SPACE TRANSFORMATION
        //****************************
        
        //calculating MIN i MAX
        MAX=RED;
        if (GREEN>MAX)
            MAX=GREEN;
        if (BLUE>MAX)
            MAX=BLUE;
        MIN=RED;
        if (GREEN<MIN)
            MIN=GREEN;
        if (BLUE<MIN)
            MIN=BLUE;
        //calculating H parameter:
        if (MAX!=MIN)
        {
            if (MAX==RED)
                    H=(60*(GREEN-BLUE))/(MIN-MAX);
            if (MAX==GREEN)
                    H=(60*(BLUE-RED))/(MIN-MAX)+120;
            if (MAX==BLUE)
                    H=(60*(RED-GREEN))/(MIN-MAX)+240;
            if (H<0)
                H+=360;
        } 
        //calculating S parameter:
        if (MAX==0)
            S=0;
        else
            S=100-(100*MIN)/MAX;
        //calculating V parameter:
        V=RED+GREEN+BLUE;
      
        printf(" RED value: %d\n ",RED);
        printf(" GREEN value: %d\n ",GREEN);
        printf(" BLUE value: %d\n\n ",BLUE);
        printf(" MAX: %d\n ",MAX);
        printf(" MIN: %d\n\n ",MIN);
        printf(" H parameter: %d\n ",H);
        printf(" S parameter: %d\n ",S);
        printf(" V parameter: %d\n\n ",V);
        
        printf(" Detected color is: ");
        if ((H>330) || (H<=30)) 
            {
            if ((V>100) && (S>50)) 
                {
                LEDRED=0;
                LEDBLUE=1;
                LEDGREEN=1;
                printf(" RED ");
                }
            }
        else if ((H>90) && (H<=150))
            {
            if ((V>100) && (S>30)) 
                {
                LEDRED=1;
                LEDBLUE=1;
                LEDGREEN=0; 
                printf(" GREEN ");
                }
            }
        else if ((H>180) && (H<=300))  
           {
            if ((V>100) && (S>30))   
                {
                LEDRED=1;
                LEDBLUE=0;
                LEDGREEN=1;
                printf(" BLUE ");     
                }
             }
        else
            {
            LEDRED=1;
            LEDBLUE=1;
            LEDGREEN=1;
            }   
        putchar(13);
    }
}

 

Code is very simple. RGB components are sampled on ADV of Atmega8. Some digital filtering is done by calculating avarage value of 128 measurements. After that standard HSV transformation is done. HSV ncolor space is much easier to use for color detection. More about this and generaly color sensors can be read in Color sensor theory for dummies article.
After calculating Hue, Saturation and Value gained data is printer to serial port as well as detected color and starting RGB values from sensor. Complete Codevision C project for Atmega8 color sensor readout can be downloaded from this link. If you have any doubts feel free to use our support forum.

Testing

For testing we have used three objects with different colors displayed on picture below.
Color sensor AVR ATmega8 RGB HSV objects

You can see  this code in action on video below:

When objects are changed AVR Atmega8 sends all relevant measured and calculated parameters on UART. Here is print screen of this data.

Color sensor www.electronics-base.com uart send

You can play further to detect other colors than red, green and blue.

 Special thanks to Milan Lukić for his contribution on this article.