PDA

View Full Version : 12F629 LDR - Light Dependant Resistor



Dennis
- 15th February 2010, 21:43
Hi all

I've been dabbling with an LDR and a PIC 12F629 (any PIC should work though) and found it so straight forward and simple that I thought some forum users might enjoy it and come up with some more interesting ideass.
This really does add a whole new dimension to the traditional day/night sensor. You could start logging the amount of actual daylight etc.

LDR's can be setup using either one of two very simple circuits.See this link for more info, I found it very helpful and interesting.
http://www.doctronics.co.uk/ldr_sensors.htm

Here is the code


************************************************** ***********************************
'12f629 to demo the use of an LDR by DENNIS
'see ldr test scehmatic
'USES ONLY 1 PIC PIN
' +---+--+---+
' VCC 1 +--+ 8 GND
' OSC1,X1,GP5 2 7 GP0,CIN+,PGD
' OSC2,X1,GP5 3 6 GP1,CIN-,PGC
' VPP,/MCLR,GP3 4 5 GP2,T0CKI,INT,COUT
' +----------+
' 12Cxxx, 12Fxxx
'
' I tested circuit in daylight and indoors, make sure you have enough light and dark separation
' Adjust the 10K potentiometer for the correct sensitivty
' For reverse operation just change IF GPIO.2 = 1 then dark << replace with 0
' This circuit does not require any crucuial timing and can be moved to any PIC
'************************************************* ***********************************

define OSC 4 '4MHz
DEFINE OSCCAL_1K 1 ' Set OSCCAL for 1k -HELPS tuning the crystal for more accurate timing
CMCON = 7 'set digital mode
'ansel = 0 'GPIO.2 and GPIO.3 set as digital - disable if using 12629 for LDR
'TRISIO = %76543210 ' port GPIO 0=output and 1=input
TRISIO = %0000100 ' GPIO.2 is an input - all the rest are outputs


' Variables
LED var GPIO.0
' end of variables
Start:
If GPIO.2 = 1 then night
HIGH led 'Turn on/off whatever you like by changing this line/replacing LED
goto start

Night:
Low led 'Turn off LED (or device)

goto start
END

In my experiment I found the best light source to be real daylight, and walking around with the breadboard as I walked in and out the door the LED would switch off (in the dark- indoors) or on (outside in daylight).
To alter the sensitivity the 10K pot can be adjusted, I found that halfway worked well.
You can reverse the operation , in other words, off at night and on during the day by just changing the 1 in this line to a 0

If GPIO.2 = 1 then night

The schematic is attached.

Hope this helps someone, and post back any info about how it worked for you or what could be changed or added :-)

Kind regards

Dennis

mtripoli
- 15th February 2010, 23:01
You don't really mean "-5V" in the schematic... call it "ground" or something... else we see the little gears in the IC come flying out...:)

Mike Tripoli

Dennis
- 15th February 2010, 23:12
Hehehe
Speed kills hey ?
Well that would make 10V the supply then :-) and without a regulator mmm could prove interesting ;-)

Mike ..thanks a million for catching that one in time :-)
Yes it definitely must be GND not -5v as in the schematic :-)
Will see if I can replace the schematic :-0

Keep well

Kind regards
Dennis

Dennis
- 15th February 2010, 23:18
Here it is .. the schematic corrected to show +5V and GND rails :-)

Kind regards
Dennis

BobK
- 16th February 2010, 03:34
Hi Dennis,

So you have an LDR and a pot and a 1 k resistor across the supply rails. Isn't this combination suppose to connect to an input on the micro? I mean how else is the micro suppose to sense a change then turn the LED on?
Just an observation!

BobK

Nice program example though!

Bruce
- 16th February 2010, 04:52
Wiper on POT to GPIO.2..?

grounded
- 16th February 2010, 13:43
forgive just trying to understand what your doing here.
instead of using the LDR as a A/D input (which the 29 does not have)
when the amount of light causes the voltage to over come the the pull down resistor you get a high input on gpio.2 ?
am I close?

Dennis
- 16th February 2010, 20:15
Hi all

Apologies for the confusion .. I had left an important line out of the schematic in my rush to share.

All is fixed now !! The new corrected schematic is attached.

I don't know how those bad schematics got here ..HUMAN HUMAN HUMAN.. grrr!

@BobK .. well we could have been trying a current limiter or 'floating points' ;-)
Valid chirp though was laughing like mad at myself for forgetting a track in schematic and spot on it should connect somewhere for the PIC to be of any use ...!

@grounded , damn right... build it , and see the magic ;-), works like a charm!

@Bruce GPIO.2 conects right between the 10K potentiometer and the LDR

Build it build it build it !

Kind regards
Dennis

Bruce
- 17th February 2010, 23:37
I used a similar circuit for an Intel 8749 Micro-Bot project I wrote for Circuit Cellar way back
in 1998, issue #92, to turn on a set of bright LED headlights on my robot.

Worked really well. Robot entered a dark area, and headlights turned on automatically.

Moved into the light, headlights turned off.

http://www.circuitcellar.com/archives/CD_contents/1998.html

Déjà vu ehh...;o)

Dennis
- 17th February 2010, 23:59
Hi Bruce


Unfortunately I can't get to see the article/place/page referred to in your link as I am not a subscriber :-(
Looks like a very interesting magazine(s) based on the tables of contents!
I always used to read Elektor magazine which aslo had some very interesting articles and projects.
Would be very interested to have a look though.. perhaps you could show a schematic or code ?

What got me started on the LDR mission was this site http://www.doctronics.co.uk/ldr_sensors.htm as I needed to understand the working of LDR's.

Earlier today I was wondering what would happen if(and when) the supply voltage would drop below the 5Volts I was using for calculations.
Need to dabble a little bit more by dropping the supplied voltage and see what the results are, hope to be able to give some feedback on that shortly.

Kind regards
Dennis

Kind regards

Dennis

Bruce
- 18th February 2010, 00:27
Hi Dennis,

Unfortunately - you can't view the article or code without buying a copy of the original
March 1998 issue #92 from Circuit Cellar. Assuming they even have a copy of an article
that old.

The code would mean very little to you if you're only familiar with BASIC since it was all in
Intel 8749 assembler using the very old Intel ISIS assembler. It was similar to standard 8051
instructions with a few differences due to the old 8749 architecture.

It would hardly be worth buying a copy of that old article if you're only using PICs, and the
schematic for the LDR sensor circuit was essentially the same as what you already have.

Edit: I think Elektor or some other magazine just bought-out Circuit Cellar, so maybe they
now have all rights to old articles? Not sure, but I know Circuit Cellar was bougth-out!

It just turned on/off two very bright LEDs for the headlights. It was a cool project, but
way outdated for now.

The neat part about the robot was it had push-button switches that allowed you to enter
the time to move in certain directions. If you messed it up, you just re-programmed it to
follow a course for specific time periods in fwd, rvs, back, left, right, etc. It didn't have any
sensors to detect obstacles since it was designed as a game - where you would compete
against other users to program the bot to navigate different courses.

It had 2 7-segment LEDs to view program entries. It was really simple, but a ton of fun at
parties. And it was my first article ever published in a major magazine.

Edit: I think Elektor bought Circuit Cellar, so they may now own the rights for old articles?

Dennis
- 18th February 2010, 00:40
Bruce ...

So the robot could navigate a maze if programed correctly and if the maze lights went off or if there weren't lights is would provide headlights ?

That would be pretty cool for caves and for video cameras and cameras too.
The LDR circuit could also give older cars the ability to provide auto-headlights.

Now I'm wondering how to adapt the circuit to allow for light readings because right now the circuit (PIC and LDR) don't really know the difference between darkness and a cloudy/rainy day.
So a possible change here could be to add a humidity/rain sensor and with the right logic and program, this circuit would ,for example, know when to switch a sprinkler system off because it is raining!

Kind regards

Dennis

Bruce
- 18th February 2010, 00:58
Yeah - it was pretty simple stuff. You entered the number of seconds for the robot to move
in fwd, rvs, left, rght, or backwards to navigate a course. The headlights just turned on or
off based on light levels. Nothing fancy. It had zero sensors except for the LDR.

The average person had to re-program it around 4 times to make it through most simple
courses, but it was tons of fun. You could do the same thing with around 50 lines of PBP
code on a PIC. It was several hundred lines of 8749 assembler. Boy have times changed.

Bruce
- 18th February 2010, 04:51
I had to really DIG to find this code. Here's the original firmware for the Micro-Bot with the old Intel 8749 controller. If this doesn't make you appreciate PBP - I just couldn't imagine what would..;)


; " Micro-Bot "
; Intel 8749H Micro Program For Programmable Mobile Robot

org 0 ; Start at 0.
sel rb0 ; Select register bank 0
mov r0,#18h ; Set DIRECTION ram location pointer.
mov r1,#19h ; Set TIME ram location pointer.

begin: mov a,#0ffh ; Load clear display bits
outl bus,a ; Clear Display.
mov a,#0f0h ; Bits to Halt all motors ( CLR P1.0 )
outl p1,a ; Halt Motors.
clr a ; Clear Accumulator.
in a,p2 ; Get user keyPad input.
cpl a ; Invert keypad entry 0 = 1.
jb0 fwd ; If Acc Bit 0 = 1 goto fwd
jb1 rvs ; If Acc Bit 1 = 1 goto rvs
jb2 left ; If Acc Bit 2 = 1 goto left
jb3 right ; If Acc Bit 3 = 1 goto right
jb4 clear ; If Acc Bit 4 = 1 goto clear / clear ram
jb5 run ; If Acc Bit 7 = 1 goto run / execute pgm
jb6 time ; If Acc Bit 6 = 1 goto time / set time
jb7 pause ; Pause / Stop routine.
jmp begin ; Recycle until Keypress detected.

clear: mov r0,#18h ; TIME + DIRECTION Ram Clearing routine.
mov r3,#68h ; 18H = Ram location #24d
mov a,#0 ; Zero's for ram locations.

incrt: mov @r0,a ;
inc r0 ;
djnz r3,incrt ; Loop until all ram locations
mov r0,#18h ; have been cleared, then goto begin.
jmp begin ;

fwd: mov @r0,#0f1h ; Move to the address indicated in R0
inc r0 ; the output bits for FORWARD motion
inc r0 ; then increment R0 to next available
mov a,#1 ; direction ram location.
outl bus,a ; Output a # 1 to display

fwd1: jt0 $ ; Loop here until the T0 input = 0
clr a ; 0 indicates user pressed ENTER Key.
jmp begin ; Goto routine BEGIN, wait for more input.

rvs: mov @r0,#0f7h ;
inc r0 ; Same as FWD routine for REVERSE direction.
inc r0 ;
mov a,#2 ; Load # 2 into ACC.
outl bus,a ; Output # 2 to display.

rvs1: jt0 $ ; Stay here until user presses enter key.
clr a ; Clear ACC.
jmp begin ; Go wait for input.

left: mov @r0,#0f5h ; Left Direction.
inc r0 ; DITTO.
inc r0 ;
mov a,#3
outl bus,a

left1: jt0 $ ; DITTO.
clr a
jmp begin

right: mov @r0,#0f3h ;
inc r0 ; DITTO.
inc r0 ;
mov a,#4 ; Load # 4
outl bus,a ; Display # 4

right1: jt0 $ ; DITTO.
clr a
jmp begin

pause: mov @r0,#0f0h ; Output bits to stop motors
inc r0
inc r0
mov a,#00 ; Show 0's on display for Pause indication.
outl bus,a

pause1: jt0 $ ; DITTO.
clr a ;
jmp begin

run: mov r0,#18h ; Load DIRECTION Ram address.
mov r1,#19h ; Load TIME Ram address.

run1: mov a,@r0 ; Move DIRECTION bits to ACC.
jz begin ; If ACC = 0 ( END RUN ) goto begin.
outl p1,a ; Output DIRECTION bits to motors on P1.
inc r0 ; Increment DIRECTION ram address
inc r0 ; to next DIRECTION location.
call speed ; Go get time to proceed in selected
jmp run1 ; direction, then return if finished.

speed: clr a ; Start here / Clear Acc.
mov a,@r1 ; Get selected TIME bits from ram.
call timer ; Goto Routine for time delay.
inc r1 ; Increment too next TIME ram address.
inc r1 ;
ret ; Return to calling routine.

time: inc @r1 ; Make sure r1 isnt = 0 at first, and
mov a,@r1 ; then increment for next numbers.
add a,#display ; Add Lookup table address to ACC.
movp a,@a ; Move page to A addressed by A.
outl bus,a ; Output the selected TIME to the display.
call delay ; Delay between display digit updates.
jz reload ; If A=0 goto subroutine Reload, else continue.
jnt0 done ; If enter key pressed goto done.
jt0 time ; If enter key not pressed recycle
; And keep updating the display.
reload: mov @r1,#00H ; Reload TIME ram address with 00's
jmp time ; and start over from # 1.

done: inc r1 ; If user pressed ENTER we come here
inc r1 ; increment to next TIME ram location
jmp begin ; then go get more input.

delay: mov r5,#2 ; Routine to establish about .5 seconds
; between display updates.
delay1: djnz r5,delay2 ;
ret ;

delay2: mov r6,#0ffh ;

delay3: mov r7,#0ffh ;
djnz r7,$ ;
djnz r6,delay3 ;
jmp delay1 ;

timer: mov r7,#30 ; Timer routine for approx 1 second.
mov r6,#0ffh ;
dis tcnti ; Dissable Timer/Counter interupt.
add a,#1 ; Will cycle through until R5 = 0.
mov r5,a ; Move user selected TIME data to R5.

timer1: clr a ;
mov t,a ; 3.57 Mhz crystal must be used
strt t ; for this routine to be effective.
djnz r5,timer2 ; Decrement R5 then if not = 0 goto timer2.
stop tcnt ; Stop timer/counter.
ret ; Return to calling routine.

timer2: jtf timer3 ; Jump on timer overflow to timer3 routine.

timer3: djnz r6,timer2 ;
jmp timer4 ;

timer4: mov r6,#0ffh ;
djnz r7,timer2 ; Loop until R7 = 0
jmp timer1 ;

display: nop ; Define bytes for display.
db 1 ; 1 To 60 Seconds.
db 2 ;
db 3 ;
db 4 ;
db 5 ;
db 6 ;
db 7 ;
db 8 ;
db 9 ;
db 10h ;
db 11h ;
db 12h ;
db 13h ;
db 14h ;
db 15h ;
db 16h ; At 60 seconds the display will reset
db 17h ; To 00 and start counting again from
db 18h ; 1.
db 19h ;
db 20h ; More time may be added to the Code,
db 21h ; by user if needed.
db 22h ;
db 23h ;
db 24h ;
db 25h ;
db 26h ;
db 27h ;
db 28h ;
db 29h ;
db 30h ;
db 31h ;
db 32h ;
db 33h ;
db 34h ;
db 35h ;
db 36h ;
db 37h ;
db 38h ;
db 39h ;
db 40h ;
db 41h ;
db 42h ;
db 43h ;
db 44h ;
db 45h ;
db 46h ;
db 47h ;
db 48h ;
db 49h ;
db 50h ;
db 51h ;
db 52h ;
db 53h ;
db 54h ;
db 55h ;
db 56h ;
db 57h ;
db 58h ;
db 59h ;
db 60h ; Output a number 60 to display
db 0 ; If count over 60 seconds start over at 0.
End ; That's All Folk's
Yikes...;o)

Dennis
- 18th February 2010, 17:31
@Bruce

That sure is a lot of coding for the task described.
And the display label sure is a lot too ! Quite a lot of repitition to get the display refreshed hey ?
What kinf of display was it ?

Kind regards

Dennis

Bruce
- 18th February 2010, 22:33
That sure is a lot of coding for the task described.
And the display label sure is a lot too ! Quite a lot of repitition to get the display refreshed hey ?
Yes. There's a big difference in doing everything in assembler VS using PBP.


What kinf of display was it ?
Just a plain old 2-digit 7-segment type.