Story:
I’ve been meaning to build a “line seeker” robot for a while now, however I can’t source LDRs (Light Dependent Resistor) due to RoHS nonsense, so I decided to use plain old LEDs instead. While you could use a couple analog amplifiers and comparators to do this I thought it would be a fun little microcontroller project.
Right now we’re just exploring how to utilize a regular LED as a photo-diode, ie. an input sensor.
There are a couple ways to accomplish this – I chose the simplest for the time being – The idea is to sample the voltage present on the LED anode (or cathode!) by using the ADC on the MSP430, this voltage will be relative to the ambient light. You could picture the LED as a solar cell in this case.
The code:
We’re going to use the on-board LEDs on the LaunchPad to simplify things. The Red LED will be our “sense” input and the Green LED will be used to depict the current state of the sensor.
You’ll have to modify the header (and your project target) depending on which MCU you’re using, I happen to have a G2452 currently populated for another project I’m working on, but you can use any value-line MCU as long as it’s got an ADC.
/* LED as Photo-Sensor
/ By: Gustavo J. Fiorenza (GuShH - info@gushh.net)
/ No external components required, simply shine a light to the RED onboard LED!
/
/ Note: Tested on a G2452 only, should also work with other value-line MCUs.
*/
#include "msp430g2452.h" // Change the header to "msp430x20x2.h" if you're using the default MCU bundled with the LaunchPad.
#define LED_SENSE INCH_0 // LED 1 (Red LED from LaunchPad).
unsigned int adcval = 0;
unsigned int analogRead(unsigned int pin) {
ADC10CTL0 = ADC10ON + ADC10SHT_2 + SREF_1 + REFON + REF2_5V;
ADC10CTL1 = ADC10SSEL_0 + pin;
ADC10CTL0 |= ENC + ADC10SC;
while (1) {
if ((ADC10CTL1 ^ ADC10BUSY) & ((ADC10CTL0 & ADC10IFG)==ADC10IFG)) {
ADC10CTL0 &= ~(ADC10IFG +ENC);
break;
}
}
return ADC10MEM;
}
void main(void) {
unsigned int i, delay;
WDTCTL = WDTPW + WDTHOLD; // Hold the watchdog.
P1DIR = BIT6; // LED 2 (Green LED from LaunchPad).
while (1){
// Multi-sampling (8 samples with delay for stability).
adcval = 0;
for ( i=0; i < 8; i++ ) {
adcval += analogRead( LED_SENSE ); // Read the analog input.
delay = 1000;
while (--delay);
}
adcval >>= 3; // division by 8
// Interpret the result
if ( adcval < 500 ){
P1OUT |= BIT6; // Turn on the onboard Green LED.
}else{
P1OUT = 0x00; // Turn off the entire Port 1, thus turning off the LED as well.
}
}
}
Why so vague?
Lately I've been suffering a serious mental block, I would really like to explain the theory behind all this but not only am I uninspired I also can't focus on writing... I would however recommend you Google "LED Sensor" (or similar query) to learn more about the subject.
Have fun.
Confirmed last night that the code (with a minor correction) runs on the G2231 on the LaunchPad. The correction is:
for ( i=0;< 8; i++ ) {
to
for ( i=0; i<8; i++ ) {
-Rusty-
Thanks, actually the only reason for this mistake is due to a problem with how WordPress parses the content, it encodes the characters every time you switch from Code to normal view, forcing you to manually edit the code — this sometimes leads to typos and missing characters. I’ll update the code soon.
There really isn’t a need to multi-sample and average the result in this case anyway 🙂
Sorta figured sumpin’ like that wuz the problem. 🙂
Thanks for the code.
I had also tested it on G2231.
Cool 🙂
Let me know if you come up with anything interesting!
Cheers.
Hey!
For some reason the code doesnt seem to be working on my g2231.The green led is permanently turned on without any changes.Am not able to figure out why tho.I havent soldered the crystal on the board.But i dont think that should cause a problem in this code right?
Hi, the external xtal is not required for this demo. I just tested the code with the g2231 (simply changed the header to “msp430.h”) and it worked fine. The green LED is supposed to light up unless there’s enough light inciding on the red LED, then the green LED will be OFF.
Make sure your LED jumpers are in place and that you don’t have anything else connected to the pins (leave the board “bare”)
Other than that try using external LEDs or another micro, there has to be something wrong with your particular setup :/
Step the program and see what the adcval variable holds after each conversion cycle, it has to change based on the input light…
I hope you get it working soon!
Cheers.
Hey
Thanks a lot.It does work now.I had to change the range of adcval a bit and now it works jst fine :-)..thanks a lot..also i was wondering if the ADC could be used to sample an audio signal and separate the frequencies.Is that possible?Somewhat lik an equaliser.It was a project i wanted to try out.
Thanks again 🙂
Glad it works!
Hmm, audio requires a lot more processing power than these value-line micros can provide. Take a look at DSP, for example: http://focus.ti.com/dsp/docs/dsphome.tsp?sectionId=46&DCMP=TIHomeTracking&HQS=Other+OT+home_p_dsp — It’s not as hard as it sounds, but it can get pretty complex! — If you have enough processing power and that’s your only task, then a powerful micro may be enough for this. Otherwise you could take a look at how opamp based equalizers work and figure out a way to control them digitally.
Well i did see the DSP boards.But then i was kinda looking at a low budget project :-p.I’ll check the op amp equalizers too.And Thansk for the code 🙂
There are digitally controlled equalizer ICs (for example LMC835) if that’s all you need though, I haven’t messed around with those since they are not exactly common parts… If you were to do it discretely I think one way would be to implement the passive networks for each band and manipulate them with analog switches followed by a decade of resistors (or you could try digital potentiometers) — then an opamp to get some of the lost amplitude back and output a similar db level to the input. It would be a monster ghetto project though. 🙂
Wow!!dats seriously a huge project :-p..but i guess i’ll have to comprimise somewhere rite:-).K i’ll keep searching for alternatives.:-).I’l keep this as an option :-p
Its just amazing…
Utilizing A current which in a range on microampere and flashing LED is just so damn Cool…
Great Work