Bidirectional led sensing

A while back I was reading about bidirectional led sensing. Basically, the idea is that you light the LED, and then switch the potential across it, setting the anode to low, and the cathode to high. Since it's a diode, the LED pulls the cathode low. Apparently, the time it takes for the cathode to fall low is dependent on the amount of ambient light -- if we measure that time, then we have a rudimentary sensor.

I tried coding it, and no matter what, it didn't work. I came across a Benoit Rousseau's post on the arduino forum about this. It turns out that there are pullup resistors built-into the Atmega168, and I believe this means that it'll interfere by pulling the cathode high, while sensing with the cathode...? I may be wrong. Anyhow, the solution is to disable those pull-up resistors with the code:

  _SFR_IO8(0x35) |= 4;
  _SFR_IO8(0x35) |= (1<<4); 

The final code was:

/* LED sensor -- photodiode.

int anodePin = 2;
int cathodePin = 8;

int wait = 10;

int value;

void setup()

  //deactivates pullup resistors?
  _SFR_IO8(0x35) |= 4;
  _SFR_IO8(0x35) |= (1<<4); 

  pinMode(anodePin,   OUTPUT);      // sets the digital pin as output
  pinMode(cathodePin, OUTPUT);      // sets the digital pin as output

void loop()
  value = 0;
  //emit light
  digitalWrite(anodePin,   HIGH);
  digitalWrite(cathodePin, LOW);
  //switch potentials -- charge LED to -5V
  digitalWrite(anodePin,   LOW);
  digitalWrite(cathodePin, HIGH);
  //measure time for potential to equalize (for cathode to be LOW)
  //switch pinmode 
  pinMode(cathodePin,  INPUT);
  //measure time it takes for cathodePin to go to zero
  //this value probably depends on the chip clock or something
  while(digitalRead(cathodePin) != 0)
  pinMode(cathodePin,  OUTPUT);
  digitalWrite(anodePin,   HIGH);
  digitalWrite(cathodePin, LOW);
  Serial.println(value, DEC);

Success! I also added code later to light a separate LED when the time for the LED sensor's cathode to drop to low would be higher than a certain threshold:

Posted by provolot on May 20, 2007 3:13 PM | | Comments (3)


TrackBack URL for this entry:

Comments (3)


Congrats on your discovery.

While playing around with a simple way of creating a flickering led ( aka led candle), I stumbled across something that is of course very simple and logical but still interesting.

If you have a string of leds that you want to blink or flicker, you only need one of the string to be a blinking led.

The blinking interupts the power flow causing all leds to blink.

Anyway, one small step for Greg.....

I am just starting out with pic programming and am interested in all aspects of this branch of electronics.

I imagine the schematic is very simple for this project but could you display it for me please.

Also I am currently playing with a 16f84a and was wondering if this code will work with my chip.

I have other ideas for leds and may want to incorporate this into my designs.

Once again, good work...


I tried but it didn't work. However I have a newer microcontroller, ATMEGA 328. Will that effect anything? Or does it matter what LED you have?


Sorry for the late reply - my site's been overrun with spam comments.

I see you have the Duemilanove. I don't have it, so I can't say, but this forum post indicates that "
digitalWrite(PIN_NUMBER,LOW)" might do the trick? I don't fully understand the bitwise or operations that I used, either.

Let me know if it works out!

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)