Introduction: Bi-directional LED Sensing Try-out

This experiment was conducted based on the example provided on http://relwin.hackhut.com/2011/03/10/19/ . The example was built on the PICAXE platform and I've converted it onto the Arduino. However, certain attributes to the LED that was explained by hackhut was not taken into consideration for example, the LED discharge time. I simply wrote the code treating the sensing LEDs as normal sensor and they would output whatever they detect on the other LED. The red and white LEDs were chosen as to provide a reference to see the difference of different LED colour attributes on its sensitivity and transmit ability. 

The result could be used in some sort of half-duplex Morse code application or even as an relay or isolator. As tested, the LED does conduct voltage when it senses light of same or lower wavelength than it was designed for. However, the different brands or structures of LEDs differs its capabilities. I provided the source code for Arduino for reference.

/*Demonstrates using LED as a sensor and emitter.
When LED A1 or A2 senses input, the other will emit
light according to the blinking sequence detected*/

#include "pitches.h"

const int led1 = A0;
const int led2 = A1;
const int breakTime = 3000; //in ms
const int speaker = 8;
int value1, value2;
int threshold1 = 250;
int threshold2 = 250;
int numNotes = 4;
boolean timeout = false;
long time = 0;

int melody[] = {
  NOTE_A4,NOTE_E4,NOTE_G4,NOTE_A4};
int noteDurations[] = {
  4, 4, 4, 4};

void setup(){
  Serial.begin(9600);
  pinMode(led1,INPUT);
  pinMode(led2,INPUT);
  pinMode(speaker,OUTPUT);
}

void loop(){
  value1 = analogRead(A0);
  value2 = analogRead(A1);
  if(value1 >= threshold1){
    Serial.print("Value 1 : ");
    Serial.println(value1);
    time = millis();
    out(led1,led2,threshold1);
    pinMode(led2,INPUT);
    timeout = false;
  }
  else if(value2 >= threshold2){
    Serial.print("Value 2 : ");
    Serial.println(value2);
    time = millis();
    out(led2,led1,threshold2);
    pinMode(led1,INPUT);
    timeout = false;
  }
}

void out(int a, int b, int threshold){
  pinMode(b,OUTPUT);
  delay(20);
  while(timeout != true){
    int value = analogRead(a);
    if(value >= threshold){
      analogWrite(b,value);
      time = millis();
    }
    else{
      analogWrite(b,0);
    }
    if(millis() - time >= breakTime){
      timeout = true;
      playTone();
    }
  }
}

void playTone(){
  for (int thisNote = 0; thisNote < numNotes; thisNote++) {
    int noteDuration = 1000/noteDurations[thisNote];
    tone(8, melody[thisNote],noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(8);
  }
}
___________________________________________________________________
As you can see from the video, the red LED cannot respond (transmit)  quick enough to the received signal.
This suggest that the red LED has capacitive properties but may differ due to the holding and discharge time of different LED. When the white LED transmits, its very clear that with every quick interval signals, the white light was able to transmit accordingly and with minimum delay. 

In terms of sensitivity, the red LED would win hands down. White light consists of broad spectrum rays and the wavelength is undetectable by the red LED unless it is put very VERY closely. With the red LED, the distance between the transmitter and receiver for successful sensing could be larger. However, we must put into account that the noise received from the atmosphere was no doubt a big disadvantage as the experiment was done under fluorescent lighting. This problem was partially solved by calibrating possible received values before writing the threshold values of both sensors. Its very simple. The piezo speaker functions to show end of transmission and the Arduino will start sensing both inputs again.

The testing code used is shown below:

void setup(){
  Serial.begin(9600);
  pinMode(A0,INPUT);
  pinMode(A1,INPUT);
}

void loop(){
  int value1 = analogRead(A0);
  int value2 = analogRead(A1);
  Serial.print("Value 1 = ");
  Serial.print(value1);
  Serial.print("\tValue 2 = ");
  Serial.println(value2);
  delay(300);
}

Also include the pitches.h file obtained from the Arduino page .
The circuit drawings were done on Fritzing . It is open-source like the Arduino.