LED Photocell and Arduino Magic

A Photocell is a transducer used to detect and measure light and other radiations. The principal aim of this article is to explore how to use a common LED as a photocell, employing an LED as a bidirectional device to send and receive light!

LED as a light sensor

In addition to emitting light, an LED can be used as a photodiode light sensor to produce a current that is proportional to the intensity of the light. This capability can be used in a variety of applications including bidirectional optical communications. As a photodiode, an LED is sensitive to wavelengths equal to (or shorter than) the predominant wavelength it emits. For instance, a green LED would be sensitive to blue light and to some green light, but not to yellow or red light. An LED with a clear plastic encapsulation (transparent type) will be more sensitive to broad-spectrum illumination than an LED with colored encapsulation (diffused type).

First, buy a 10mm water clear Green LED. It’s a crucial component required to proceed with the proposed project – this time don’t opt ​​for any other color/type!

According to the datasheet, the super bright green LED I used has a typical peak wavelength of 520nm (VF = 3.2V & IF = 20mA). The typical predominant wavelength is 525nm.

LED light sensor quick test setup

You can build a simple test setup as shown below. Notice that the LED under test is reverse-biased ie in solar cell mode. In the solar cell mode, no applied bias voltage is used – the LED under test generates its own current and voltage. Remember, in order to use the LED as a light sensor, do not forward bias the LED into quadrant #1 of the current-voltage (IV (volt))

curve. (Quadrant 1 is when the operating voltage and current are both positive.) Allow the LED to operate in the solar cell mode, quadrant #4 (operating voltage is positive, current is negative), or in the photodiode mode quadrant #3 (operating voltage is negative, current is negative). Thanks to https://wiki.analog.com/

Simply insert the LEDs in the test setup, one at a time, and try exposing the LED (LED1) to different light sources. Then use an oscilloscope to monitor the voltage at the collector point (TP1) of the transistor T1. The light-generated current will flow into T1 as base current and will appear in the collector multiplied by the current gain (ß) of the transistor T1. You can try increasing the sensitivity or gain of the test setup by increasing the value of the load resistor R1 to 220KΩ or 470KΩ. Or use a Darlington transistor as T1 after lowering the value of the load resistor R1 (you may start with a 2.2KΩ resistor).

How to use one LED as a light sender and receiver at the same time?

Recently I came across an interesting paper on communication using bidirectional LEDs (https://www.merl.com/publications/docs/TR2003-35.pdf), and got inspired by that clever concept. I found that it’s easy to use an Arduino to build a simple bidirectional LED (light sender and receiver) with the help of a few lines of code. In this session, I’ll use an Arduino Uno and a single green LED to demonstrate the idea. This is the hardware setup:

The green LED (LED1) is set to work in three modes. By steering the three modes (forward bias → reverse bias → discharge), the same LED can be used as the light sender and receiver.

Under reverse bias conditions, a simple model for the LED is a capacitor in parallel with a current source which models the optically induced photo current. An easy way to make a photo sensor out of an LED is to tie its anode to ground and connect the cathode to a CMOS I/O pin driven high (this will reverse bias the diode, and charge the capacitor). Next, switch the I/O pin to input mode, which lets the photo current discharge the capacitor to the digital input threshold. By timing how long this takes, we get a measurement of the photo current and thus the amount of incident light. The following figure will (hopefully) make this clear.

Here the default value of the series resistor (R1) is set to 210Ω, however you may try another value within the recommended resistance range – 150Ω to 470Ω. Note that analogue pin A0 of the Arduino is used as a digital pin as well to drive LED1 in bidirectional mode.

My ‘angled’ breadboard snaps:

When you complete the hardware assembly, load the Arduino Sketch (given at the end of this post) into the Arduino Uno (or Nano) board, and keep the setup powered by a 9V battery. When the LED is illuminated by a decent light source, the LED flashes once every 2 seconds (Normal Mode). If the light falling on the LED is obstructed, the LED flashes rapidly at a frequency of about 5Hz (Alarm Mode). The detection sensitivity can be changed by modifying the threshold value in the code – go to the line “int threshold = 400”.

side note: Now you know how to use a ‘bidirectional’ LED in your project, and the way to reverse bias it to work as a photo sensor/light sensor in your microcontroller projects.

All PN-junction diodes, including LEDs, have capacitance due to depletion and diffusion profiles. You can also use the inherent capacitance of an LED to make a series resonant boost circuit that can create a voltage large enough to light the LED. (https://www.edn.com/an-leds-intrinsic-capacitance-works-in-a-650-mv-lrc-circuit/).

Now you have a great Arduino microcontroller setup. It can alternately emit and detect light using only one light emitting diode. According to the paper published by Mitsubishi Electric Research Laboratories, the interchangeability between solid-state light emission and detection was widely publicized in the 1970’s by Forrest W. Mims, but has been largely forgotten by LED users!

It shouldn’t take you too long to learn the ropes!



 * Single LED as a light sender & light receiver

 * Arduino Uno/Nano Project

 * With 10mm water-clear Green LED

 * Adapted Code - Thanks to http://612photonics.com

 * Author: T.K.Hareendran / 08.2020


int ledAnode = 6; // LED-A to D6 through 210R series resistor

int ledCathode = A0; // LED-K to A0

int sensorValue;

int interval = 100; // 100ms

int counter = 0;

int mode = 0;   // Normal =0, Alarm = 1

int threshold = 400; // See Note!

void setup() {

  pinMode(ledAnode, OUTPUT);

  pinMode(ledCathode, OUTPUT);



void loop() {

  if (mode == 0 && counter%10 != 0) { 

    digitalWrite(ledAnode, LOW);

    digitalWrite(ledCathode, LOW);


  else {

    digitalWrite(ledAnode, HIGH); 

    digitalWrite(ledCathode, LOW);



  digitalWrite(ledAnode, LOW); 

  digitalWrite(ledCathode, HIGH);


  pinMode(ledCathode, INPUT); 


  sensorValue = analogRead(ledCathode); 

  Serial.print("value: ");


  if (sensorValue < threshold) mode = 0; 

  else mode = 1;     

  pinMode(ledCathode, OUTPUT);

  counter = counter+1;



Leave a Comment