Ambient light color sensing

From Mech
Jump to navigationJump to search

Overview

Phototrans.jpg

A phototransistor will alter its emitter current according to the amount of light shone upon its base input. Thus, the current will be at its maximum when the transistor receives the most light, and at a minimum when it receives no light. To translate this current into a voltage measurable by the PIC, the voltage can be probed across a resistor placed in series at the collector or emitter of the phototransistor. This means that maximum voltage (at maximum light exposure) should be approximately equal to the input voltage at the collector, minus the voltage drop across the transistor, and the minimum voltage should be approximately zero.

To split the source light into separate colors, color filters must be used to block out other wavelengths of light. A red color filter will allow red light to pass through (650 nm), a cyan filter will allow cyan light to pass through, and a green filter will allow green light to pass through (510 nm). Note that filters may also allow light out of the visible spectrum (for example, Infrared radiation), so be sure to consult the spectral property of the individual filter you intend to use. The spectrum of the green filter can be seen on the right. (Click here for filter spec sheet).

Color filter.JPG

These three filters will split light into Red-Green-Blue (RGB) components, a common quantification of the visible spectrum in PCs. Note that phototransistors may be sensitive to differing wavelengths of light, usually visible light or IR phototransistors- make sure you choose the correct one for your purposes.


LCDRGB.jpg

The sensitivity of the phototransistor depends on the resistance R. Using a larger resistance will allow for an increase in the ability to detect changes in light. Once you have three different phototransistor voltages that are dependent on 3 RGB values, each one can be connected to the PIC via an analog input. While the voltage read may be between 0 and 5, it can be adjusted linearly to a scale from 0 to 255, the range for an RGB value. Each transistor will have a value from 0 to 255, which can then be reconstructed back into a single color on the computer, or can be printed out to an LCD screen.

The LCD screen is a two-line parallel port screen, model MCC162A4-5. The information for displaying content on the lcd screen can be found here: C_Example:_Parallel_Interfacing_with_LCDs.

Phototransistors can be purchased through digikey. Color filters may be ordered here.

Circuit

Photo circuit.jpg

R = 100 kOhm. Rp has a max value of 10 kOhms.

Note that if the positions of the phototransistors are swapped with that of the resistors, the input signs will be reversed.

RGBcicuit.jpg

Code


#include <18f4520.h>

#DEVICE ADC=8;

#fuses HS,NOLVP,NOWDT,NOPROTECT
#use delay(clock=20000000)
#include "flex_lcd.c"

//#use rs232(baud=19200, xmit=PIN_A0, rcv=PIN_A1)    // you can use any pins for software uart...
#use rs232(baud=19200, UART1)       // hardware uart much better; uses  RC6/TX and RC7/RX 
// characters tranmitted faster than the pic eats them will cause UART to hang.

int8 R;
int8 G;
int8 B;
int8 redchan;
int8 bluechan;
int8 greenchan;

void main(){

 setup_adc_ports(AN0_TO_AN3);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11
 setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0
 
lcd_init();  // Always call this first.

lcd_putc("\f(R,G,B)\n");
 
    while (TRUE) {
   
      set_adc_channel(1);     // there's only one ADC so select which input to connect to it; here pin AN0
      delay_us(10);           // wait 10uS for ADC to settle to a newly selected input
      redchan = read_adc();     // now you can read ADC as frequently as you like
      set_adc_channel(2);     // there's only one ADC so select which input to connect to it; here pin AN0
      delay_us(10);           // wait 10uS for ADC to settle to a newly selected input
      greenchan = read_adc();     // now you can read ADC as frequently as you like
      set_adc_channel(3);     // there's only one ADC so select which input to connect to it; here pin AN0
      delay_us(10);           // wait 10uS for ADC to settle to a newly selected input
      bluechan = read_adc();     // now you can read ADC as frequently as you like
      
     R = 255 - redchan  ;
     G = 255 - greenchan;
     B = 255 - bluechan;
   
           
printf(lcd_putc,"(%u, %u, %u) \n", R,G,B);
            
       delay_ms(500);
   }
}