newest photos | all photos | cream of the crop | stuffcalendar | adailyphoto | waves | words | stuff | projectlog | about
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
  
  Serial.begin(9600);
}

void loop()
{
  value = 0;
  
  //emit light
  digitalWrite(anodePin,   HIGH);
  digitalWrite(cathodePin, LOW);
  delay(50);
  
  //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)
    value++;
  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 on May 20, 2007 3:13 PM | | Comments (0)

TrackBack

TrackBack URL for this entry:
http://www.provolot.com/cgi-bin/mt4/mt-tb.cgi/52

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.)