Arduino Basics: LED as Sensor
Showing posts with label LED as Sensor. Show all posts
Showing posts with label LED as Sensor. Show all posts

19 August 2011

Poor Man's Colour Detector (Part 2) - The project

In this project we will be detecting the colour of 3 different Mega Blok colours (Red, Yellow and Green). We will be using an Arduino UNO connected to  2 LEDs (one Yellow and one Red LED) as light detectors, and an RGB LED to illuminate the subject. We will use a Photocell to account for varying ambient light levels. 

The signals from the LED light sensors will be sent to a Processing.org program via a Serial command. The computer program will make use of my Neural Network to classify the pattern of results and hopefully provide the correct colour "answer". The program should change the colour of the computer screen background to coincide with the colour of the Mega Blok.

The Video


4 August 2011

Poor Man's Colour Detector (Part 1) - The concept

Well, I have finally done it. Not sure if I should post the tutorial, because it is not very basic. But then again, a novice like me managed to do it, so why not !! We will need to pull together a number of previous blogs, but rather than jumping back and forth, I think I will just walk you through from beginning to end, and hope that I don't lose you along the way. 

The concept

In my earlier blog posts, I managed to get LEDs to detect light. And through a bit of trial an error, plus a bit of internet research, I found out that an LED will detect light of the same wavelength that it emits. Therefore a red LED will detect RED light, and a yellow LED will detect yellow light etc etc.

I decided to test this theory by placing different coloured MEGA-BLOKs over the LEDs to see if there was any difference ? And from my simplistic experiments, I could see that the RED LED responded much better to a RED Mega-blok than any other colour, and a YELLOW LED responded much better to a Yellow mega-blok than any other colour.

I decided to test out another theory.
Could I detect other mega-blok colours using a red and yellow LED?

While I was aware that I would be better off using primary colour LEDs (RYB - red yellow and blue) or even RGB (red green and blue) in this experiment, I was limited by the LEDs that came in the Sparkfun's Inventor Kit. So I had to use red and yellow.

I developed a little program in "Processing" that would change the colour of the computer screen based on the colour of the mega-blok sitting over the LEDs. I would use specific cut-off values to separate the different readings and translate them into 4 different classes. This was a bit hit and miss. Depending on the ambient light level, the cut-off values would shift. Plus there was a bit of imprecision in the readings.

I then decided to introduce an RGB LED to shine light on the subject. This helped a bit, however, changes in ambient light were proving to be my enemy. I then introduced a photo-cell, however, by this stage, I had so many values and readings and conditions to meet, that I almost gave up.

That was until I read something about neural networks. Then the real fun began. One month later, and a determined novice that was keen to see this project through to the end, my Arduino UNO can now detect coloured mega-bloks!! How did I do it?  I made the computer figure it out !!

Using a feed-forward neural network with a supervised learning back-propagation model (don't switch off just yet), I got the computer to learn the colours under different light conditions and voila ! I ended up with an Arduino UNO and a couple of LEDs (and photocell) that could tell me what colour Mega-blok was sitting over it. The end result is not 100% perfect, but it works quite well.

In the next part, I will walk you through my neural network step by step. Not sure how this tutorial will pan out, but I'll do my best. (Click here for the Neural Network Tutorial)

Or go here for the table of contents

12 June 2011

Arduino UNO: LED Sensor, Part Two




Building on the last project, I am now using a Red and a Yellow LED as a Sensor to detect light coming from an RGB LED.

Putting different coloured Mega Bloks over the LEDs has different effects on the Sensors as the RGB LED gets brighter and brighter.

I used the Processing Language to control the brightness of the RGB LED through a Serial command, and then use the resulting Sensor readings from the Yellow and the Red LEDs to create a chart or plot.

Here are the results of my experiment.

Red Mega Blok




Yellow Mega Blok



Green Mega Blok













When the displayed bars are RED, it indicates that the Red LED is absorbing MORE light than the Yellow LED (and vice versa). Hence this is a "Difference Chart".
The Green Mega Blok absorbs more Red Light than the other blocks, therefore producing a big difference between Red LED sensor readings and Yellow Sensor readings.

Here is the list of components required to perform this experiment
All parts hardware parts except for the wires and the Mega Bloks
can be found in the Sparkfun Inventors Kit.

Here is the Sketch: (created in Fritzing):

































Here is the Arduino Code:

arduino code RedYellow Sensor with RGB LED

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//Define the pins for the Red LED Sensor
#define Red_LED_Sensor_POS 4
#define Red_LED_Sensor_NEG 5

//Define the pins for the Yellow LED Sensor
#define Yellow_LED_Sensor_POS 7
#define Yellow_LED_Sensor_NEG 8

//Define the pin for the RGB LED torch
#define RGB_LED_RedPin 9
#define RGB_LED_GreenPin 10
#define RGB_LED_BluePin 11
int intensity=0;


//Define the maximum cycles/time allowed for each LED to capture light
long max_darkness=80000;


void setup(){
  //Setup the RED LED Sensor
  pinMode(Red_LED_Sensor_POS,OUTPUT);
  digitalWrite(Red_LED_Sensor_POS,LOW);
  
  //Setup the YELLOW LED Sensor
  pinMode(Yellow_LED_Sensor_POS,OUTPUT);
  digitalWrite(Yellow_LED_Sensor_POS,LOW);
  
  //No need to setup the RGB LED Pins
    
  //Turn on Serial Protocol
  Serial.begin(9600);
}

void loop()
{      
  
  byte byteRead;
   // check if data has been sent from the computer:
  if (Serial.available()) {
    // read the most recent byte (which will be from 0 to 255):
    byteRead = Serial.read();
    // set the brightness of the LED:
    analogWrite(RGB_LED_RedPin, byteRead);
    analogWrite(RGB_LED_GreenPin, byteRead);
    analogWrite(RGB_LED_BluePin, byteRead);
  
  //Read the amount of Yellow light
  read_LED('Y', Yellow_LED_Sensor_NEG);
  
  //Read the amount of Red light
  read_LED('R', Red_LED_Sensor_NEG);
  }
}

void read_LED(char LED_Colour, int LED_Pin){

  // Charge the LED by applying voltage in the opposite direction
  pinMode(LED_Pin,OUTPUT);
  digitalWrite(LED_Pin,HIGH);
  
  //Read the amount of Light coming into the LED sensor
  long darkness=0;
  int lightLevel=0;
  pinMode(LED_Pin,INPUT);
  digitalWrite(LED_Pin,LOW);
  
  while((digitalRead(LED_Pin)!=0) && darkness < max_darkness){
     darkness++;
  }
  
  lightLevel=((max_darkness-darkness)+1)/80;
  
  //Print the LED colour
  Serial.println(LED_Colour);
  //Print the light level
  Serial.println(lightLevel);
}




Here is the Processing Code:

processing code Read Serial Chart and Write Serial

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* Processing code for this example */
 
 // Graphing sketch
 
 //This sketch was written by ScottC, but was adapted from a sketch
 //written by Tom Igoe in 2005
 
 // This example code is in the public domain.
 
 import processing.serial.*;
 
 Serial myPort;        // The serial port
 int xPos = 1;         // horizontal position of the graph
 float YellowVal=0;    // The variable to hold the Yellow Sensor Reading
 float RedVal=0;       // The variable to hold the Red Sensor Reading
 float Diff=0;         // The variable to hold the difference between the readings
 int Switcher=0;       // Used to control the flow of the program
 
 void setup () {
 // set the window size:
 size(1020, 750);        
 
 // List all the available serial ports
 println(Serial.list());
 // I use COM13 for my Serial Port - you will need to change this to suit your system
 myPort = new Serial(this, "COM13", 9600);
 // don't generate a serialEvent() unless you get a newline character:
 myPort.bufferUntil('\\n');
 // set inital background:
 background(0);
 //Send a value to the Arduino to start the feedback mechanism
 myPort.write(0);
}
 void draw () {
 // everything happens in the serialEvent()
 }
 
 void serialEvent (Serial myPort) {
 // get the ASCII string:
 String inString = myPort.readStringUntil('\\n');
 
 if (inString != null) {
   // trim off any whitespace:
   inString = trim(inString);
   
   //The arduino sends 2 sensor readings. The following code 
   //helps to identify which reading is which.
   if(inString.equals("Y")){
     Switcher=0;
   } else if (inString.equals("R")){
     Switcher=1;
   } else {
     
     //Convert the String to a float
     float inByte = float(inString); 
     //Map the reading, so that the chart fits within the window.
     inByte = map(inByte, 0, 1000, 0, height);
     
     if(Switcher==0){
       //Save the reading from the yellow sensor to YellowVal
       YellowVal=inByte;
     } else {
       //Save the reading from the red sensor to RedVal
       RedVal=inByte;
       //Calculate the difference between the readings
       Diff=RedVal-YellowVal;
       
       //If the yellow sensor is greater, plot with a yellow line
       //If the red sensor reading is greater, plot a red line.
       if(Diff<=0){
         stroke(255,255,0);
         Diff=abs(Diff);
       } else {
         stroke(255,0,0);
       }
       // draw the line:
       line(xPos, height, xPos, height - Diff);
 
       // at the edge of the screen, go back to the beginning:
       if (xPos > width) {
         xPos = 0;
         background(0);
         //Send a value to the Arduino to change the intensity
         //of the RGB LED and take another reading
         myPort.write(xPos); 
       } else {
         // increment the horizontal position: Increment by more
         // to get less readings and to make it quicker
         xPos+=4;
         if (xPos>0){
           //Send a value to the Arduino to change the intensity
           //of the RGB LED and take another reading
           myPort.write(xPos/4);
         } else {
           myPort.write(xPos);
         }
       }
     }
   }
 }
}