8 June 2011

Arduino UNO: LED Sensor, Part One

As seen in the previous blog postings, the LED (Light Emitting Diode) was used to DISPLAY the result of various sensors. It was also used to create a variety of Light patterns or sequences.

The LED is commonly used as an OUTPUT device, however, I have since found out: there is another option.

You can use the LED as an INPUT device !!



I have only tried this with a Yellow LED and a Red LED, however, this should work with any colour. Some sites recommend using a clear/transparent/colourless LED for best effect, but it depends on what you are trying to achieve.

The LED responds better to light of the same wavelength that it emits. So a yellow LED responds better to yellow light, and a red LED responds better to Red light.

The following experiment attempts to prove this theory.
A Red and Yellow LED alternate and fade in to maximum brightness using PWM (Analog Output). Meanwhile, a separate LED is used as an INPUT device to receive the light. The value obtained is plotted using a processing sketch.

The chart above used a Yellow LED to measure the light emitted from a Red and then a Yellow LED.
As the Yellow LED gets brighter, the INPUT LED takes less time to discharge, and thus produces a lower result. On the other hand, the Red LED has little effect on the INPUT LED, despite it's brightness.
Ambient light will produce different graph patterns.

Parts Required:
  • Arduino UNO
  • 2 x Yellow LEDs
  • 1 x Red LED
  • 3 x 330 ohm Resistors (choose resistors suitable for your LEDs)
  • 5 wires to connect the circuit
  • Breadboard
  • Processing software
Here is the Sketch:

     Created with Fritzing : http://fritzing.org/


Here is the Arduino Code: which was adapted from this site.
 1
 2
 3
 4
 5
 6
 7
 8
 9
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
#define LED_Sensor_NEG 8
#define LED_Sensor_POS 7
#define Yellow_LED 10
#define Red_LED 9

int switcher=0;
int lightLevelY=0;
int lightLevelR=0;

void setup(){
  pinMode(LED_Sensor_POS,OUTPUT);
  digitalWrite(LED_Sensor_POS,LOW);
  pinMode(Yellow_LED,OUTPUT);
  pinMode(Red_LED,OUTPUT);
    
  //Turn on Serial Protocol
  Serial.begin(9600);
}

void loop()
{      

  //Alternate the flashing of the Yellow and Red LED 
  if(switcher==0){
    lightLevelR+=4;
    if(lightLevelR>255){
      lightLevelR=0;
      switcher=1;
    }
  } else {
    lightLevelY+=3;
    if(lightLevelY>255){
      lightLevelY=0;
      switcher=0;
    }
  }
  analogWrite(Red_LED,lightLevelR);
  analogWrite(Yellow_LED,lightLevelY);


  // Charge the LED by applying voltage in the opposite direction
  pinMode(LED_Sensor_NEG,OUTPUT);
  digitalWrite(LED_Sensor_NEG,HIGH);
  
  // Set pin 8 to read the input and Turn off the internal pull up resistor. 
  // The greater the amount of light in the room, the smaller the number represented by variable "darkness".
  long darkness=0;
  int outputVal=0;
  pinMode(LED_Sensor_NEG,INPUT);
  digitalWrite(LED_Sensor_NEG,LOW);  
  while((digitalRead(LED_Sensor_NEG)!=0) && darkness<80000){
     darkness++;
  }

  outputVal=darkness/80;
  //Print the darkness level in the room.
  Serial.println(outputVal);
}

Here is the Processing Code:     Code Source
 1
 2
 3
 4
 5
 6
 7
 8
 9
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
/* Processing code for this example */
 
 // Graphing sketch
 
 
 // This program takes ASCII-encoded strings
 // from the serial port at 9600 baud and graphs them. It expects values in the
 // range 0 to 1023, followed by a newline, or newline and carriage return 
 // Created 20 Apr 2005
 // Updated 18 Jan 2008
 // by Tom Igoe
 // This example code is in the public domain.
 
 import processing.serial.*;
 
 Serial myPort;        // The serial port
 int xPos = 1;         // horizontal position of the graph
 
 void setup () {
 // set the window size:
 size(400, 300);        
 
 // List all the available serial ports
 println(Serial.list());
 // I know that the second port in the serial list on my PC 
 // is always my  Arduino, so I open Serial.list()[1].
 // Open whatever port is the one you're using.
 myPort = new Serial(this, Serial.list()[1], 9600);
 // don't generate a serialEvent() unless you get a newline character:
 myPort.bufferUntil('\n');
 // set inital background: 
background(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);
 // convert to a float and map to the screen height:
 float inByte = float(inString); 
 inByte = map(inByte, 0, 1023, 0, height);
 
 // draw the line: 
stroke(127,34,255);
 line(xPos, height, xPos, height - inByte);
 
 // at the edge of the screen, go back to the beginning:
 if (xPos >= width) {
 xPos = 0;
 background(0); 
 } 
 else {
 // increment the horizontal position:
 xPos++;
 }
 }
 }

14 comments:

  1. Hello I have a question about your Arduino project. I am trying to recreate this but I have a problem with Processing. In your code on line 41 it says

    " String inString = myPort.readStringUntil('\\n');"

    What should the commented n be? Processing won't start because of this.

    ReplyDelete
    Replies
    1. Try \n instead of \\n
      It is basically reading from the port until it comes across as linefeed eg. Serial.println("");

      Delete
    2. I have now fixed this in the code.

      Delete
  2. hi i have atlas pH stamp, arduino duemilanove.

    i want to trigger some LEDs, buzzer,when certain pH is reached. i also want to display the pH reading on LCD display.

    please help me with the code. any reference would also be really helpful.

    this is my first time doing such project.

    thanks

    ReplyDelete
    Replies
    1. Hi Unknown,
      Have a look at these sites:
      pH Stamp:
      http://atlas-scientific.com/_files/code/Arduino-sample-code-EZ-COM.pdf
      http://atlas-scientific.com/product_pages/embedded/ph.html
      https://www.sparkfun.com/products/10972

      Buzzer:
      http://www.hobbytronics.co.uk/arduino-tutorial7-piezo-beep

      LEDs:
      http://electroschematics.com/6766/simple-arduino-led-projects/

      LCD display:
      Depends on the type of LCD display - but this may take up a lot of pins.
      http://www.arduino.cc/playground/Code/LCD

      I'm sorry - I don't have a pH stamp - but these sites should get you on the right track. Have a go, and then post any issues you have on the Arduino forums. They are very helpful.
      http://arduino.cc/forum/






      Delete
  3. hi...i am working on bidirectional communication using LED,
    i needed help for transmitting a string serially from one arduino to other via LEDs(ie LED as tx & other side LED as rx).
    is this possible without converting each string to binary manually??
    thanks, got to learn a lot from ur posts

    ReplyDelete
    Replies
    1. I am not sure on how you could do this without converting it to binary.
      Perhaps you could create a "secret code" whereby different LED intensities could represent a specific letter / number (it depends on what you are trying to transmit). However,you have to take into consideration the effects of stray light or light interference. You would have to test this under varying levels of ambient light, and the precision of each reading would have to be investigated. The safest option is binary, but I guess the secret code sounds like more fun?

      Delete
    2. the problem that we face using binary is synchronization ....
      the receiver LED misses 1bit/100bits at just rate of 2bits/sec.
      anyways...if binary is the only option, then are there any readily available efficient codes in your consideration , that could help me??
      thanks again:)

      Delete
    3. Firstly, there are so many variables that I do not know about your system. Are the LEDs close/far. How bright are they? Are you using an Arduino? Why are you using LEDs? What rate do you need? Could you use more than 2 LEDs or do you specifically need to use 2. Are the LEDs moving (like on a robot) - ie. are the distances changing?
      Sorry - it is hard to really answer your question without knowing what you are trying to achieve. I have never transmitted a specific message using LEDs - but I could try and see what I come up with... not sure how long it would take. I guess it also depends on how long you are willing to wait :)

      Delete
    4. actually we are workin on a project to obtain low cost sensing...
      as LED works as detector, low distance comm can be very cheap....
      refer "Very Low-Cost Sensing and Communication Using Bidirectional LEDs, Paul Dietz, William Yerazunis, Darren Leigh TR2003-35 July 2003 MITSUBISHI ELECTRIC RESEARCH LABORATORIES http://www.merl.com"


      distance = 10 cm constant
      LEDs are normal white leds(can be red as well)
      want rates as much as possible

      not much info is available on net
      anyways its interesting to try out...

      Delete
    5. I will look into it - but don't expect any miracles. It may take a bit of trial and error. If I can get it to work - I will blog about it. Not sure how long that will take... I hope you are patient :)

      Delete
    6. How many LEDs am I allowed to use? What about photoresistors - am I allowed to use them - or only LEDs? And I assume Arduino?

      Delete
    7. Hi Anonymous,

      After a bit of trial and error, like I said before, you have to take into consideration the effect of stray light. You had issues with synchronization, and from my own experiments - looks like you need a way of telling the other arduino that you are about to send a message. While the concept seems pretty simple, there are a lot of variables and factors that need to be accounted for. You need to understand the principles of Analog to Digital conversion, when the Analog signal can vary depending on the amount of ambient light. This is not an easy task, and unfortunately I don't have enough time to sort this one out at the moment. I may revisit this at a later date. Sorry.

      Delete
    8. If I were you, I would use 2 LEDs of different colours (eg Green / Red), to represent the 0s and 1s, rather than try to use a single LED for both binary representations. I think this approach would be a whole lot easier.

      Delete

Feel free to leave a comment about this tutorial below.
Any questions about your particular project should be asked in the ArduinoBasics forum.

Comments are moderated due to large amount of spam.