Language

english vietnamese

Nhận dạng màu sắc với cảm biến TCS3200 - Atmega32
Color Detector using TCS3200 based on Microcontroller - Atmega32

2
       In this project, Atmega32 microcontroller will be used to program an application – Color Detector. The color sensor will collect the data of the color we want to detect. The microcontroller will use the data to process, analyze the specific information about the color, it will decide what the color is, and the color name will be display on a 128x64 graphic screen (Graphic LCD - GLCD). If the color which is detected, is black, 1 KHz will be created and send this signal to a buzzer. One button will be program to turn the buzzer off.
       In order to obtain the goal of the project, the extension board of color sensor TCS3200 will be designed and used to collect the data about the color, converts it to frequency. The microcontroller will count the frequency; determine what color is, and display information on GLCD.


All code is written in AVRStudio with WinAVR compiler

I) Color Sensor - TCS3200

     
 The TCS3200 is programmable color light-to-frequency converter that combine configurable silicon photodiodes and a current-to-frequency converter on a single monolithic CMOS integrated circuit. The output is a square wave (50% duty cycle) with frequency directly proportional to light intensity [2].
Full-scale output frequency can be scaled by one of three presets in the table  below:
Table 1:
S0
S1
Output Scaling (f0)
0
0
Power down
0
1
2%
1
0
20%
1
1
100%
     The Output enable (OE) places the output in the high-impedance state for multiple-unit sharing of a microcontroller input line. Pin VDD connects with the power and GND connects with ground.
In the TCS3200, the light-to-frequency converters read an 8x8 array of photodiode. Sixteen photodiodes have blue filters, 16 photodiodes have green filters, and 16 photodiodes have red filters. All photodiodes of the same color are connected in parallel. Pin S2 and S3 are used to select which group of photodiodes (red, blue, green, clear) is active. See the table 2 below for more details.
Table 2:
S2
S3
Photodiode Type
0
0
Red
0
1
Blue
1
0
Clear (no filter)
1
1
Green

Module Design:
      The TCS3200 sensor module is designed with SMD TCS3200 IC, four white LEDs, LED control circuit and a few components. The white LEDs throw light on the object that is placed in front of the sensor. The complete schematic shows in figure:
         
You can download complete schematic and layout at the of my post (Orcard)

     Four white LEDs in the module is active with logic 1. To active the output of TCS3200, the pin !OE needs to be active with logic 0. In this project, 2% scale-output frequency is chosen because the microcontroller has fast crystal (8MHz), thus pin S0 is low and S1 is high (see the table 1)

Measurement technique:
     The half period measurement is used to obtain the frequency from output pin of TCS3200.  The frequency of each Green, Blue and Red will be measured to obtain the RGB value.



        Because the output signal from TCS3200 is 50%-duty cycle square wave, so we only need to measure the time of half period which means from the falling edge to the first next rising edge.
For the best measurement result, the process of measurement for each color (RGB) shows in the figure II.4. Firstly, we need to check the signal state, if level of signal input frequency is low, we will wait for the rising edge (1):

if(!(TCS_OUT_PORT & (1<<TCS_OUT_POS)))
       {
              while(!(TCS_OUT_PORT & (1<<TCS_OUT_POS)));      //Wait for rising edge    
       }

Secondly, we will wait from the rising edge to the next falling edge, until falling edge, timer1 will be initialized and begin the counter1 to count the time of half pulse (2).

while(TCS_OUT_PORT & (1<<TCS_OUT_POS));  //Wait for falling edge
TCNT1=0x0000;        //Reset Counter
TCCR1B=(1<<CS10);    //Prescaller = F_CPU/1 (Start Counting)
//Stop Timer
TCCR1B=0x00;
return ((float)F_CPU/TCNT1);

Finally, ultil the next rising edge reaches (3), we will obtain the value of couter1, from this result, we can calculate the time of pulse or half period time by the equation:

Thus the rate of twice output frequency will be gathered.
RGB Analyze:
       RGB color space or RGB color system, constructs all the colors from the combination of the Red, Green and Blue colors.
     The red, green and blue use 8 bits each, which have integer values from 0 to 255. This makes 256*256*256=16777216 possible colors.
        Each pixel in the LCD monitor displays colors this way, by combination of red, green and blue LEDs (light emitting diodes). When the red pixel is set to 0, the LED is turned off. When the red pixel is set to 255, the LED is turned fully on. Any value between them sets the LED to partial light emission.
In this project, I will determine only seven colors: black, white, green, yellow, red, blue and purple. The table below is some decimal codes RGB of 7 colors.
Color
HTML/CCS Name
Decimal Code R,G,B

Black
0,0,0

White
255,255,255

Green
0,128,0

Blue
0,0,255

Red
255,0,0

Yellow
255,255,0

Purple
128,0,128
        The color sensor TCS3200 converts the color into frequency.  We will use TCS3200 module to collect the frequency obtained with Green, Red and Blue filter of the object by enabling corresponding filter actives.         Three function to get RGB value in my program
unsigned int Measure_R();         //measure frequency with red filter
unsigned int Measure_G();         //measure frequency with green filter
unsigned int Measure_B();         //measure frequency with blue filter
unsigned int Measure_C();         //measure frequency without filter
        Measure_C() function is used to detect the object in range of measure or not, if the frequency obtained is smaller than 2 KHz than “no object” message will be displayed on the graphic LCD.
c = Measure_C();
if (c>2000){
…      //main process in here
}
else{
       …
       GLCD_Print78(0,10,"No Object");
}
       To determine what color of object is, we need to scale the value of RGB. The function to find the smallest value is applied: (_r, _g, _b is the RGB value which have measured before)
if(_r<_b){   
       if(_r<_g)
              wb=_r;
       else
              wb=_g;
}
else{
       if(_b<_g)
              wb=_b;
       else
              wb=_g;
}     
wb=wb/10;     //decrease the smallest value with factor of 10
r=_r/wb;      //r, g, b are the value which have scaled
g=_g/wb;
b=_b/wb;

         From the RGB has scaled, the decimal code RGB table and real experiment, I have assigned the range value for 7 color (smallest value of RGB is 10), see the below summary (wb is smallest value of RGB frequency which has scaled down a factor of 10)
Color
Condition match
White
Wb>200, r=10
Yellow
(r>b)&(g>b), b=10
Green
g>b ,g>r, r=10
Blue
b>g,b>=15, r=10
Red
r>b,b=10,g=10
Purple
b>g,r=10,g=11,wb<150
Black
Wb<80,r=10
       
       The buzzer in this project is used to indicate that the object’s color is black (active with low logic level). It will turn off if an assigned button is press, here is button connected with pin PC0     
   
       1 KHz signal is generated by timer0 and send to the buzzer
We have the formula to compute the pulse of signal to generate the desire frequency.

    Thus, we will use timer0 with TCNT0 = -100 counts to 0, than we use variable count increase 5 time every 0.1ms, we will obtain 1 KHz frequency and send it to buzzer.
TCNT0 = -100;        //count value to get 0.1ms
TCCR0=0x02;          //TIMER0 INTERNAL CLOCK, PRESCALER/8
ISR (TIMER0_OVF_vect){            //timer0 interrupt every 0.1ms
       TCNT0=-100;
       count++;
       if (count==5)              //0.1x5 = 0.5ms
              Buzzer ^=0x02;       //create pulse 1kHz at PC1
}

II) Graphic LCD

        In this project, the Graphic LCD 128x64 driven by KS0108 will be used to display the name of color. The specification of this LCD is as follows [2]:
·                    128 horizontal pixel and 64 vertical pixel resolution.
·                    Controlled based on KS0108B
·                    Parallel 8bit interface
·                    On board graphic memory.
·                    Available in Green backlight with dark green pixels.
·                    Also available in Blue backlight with light blue pixels.
·                    LED backlight.
·                    20 PIN linear connection
            Diagram for connection

         Graphic LCD 128x64 interfaces with Atmega32 through PORTB (control) and PORTD (data),below is short map of interfacing.
  GLCD_DATA_O          PORTD  // Ouput Data bus
  GLCD_DATA_I        PIND   // Input Data bus
  GLCD_DATA_DDR             DDRD   // Direction
  GLCD_CTRL_O        PORTB  // Output Control bus
  GLCD_CTRL_I              PINB    // Input Control bus
  GLCD_CTRL_DDR             DDRB   // Direction
  GLCD_E                   PB1    // Enable line
  GLCD_RW                   PB2    // read/write selecting line
  GLCD_RS                   PB3    // Register select: Data/Instruction (DI)
  GLCD_CS1           PB5    // left/right selecting line#1
  GLCD_CS2           PB4    // left/right selecting line#2
Simulate circuit:

Some function is used in graphic LCD 128x64:
void GLCD_Init(void)                     //Initialize GLCD
void GLCD_Clr(void)                      //clear GLCD
void GLCD_PutChar78(uint8_t Line, uint8_t Col, uint8_t chr)   //print character 7x8
void GLCD_Print78(uint8_t Line, uint8_t Col, char* str)              //print string
void GLCD_PutBMP(char *bmp)       //put bitmap image to GLCD                     
int GLCD_PutNum(unsigned char x,unsigned char y, unsigned int num) //print number
For example code:
       //Initialize the GLCD Library
       GLCD_Init();
       GLCD_Clr();  
       //Put my bitmap to GLCD
       GLCD_PutBMP(hiGLCD);
       _delay_ms(2000);
         GLCD_Clr();
       ...
       color = 8;
       Clear();
       GLCD_Print78(0,0,"Oooppp!!!");
       GLCD_Print78(2,10,"Unknown color");       
Please take a look in GLCD.c file to know the purpose of each function.

III) Result
         The application has programmed and run successfully. Seven colors is determined with TCS3200 color sensor module: black, yellow, green, blue, white, red, purple, display the name of color on graphic LCD 128x64 and send 1 KHz signal to the buzzer when the object is black, turn off the buzzer if PC0 is pressed. 
          Because the time is limited, so the application is determined and tested with only 7 colors by the particular specification of each color: white, black, yellow, blue, green, purple, red, it’s not the common specification of all colors. With other colors, if it is not assigned color in 7 color s above, the application will not analyze and respond correct color of object; sometimes it will give the name of nearby color for color of object, for example: dark red or light red are named as red, light blue is unknown color…

Finally, this is just my small research, if it has something wrong. please let me know. I'm glad to see your advise. Thanks you!


Download file:
- Schematic and layout (orcad format). Click here (choose file->download or Ctr+S to save all file)
- All firmware files. Click here (choose file->download or Ctr+S to save all file)
- Schematic of the microcontroller kit. Please contact me, because it's reserved. Email me


Have fun,

Thanh Nguyen
I





2 comments:

  1. First of all, thanks for your sharing.

    For the scaling the frequency part, i still have little confusion. Could you mind please explain in details? What's the MAX RGB values you could detected? I've different MAX and MIN values for red, green and blue if it detectes black or white color. For example, MAX for red is 200,000hz, green is 60,000hz and blue is 120,000. This makes me very hard to do the scaling to the range between 0-1.

    ReplyDelete
  2. Hi Violet,
    what do you mean MAX RGB value it can detect? As you can see in the main code of firmware, i have some line of code to scale the frequency
    [code]
    if(_r<_b)
    {
    if(_r<_g){
    wb=_r;
    }
    else
    wb=_g;
    }
    else
    {
    if(_b<_g)
    wb=_b;
    else
    wb=_g;
    }
    [\code]
    Above code is use to find out what is the smallest value, R or G or B.
    than I save it to wb.
    [code]
    wb=wb/10;
    r=_r/wb;
    g=_g/wb;
    b=_b/wb;
    [\code]
    I use this code to scale frequency which I obtained from TCS3200 to scale of 10.
    For illustration. _r is smallest vaule -> wb=_r, wb=wb/10, r= _r/wb -> r = r/(r/10) = 10. It's mean that when any value in 3 values is smallest, it mus be equal 10.
    If it detects black or white, it doesnt need to compare max or min value of RGB, because white is 255,255,255 -> value of R G B is equal after scale, and the frequency of all there r g b values is largest -> white color, and black is revesed with white, you can see in my code, after compare with a range of r g b, i eliminate the range of black color. I need to hornet that my code is not perfect and it just detects main color only. you can create another better algorithm to solve this problem ^^
    Have fun!

    ReplyDelete