PDA

View Full Version : LED "capacitance" won't get lower



flotulopex
- 1st May 2007, 21:08
Hello,

I've been reading some threads about the LED's capacity feature and that they can be used as "sensors".

Now, I made a short program where I involve 3 LEDs to be discharged and measured in time like this:
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1583&stc=1&d=1178048854">

The shema is simple: one port connected to all Anodes (through a 330 ohms resistor) and three ports connected each to one Kathode. I use a 16F88 @ 20MHz.

I reduced the code as much as I could and here it is:
LOOP:
for Counter = 1 to 3
PORTB.0 = 0 : PORTB.0(counter) = 1 'reverse power to the LED to "charge" it
TRISB.0(counter) = 1 'make the last HIGH port an Input and...
while PORTB.0(counter) = 1 '...read it. As long as port is 1, increment "Discharge"
discharge = discharge + 1
wend
discharge(counter) = discharge 'store Discharge's value for later comparision
discharge = 0
next
gosub display
TRISB = 0
goto loop
end
I know I can reduce the overall process time by modifying the program but this is currently not the problem since I want to reduce the discharge time of each LED.

I thought I would be able to lower the LED's capacitance by reducing the voltage applied to it. So I put a 10K instead of the 330ohms one.

I even added a 10Mohms resistor in parallel with the LED to make a kind of load.

Result: no change(!?). The time values never change.

What am I doing wrong here? Should I use a 40MHz PIC instead?

skimask
- 1st May 2007, 21:20
Hello,
I've been reading some threads about the LED's capacity feature and that they can be used as "sensors".
Now, I made a short program where I involve 3 LEDs to be discharged and measured in time like this:
The shema is simple: one port connected to all Anodes (through a 330 ohms resistor) and three ports connected each to one Kathode. I use a 16F88 @ 20MHz.....etc....etc....etc....


Check my webpage, www.srt.com/~jdgrotte, click on LED touch sensor.
I did basically the same thing awhile back, used 8 LEDs, NO resistors, standard parallel LCD, and an 18F4620 @ 40Mhz.
Most of the code is posted on the page itself. Should work with a 16F88 at 20Mhz, not sure, never tried.
Check the video to see it in action (it's a crappy video, I've been meaning to update, never got around to it).
This is actually my 18F4620 code:



looper var byte
anode var porta.1 'common anode of all IR LEDs

t1 var portc.5 : t2 var portc.4 : t3 var portc.1 : t4 var portc.0 : t5 var porte.2 : t6 var porte.1 : t7 var porta.4 'all IR LEDs cathodes pins

touchval var word[7] : touchmin var word[7] : touchmax var word[7] : touchrange var word[7] : touchpos var word[7] : touchaverage var word[7]
touchmidpoint var word[7] : maxval var byte : maxtemp var word

skipsubs: 'generic setup I use for all my programs, YMMV
flags=0 : pause 1000 : intcon=0 : intcon.7=1 : intcon.6=1 : intcon.5=1 : intcon2=0 : intcon2.2=1 : intco3=0 : pir1=0 : pir2=0 : pie1=0 : pie1.5=1 : pie1.4=1
pie2=0 : t0con=0 : t0con.7=1 : t0con.6=1 : t0con=t0con+2 : t1con=0 : t2con=0 : t3con=0 : ccp1con=0 : ccp2con=0 : pwm1con=0 : eccp1as=0 : sspstat=0
sspcon1=0 : sspcon2=0 : txsta=0 : txsta.6=0 : txsta.5=1 : txsta.4=0 : txsta.2=1 : rcsta=0 : rcsta.7=1 : rcsta.6=0 : rcsta.4=1 : baudcon=0 : baudcon.3=1
spbrgh=4 : spbrg=16 : adcon0=0 : adcon1=$f : adcon2=$ff : cmcon=7 : cvrcon=0 : hlvdcon=0 : trisa=0 : porta=0 : trisb=0 : portb=0 : trisc=0 : portc=0 : trisd=0
portd=0 : trise=0 : porte=0 : input switch1 : input switch2 : output led1 : led1=1 : led1=0 : pause 200 : led1=1 : pause 200 : led1=0 : pause 200 : led1=1
pause 200 : led1=0 : pause 200 : led1=1 : pause 200 : led1=0 : pause 200 : led1=1 : pause 200 : led1=0 : pause 200 : lcdout $fe,1 : switchignorecount=0
menu=1 : switchdelay=1000 : output serialdataoutputpin : input serialdatainputpin : touchmin = 65000 : touchmax = 100

loop2:
led1 = counter.0
for looper = 1 to 7 'light an LED, even though you can't see it
output anode : anode=1 : input t1 : t1=0 : input t2 : t2=0 : input t3 : t3=0 : input t4 : t4=0 : input t5 : t5=0 : input t6 : t6=0 : input t7 : t7=0
select case looper
case 1
output t1 : t1 = 0
case 2
output t2 : t2 = 0
case 3
output t3 : t3 = 0
case 4
output t4 : t4 = 0
case 5
output t5 : t5 = 0
case 6
output t6 : t6 = 0
case 7
output t7 : t7 = 0
end select
pause 1 : anode = 0
select case looper 'reverse bias that same LED
case 1
output t1 : t1 = 1
case 2
output t2 : t2 = 1
case 3
output t3 : t3 = 1
case 4
output t4 : t4 = 1
case 5
output t5 : t5 = 1
case 6
output t6 : t6 = 1
case 7
output t7 : t7 = 1
end select
pause 1
select case looper 'switch that LED to an input to read it
case 1
input t1
case 2
input t2
case 3
input t3
case 4
input t4
case 5
input t5
case 6
input t6
case 7
input t7
end select
loop3a:
'run a counter in a tight loop (loop3a) and keep checking and waiting for the particular LED input to drop from
'a logic 1 to a logic 0 because the voltage sitting on the LED due to the internal capacitance drops 'slowly'
touchval[ looper ] = touchval[ looper ] + 1 : if touchval[ looper ] > 65000 then goto kickoutloop3a
'if we wait too long or the pin is stuck, we'll never get out of the loop
select case looper
case 1
if t1 = 1 then goto loop3a
case 2
if t2 = 1 then goto loop3a
case 3
if t3 = 1 then goto loop3a
case 4
if t4 = 1 then goto loop3a
case 5
if t5 = 1 then goto loop3a
case 6
if t6 = 1 then goto loop3a
case 7
if t7 = 1 then goto loop3a
end select
kickoutloop3a:
counter = counter + 1 'just a counter to show a 'heartbeat'
next looper

maxval = 0 : maxtemp = 0 'maxval keeps track of which led had the lowest value, maxtemp keeps track of the lowest value

for looper = 1 to 7 'check al 7 LEDs to find the lowest one
if touchval[ looper ] > maxtemp then
maxtemp = touchval[ looper ] : maxval = looper
endif
next looper

'clear out the line, then display the number of the darkest LED
lcdout $fe , $80 , " " : lcdout $fe , $80 + ( 7 - maxval ) , DEC1 ( 7 - maxval ) : lcdout $fe , $c0 , " " : lcdout $fe , $c0 + ( 7 - maxval ) , $ff
for looper = 1 to 7 : touchval[ looper ] = 0 : next looper
goto loop2
END

flotulopex
- 1st May 2007, 21:40
Hi skimask,

I've read lots of threads and went already on your site (btw: thank you) and many others about this topic.

The problem is not to make it work - it does.

I want to understand how to modulate the LED's capacitance.

It's maybe more an electronics issue, not a PIC one at this time.

Any idea?

skimask
- 1st May 2007, 22:34
Hi skimask,
I've read lots of threads and went already on your site (btw: thank you) and many others about this topic.
The problem is not to make it work - it does.
I want to understand how to modulate the LED's capacitance.
It's maybe more an electronics issue, not a PIC one at this time.
Any idea?

I tried a few different things, added resistors, added small cap's in parallel with the LED, couldn't really get the results to change to get a larger 'range'. The results would 'shift' up and down, but never really stretch out the way I wanted them to.
Are you trying to 'widen' the range of the number you get back from the function? In other words, instead of, say 0-10, you'd get 0-1000?
The key might be finding the right LED vs. adding components to the circuit, or just plain counting it all really fast.
As you can see from my page, basically, as soon as I got that to work, I called it good...something in the hobby toolbox for the future...

rhino
- 2nd May 2007, 03:13
I've been doing some reading on this subject and had it in the back of my mind for sometime now, using an led as a switch instead of a mechanical switch. A few things that I've read that may influence the range your after are the color of the lens... I think a clear lens works better, and the amount of ambient light in the room. It would be an easy experiment to see how it reacts in total darkness compared to whatever your normal lighting conditions are. Here's a couple links for info.
http://www.edn.com/article/CA6387024.html
Check out some of the references at the bottom of the page. I especially like the reference to the Mitsubishi Electric Research lab paper.
THIS (http://cs.nyu.edu/~jhan/ledtouch/index.html) is originally where I saw a demonstration. And ofcourse Skimask has video proof that it works, not to mention nice enough to post some code. Nice video!

skimask
- 2nd May 2007, 03:37
A few things that I've read that may influence the range your after are the color of the lens... I think a clear lens works better

I tried a couple of type of red lensed LEDs, barely got any results at all. Tried a clear-greenish lensed, got some results, but nothing useful. The LEDs I ended up using were IR LEDs. You can barely see them in that 'video' I made. They show up on the camera, but you can't really see them.


and the amount of ambient light in the room. It would be an easy experiment to see how it reacts in total darkness compared to whatever your normal lighting conditions are

I sorta wrote the code to compensate for ambient lighting. I'd keep track of the high and low values and the one that was the darkest was the one with my finger over it. And the code on the site isn't exactly the finished product. The 'real' code (before I shelved the project) had a couple of extra lines in it to 'reset' the high and low values over time so they wouldn't get 'stuck'.


http://www.edn.com/article/CA6387024.html

That same video is where I got the original idea from.


And of course Skimask has video proof that it works, not to mention nice enough to post some code. Nice video!

(Code posting) - First time for everything I guess :D

Someday, when I get my basement/LAB rework finished (major water damage, repainting walls in the works), I'll put it back together with a few more LEDs and redo the video. Bought the wife a new camera for Xmas last year (or was it me? I forget :D)...has a really decent movie mode on it.

flotulopex
- 2nd May 2007, 08:18
Well,

I see we all have been reading and viewing the same documents and medias already.

I've tried this with lots of different LEDs (IR, simple colored red/ambre/green/yellow/blue/white, 7seg and even a bicolor one) and they ALL work. Of course, I get different results but it works always.

Since the way to "measure" the LED with a PIC is to calculate it's discharging time (state change), to make it work fast, I want to REDUCE the "RC time".

So, if now I'm counting around 4000 counts (see post #1) until the LED goes from state "1" to state "0", I want to speed-up things with lowering this value and make it become something around 100.

How can I reach this?

Depending on the surrounding luminosity, the scanning/counting process can vary from a few milliseconds to seconds.

As mentionned in lots of articles, the surrounding luminosity affects tremendously the discharge time of the LED and compensation is mandatory.

In my mind, the only way to compensate the longer discharging time due to surrounding darkness is to reduce the voltage applied to the LEDs.

Is there another way?

Ioannis
- 2nd May 2007, 10:02
Since the discharge is performed by the PIC itself, I don't see a way to speed the process unless you connect an external Transistor in parallel with the LED. A mosfet perhaps. But that will complicate the things...

Ioannis

flotulopex
- 2nd May 2007, 11:04
Okay; I probably ask the wrong question. Let me formulate another way.

If I recall well, the electrical law for capacitors is: Q = U x C = I x t

Where:
Q is the Load (Coulomb) - in french, la charge
U is the Voltage
C is the capacity (Farad)
I is the intensity (Amps)
t is the time (second)

A.- Is it correct/acceptable to apply this law to LEDs?

B.- Am I right to think that if I change the charging voltage of the LED, I'm going to modifiy its Load?

skimask
- 2nd May 2007, 14:12
A.- Is it correct/acceptable to apply this law to LEDs?

B.- Am I right to think that if I change the charging voltage of the LED, I'm going to modifiy its Load?

1- I don't know if it so much applies to LEDs as it applies to the interjunction capacitance of a diode, so, yes, by definition, it does apply to LEDs.

2- If you change the charging voltage to the LED, I would think all you'd really change is the point at which the voltage dropping from the LED would trip the PICs pin input from logic high to logic low...(one setup charges to 5v, take awhile to drop to logic 0, other setup only charges to 3v, doesn't take near as long to drop to logic 0).

Why do you want to 'speed up' the discharge process?
What end result AREN'T you getting now that you really want?

Just trying to get a handle on what you're after...

flotulopex
- 3rd May 2007, 07:04
Okay skimask,

I'll try to explain clearly what I'm doing - or trying to achieve.

I have three 7seg-LEDs (three "digits") connected to a 16F88 @ 20MHz and I want them to act as buttons as well.

These three 7seg-LEDs display random numbers whithout any decimal point so I use this Dot-Point as the sensor for each 7seg-display.

I couldn't find exactly in your code how you compensated the effect of the surrouding luminosity but you have surely noticed that, in a dark environment, the discharge time of the LEDs raises drastically.

Thus, the "scanning time" until the "darkest" (or "pressed") LED is detected can be quite long. In my experience, it can take over a second.

My idea is to compensate the surrounding darkness by dropping the LED's Dot-Point voltage and hence, reduce the charging/discharging cycle.

Currently, for testing, I'm working with three digits but my final project would have ten digits (key-pad) so the time to analyse which button is pressed is important.

Voilą. Hope this helps for understanding...

It's far too amazing so I can't give-up now; got the same kick as you :D

skimask
- 3rd May 2007, 13:32
I have three 7seg-LEDs (three "digits") connected to a 16F88 @ 20MHz and I want them to act as buttons as well.

I'm wondering if the case of the 7 segment displays isn't killing your light input, ya know, the covering over the segments themselves...


I couldn't find exactly in your code how you compensated the effect of the surrouding luminosity

I just kept scanning the LEDs, keeping track of the highest and lowest result every returned. Just for arguments sake, let's say the highest result I've gotten is 500. The next time I scan, the highest result is 498, I might subtract 1 from my last known highest result. Same thing for the lowest result. I don't rely on absolute numbers. I keep track of the range of inputs, recheck the inputs, see if the same input is the highest more than once, then select the most probable out of the bunch.


My idea is to compensate the surrounding darkness by dropping the LED's Dot-Point voltage and hence, reduce the charging/discharging cycle.

I wonder if going the other direction, lighting it up a bit more would be better.
And it is a neat little thing to play with...
All in all, I think it's the 7 segment display itself that's going to cause you problems.

Ioannis
- 3rd May 2007, 13:42
I have not yet dealed with this kind of touch sensors but have an idea for flotulopex: Use all 7 segments, or at least some of them, to measure the ambient light instead of the dot only. I think you will get more reliable data.

When I have the time I'd love to experiment on this.

Ioannis

skimask
- 3rd May 2007, 13:43
I have not yet dealed with this kind of touch sensors but have an idea for flotulopex: Use all 7 segments, or at least some of them, to measure the ambient light instead of the dot only. I think you will get more reliable data.
When I have the time I'd love to experiment on this.
Ioannis

There ya go...you could use some of the lit segments along with the dot. At least you'd get a better average. And some of the light from other lit segment bouncing off your finger might help the other 'sensing segments' give you better numbers.

flotulopex
- 3rd May 2007, 14:38
I did so already (using all segments).

There's no big difference with using the dot-point only.

I spent around 20 hours on making tests with different LED configurations and finally, I think the best way to handle "compensation" would be to influence the LED's capacitance.

But up to now, nobody could give me a hint on how to achieve this... :(

skimask
- 3rd May 2007, 14:47
I did so already (using all segments). There's no big difference with using the dot-point only. I spent around 20 hours on making tests with different LED configurations and finally, I think the best way to handle "compensation" would be to influence the LED's capacitance. But up to now, nobody could give me a hint on how to achieve this... :(

If, in fact, it is achievable...which I don't think it is. Sure you can change the 'charge voltage', but it'll still discharge at the same rate. You can change load resistance, which will also affect your charge time.
Maybe you might need a different type of display, maybe a different color?
How about some sort of constant overhead light (front lighting?)...
You've got a neat idea...and I'm thinking...still...and it hurts :)

Ioannis
- 3rd May 2007, 20:31
skimask's keyword is "rate". That won't change with voltage only.

Given the voltage and the load on the capacitance of the LED the rate will always be the same.

Only by changing the load presented to the LED will change the rate. And now it came to me an idea. Why not put a second pin of a PIC in parallel to increase the load when you want and then set it at tristate again? May be and a third one?

Ioannis