Introduction: Dimming Illuminator- for Bedside Clocks Etc.
This unit came into being due to my wife complaining that she couldn't see the bedroom clock when the bedroom was in the dark , and she didn't want to turn the lights on to wake me. My wife didn't want a blinding light on the clock, just enough light to be able to read the time, regardless of the ambient light!
Our bedroom has a large window facing East that is almost always unshuttered, so that the bedroom light is constantly varying during the evening and morning hours. This gave me the notion that any clock illumination should be inversely proportional to the illumination within the bedroom.
This led to creation of the following simple unit, comprising a double row of 4 high brightness white LEDs, whose brightness is controlled by a PIC processor via the input from a photo diode.
The PIC was chosen as the control, as it contains an ADC input for sensing the photo diode, and a PWM channel for light intensity control of the LEDS. This unit satifactorally controls the clock illumination to the desired level.
The unit is simple to build and may have many other uses where a light source needs to be inversely proportional to the ambient light, for instance an illumination source for car instruments.
Step 1: Components List
1 off Printed circuit board, or stripboard if you do it the simple way.
1 off power supply 15 to 18 volts AC or DC.
8 off high brightness white LEDS 5mm ( or as you wish) Led 1 - 8
1 off GP Photo diode Led 9
1 off PIC 16F684 Micro. IC1
1 Off 1 Amp bridge rectifier.
1 off 7812 12Volt regulator. IC2
1 off 78l05 5 Vlot regulator. IC3
1 off 100 uF 25 VW electrolytic capacitor.
3 off 0.01 capacitors (any small sort will suffice)
1 off 470R 1/8thw resistor R5
1 off 470K 1/8thw resistor R4
1 off 1M 1/8thw resistor R3
2 off 1R 1/8thw resistor R1-2
Wire and solder as required.
Step 2: Circuit Board
If you are using stripboard then you will need to decide your own layout !
If you wish to make your own printed circuit board then please download the actual files in EAGLE format, or use the attached picture and process it yourself ie. copy it and use whatever pcb method you normally use to manufacture it.
If you are stuck without the facilities to make the board then as a last resort email me and I will see if I can provide you with a PCB (this is dependant on the number of requests I have for the PCBs!).
Attachments
Step 3: Components and PIC Programming
The components are all readily available , and should not be a problem to obtain.
Should you wish to order the PIC from me, then please request by Email and I will reply with the cost of shipping a pre-programmed PIC.
For you to self programme your own PIC 16F684 the HEX file is here available.
Carefully insert and mount all the components (following the component layout here), start with the low level components such as resistors first. Solder and trim the component legs.
Take care that the components are correctly orientated or components will be damaged. Note the LEDS have a flat side (the cathode!). The PIC should be ideally be mounted in a Dil socket and be sure that it is correctly mounted with the notch at the correct end as the layout picture. Note the polarity markings on the bridge rectifier and the Electrolytic capacitor! double check your component assembly and also the printed circuit board (for bridges/shorts or open circuits or properly soldered joints), before applying power. The circuit and PIC have been proved and tested, so of it fails to work as expected the fault is with the construction or a failed component, the most likely being that a fault exists on the copper side of the PCB, DOUBLE CHECK EVERYTHING (A visual check is the most important check you can make before any other!).
Attachments
Step 4: Testing
Your assembly should now be ready for power up and testing.
Connect the power source to the board (15-to-18 Volts DC or AC) and expose the photo resistor to a normal bright light, the output LEDS should light up full power (Don't look directly at them, it can hurt your eyes). Next shadow the photo diode with your hand or better still with a piece of black tubing, and the output light should reduce to a very low light. If this test proves OK then you have succeeded, otherwise you need to go back to the previous section and go through the fault seeking order again.
OK your unit works, now its up to you how you use it, for my application, I mounted the board some 1 metre away from the Bedroom clock so that the clock face was evenly illuminated, and it functions very well. If you have other applications you can of course move the Photo diode away from the board via a wired connection and mount it a position better suited for your application.
18 Comments
13 years ago on Introduction
Hey brianpxbd,
this is such a great idea that I decided to make this as my first instructable at all. The clock I already bought, but I would like to illuminate the clock from each of the 12 numbers each with one LED. Is your circuid board design able to also serve 4 LEDs more (two more on each line) THX!
13 years ago on Introduction
Hi all, please note my website is changed tohttp://picdesignhouse.webplus.net/index.html and many thanks for all your interest.
14 years ago on Introduction
Can you provide a copy of the program in assembly or C?
Reply 14 years ago on Introduction
here it is in assembly:
; Assembly code generated by mikroVirtualMachine - V. 5.0.0.3
; Date/Time: 09/02/2009 20:47:26
; Info: http://www.mikroe.com
; ADDRESS OPCODE ASM
; ----------------------------------------------
$0000 $28B0 GOTO _main
$00D5 $ _delay_22us:
;delays.pbas,17 :: sub procedure Delay_22us()
;delays.pbas,18 :: Delay_us(22)
$00D5 $3024 MOVLW 36
$00D6 $1303 BCF STATUS, RP1
$00D7 $1283 BCF STATUS, RP0
$00D8 $00FA MOVWF STACK_10
$00D9 $0BFA DECFSZ STACK_10, F
$00DA $28D9 GOTO $-1
$00DB $0000 NOP
$00DC $ delays_L_3:
$00DC $0008 RETURN
$0085 $ _mul_16x16_u:
$0085 $1303 BCF STATUS, RP1
$0086 $1283 BCF STATUS, RP0
;math.ppas,42 ::
;math.ppas,44 ::
$0087 $01FB CLRF STACK_11
;math.ppas,45 ::
$0088 $01FA CLRF STACK_10
;math.ppas,46 ::
$0089 $01F9 CLRF STACK_9
;math.ppas,47 ::
$008A $3080 MOVLW 128
;math.ppas,48 ::
$008B $00F8 MOVWF STACK_8
;math.ppas,49 ::
$008C $0CF1 RRF STACK_1, F
;math.ppas,50 ::
$008D $0CF0 RRF STACK_0, F
;math.ppas,51 ::
$008E $1C03 BTFSS STATUS, C
;math.ppas,52 ::
$008F $2899 GOTO $+10
;math.ppas,53 ::
$0090 $0874 MOVF STACK_4, W
;math.ppas,54 ::
$0091 $07F9 ADDWF STACK_9, F
;math.ppas,55 ::
$0092 $0875 MOVF STACK_5, W
;math.ppas,56 ::
$0093 $1803 BTFSC STATUS, C
;math.ppas,57 ::
$0094 $0F75 INCFSZ STACK_5, W
;math.ppas,58 ::
$0095 $07FA ADDWF STACK_10, F
;math.ppas,59 ::
$0096 $1803 BTFSC STATUS, C
;math.ppas,60 ::
$0097 $0AFB INCF STACK_11, F
;math.ppas,61 ::
$0098 $1003 BCF STATUS, C
;math.ppas,62 ::
$0099 $1FF0 BTFSS STACK_0, 7
;math.ppas,63 ::
$009A $28A1 GOTO $+7
;math.ppas,64 ::
$009B $0874 MOVF STACK_4, W
;math.ppas,65 ::
$009C $07FA ADDWF STACK_10, F
;math.ppas,66 ::
$009D $0875 MOVF STACK_5, W
;math.ppas,67 ::
$009E $1803 BTFSC STATUS, C
;math.ppas,68 ::
$009F $0F75 INCFSZ STACK_5, W
;math.ppas,69 ::
$00A0 $07FB ADDWF STACK_11, F
;math.ppas,70 ::
$00A1 $0CFB RRF STACK_11, F
;math.ppas,71 ::
$00A2 $0CFA RRF STACK_10, F
;math.ppas,72 ::
$00A3 $0CF9 RRF STACK_9, F
;math.ppas,73 ::
$00A4 $0CF8 RRF STACK_8, F
;math.ppas,74 ::
$00A5 $1C03 BTFSS STATUS, C
;math.ppas,75 ::
$00A6 $288C GOTO $-26
;math.ppas,76 ::
$00A7 $087B MOVF STACK_11, W
;math.ppas,77 ::
$00A8 $00F3 MOVWF STACK_3
;math.ppas,78 ::
$00A9 $087A MOVF STACK_10, W
;math.ppas,79 ::
$00AA $00F2 MOVWF STACK_2
;math.ppas,80 ::
$00AB $0879 MOVF STACK_9, W
;math.ppas,81 ::
$00AC $00F1 MOVWF STACK_1
;math.ppas,82 ::
$00AD $0878 MOVF STACK_8, W
;math.ppas,83 ::
$00AE $00F0 MOVWF STACK_0
;math.ppas,84 ::
$00AF $ math_L_1:
;math.ppas,85 ::
$00AF $0008 RETURN
$00DD $ _pwm_start:
;PWM_c5.ppas,26 ::
;PWM_c5.ppas,27 ::
$00DD $1303 BCF STATUS, RP1
$00DE $1683 BSF STATUS, RP0
$00DF $1287 BCF TRISC, 5
;PWM_c5.ppas,28 ::
$00E0 $1283 BCF STATUS, RP0
$00E1 $1512 BSF T2CON, 2
;PWM_c5.ppas,29 ::
$00E2 $300C MOVLW 12
$00E3 $0495 IORWF CCP1CON, 1
$00E4 $ PWM_c5_L_2:
;PWM_c5.ppas,30 ::
$00E4 $0008 RETURN
$004C $ _adc_read:
;ADClib_A_B.ppas,12 ::
;ADClib_A_B.ppas,13 ::
$004C $3040 MOVLW 64
$004D $1303 BCF STATUS, RP1
$004E $1283 BCF STATUS, RP0
$004F $059F ANDWF ADCON0, 1
;ADClib_A_B.ppas,14 ::
$0050 $30F0 MOVLW 240
$0051 $1683 BSF STATUS, RP0
$0052 $049F IORWF ADCON1, 1
;ADClib_A_B.ppas,15 ::
$0053 $1283 BCF STATUS, RP0
$0054 $179F BSF ADCON0, 7
;ADClib_A_B.ppas,16 ::
$0055 $0822 MOVF FARG_ADC_read, 0
$0056 $00F0 MOVWF STACK_0
$0057 $0DF0 RLF STACK_0, 1
$0058 $1070 BCF STACK_0, 0
$0059 $0DF0 RLF STACK_0, 1
$005A $1070 BCF STACK_0, 0
$005B $0870 MOVF STACK_0, 0
$005C $049F IORWF ADCON0, 1
;ADClib_A_B.ppas,17 ::
$005D $141F BSF ADCON0, 0
;ADClib_A_B.ppas,18 ::
$005E $20D5 CALL _delay_22us
;ADClib_A_B.ppas,19 ::
$005F $149F BSF ADCON0, 1
;ADClib_A_B.ppas,20 ::
$0060 $ ADClib_A_B_L_2:
$0060 $081F MOVF ADCON0, 0
$0061 $00F2 MOVWF STACK_2
$0062 $3000 MOVLW 0
$0063 $18F2 BTFSC STACK_2, 1
$0064 $3001 MOVLW 1
$0065 $00F2 MOVWF STACK_2
$0066 $0872 MOVF STACK_2, 0
$0067 $3A01 XORLW 1
$0068 $1D03 BTFSS STATUS, Z
$0069 $286C GOTO ADClib_A_B_L_3
;ADClib_A_B.ppas,21 ::
$006A $0000 NOP
$006B $2860 GOTO ADClib_A_B_L_2
$006C $ ADClib_A_B_L_3:
;ADClib_A_B.ppas,22 ::
$006C $081E MOVF ADRESH, 0
$006D $00F2 MOVWF STACK_2
$006E $01F3 CLRF STACK_2+1
$006F $0872 MOVF STACK_2, 0
$0070 $00F3 MOVWF STACK_2+1
$0071 $01F2 CLRF STACK_2
$0072 $0872 MOVF STACK_2, 0
$0073 $00A3 MOVWF _adc_read_local_result
$0074 $0873 MOVF STACK_2+1, 0
$0075 $00A4 MOVWF _adc_read_local_result+1
;ADClib_A_B.ppas,23 ::
$0076 $1683 BSF STATUS, RP0
$0077 $081E MOVF ADRESL, 0
$0078 $0472 IORWF STACK_2, 0
$0079 $1283 BCF STATUS, RP0
$007A $00A3 MOVWF _adc_read_local_result
$007B $0873 MOVF STACK_2+1, 0
$007C $00A4 MOVWF _adc_read_local_result+1
$007D $3000 MOVLW 0
$007E $04A4 IORWF _adc_read_local_result+1, 1
;ADClib_A_B.ppas,24 ::
$007F $101F BCF ADCON0, 0
$0080 $ ADClib_A_B_L_0:
;ADClib_A_B.ppas,25 ::
$0080 $0823 MOVF _adc_read_local_result, 0
$0081 $00F0 MOVWF STACK_0
$0082 $0824 MOVF _adc_read_local_result+1, 0
$0083 $00F1 MOVWF STACK_0+1
$0084 $0008 RETURN
$0004 $ _pwm_change_duty:
;PWM_c5.ppas,17 ::
;PWM_c5.ppas,18 ::
$0004 $1303 BCF STATUS, RP1
$0005 $1683 BSF STATUS, RP0
$0006 $0812 MOVF PR2, 0
$0007 $00F0 MOVWF STACK_0
$0008 $01F1 CLRF STACK_0+1
$0009 $0870 MOVF STACK_0, 0
$000A $3F01 ADDLW 1
$000B $00F4 MOVWF STACK_4
$000C $3000 MOVLW 0
$000D $1803 BTFSC STATUS, C
$000E $3F01 ADDLW 1
$000F $0771 ADDWF STACK_0+1, 0
$0010 $00F5 MOVWF STACK_4+1
$0011 $1283 BCF STATUS, RP0
$0012 $0822 MOVF FARG_PWM_Change_Duty, 0
$0013 $00F0 MOVWF STACK_0
$0014 $01F1 CLRF STACK_0+1
$0015 $2085 CALL _mul_16x16_u
$0016 $3006 MOVLW 6
$0017 $00F2 MOVWF STACK_2
$0018 $0870 MOVF STACK_0, 0
$0019 $00F8 MOVWF STACK_8
$001A $0871 MOVF STACK_0+1, 0
$001B $00F9 MOVWF STACK_8+1
$001C $0872 MOVF STACK_2, 0
$001D $ L_PWM_Change_Duty_0:
$001D $1903 BTFSC STATUS, Z
$001E $2824 GOTO L_PWM_Change_Duty_1
$001F $0CF9 RRF STACK_8+1, 1
$0020 $0CF8 RRF STACK_8, 1
$0021 $13F9 BCF STACK_8+1, 7
$0022 $3FFF ADDLW 255
$0023 $281D GOTO L_PWM_Change_Duty_0
$0024 $ L_PWM_Change_Duty_1:
;PWM_c5.ppas,19 ::
$0024 $0878 MOVF STACK_8, 0
$0025 $00F0 MOVWF STACK_0
$0026 $0879 MOVF STACK_8+1, 0
$0027 $00F1 MOVWF STACK_0+1
$0028 $0DF0 RLF STACK_0, 1
$0029 $0DF1 RLF STACK_0+1, 1
$002A $1070 BCF STACK_0, 0
$002B $0DF0 RLF STACK_0, 1
$002C $0DF1 RLF STACK_0+1, 1
$002D $1070 BCF STACK_0, 0
$002E $0DF0 RLF STACK_0, 1
$002F $0DF1 RLF STACK_0+1, 1
$0030 $1070 BCF STACK_0, 0
$0031 $0DF0 RLF STACK_0, 1
$0032 $0DF1 RLF STACK_0+1, 1
$0033 $1070 BCF STACK_0, 0
$0034 $3030 MOVLW 48
$0035 $0570 ANDWF STACK_0, 0
$0036 $00F6 MOVWF STACK_6
$0037 $0871 MOVF STACK_0+1, 0
$0038 $00F7 MOVWF STACK_6+1
$0039 $3000 MOVLW 0
$003A $05F7 ANDWF STACK_6+1, 1
;PWM_c5.ppas,20 ::
$003B $0878 MOVF STACK_8, 0
$003C $00F0 MOVWF STACK_0
$003D $0879 MOVF STACK_8+1, 0
$003E $00F1 MOVWF STACK_0+1
$003F $0CF1 RRF STACK_0+1, 1
$0040 $0CF0 RRF STACK_0, 1
$0041 $13F1 BCF STACK_0+1, 7
$0042 $0CF1 RRF STACK_0+1, 1
$0043 $0CF0 RRF STACK_0, 1
$0044 $13F1 BCF STACK_0+1, 7
$0045 $0870 MOVF STACK_0, 0
$0046 $0093 MOVWF CCPR1L
;PWM_c5.ppas,21 ::
$0047 $300F MOVLW 15
$0048 $0595 ANDWF CCP1CON, 1
;PWM_c5.ppas,22 ::
$0049 $0876 MOVF STACK_6, 0
$004A $0495 IORWF CCP1CON, 1
$004B $ PWM_c5_L_1:
;PWM_c5.ppas,23 ::
$004B $0008 RETURN
$00E5 $ _pwm_init:
;PWM_c5.ppas,8 ::
;PWM_c5.ppas,9 ::
$00E5 $1303 BCF STATUS, RP1
$00E6 $1283 BCF STATUS, RP0
$00E7 $0193 CLRF CCPR1L, 1
;PWM_c5.ppas,10 ::
$00E8 $1215 BCF CCP1CON, 4
;PWM_c5.ppas,11 ::
$00E9 $1295 BCF CCP1CON, 5
$00EA $ PWM_c5_L_0:
;PWM_c5.ppas,12 ::
$00EA $0008 RETURN
$00B0 $ _main:
;ledlightcontrol for clock.pbas,6 :: main:
$00B0 $ _main_main:
;ledlightcontrol for clock.pbas,9 :: porta =%00000001 rem porta 0 is adc input
$00B0 $3001 MOVLW 1
$00B1 $1303 BCF STATUS, RP1
$00B2 $1283 BCF STATUS, RP0
$00B3 $0085 MOVWF PORTA
;ledlightcontrol for clock.pbas,10 :: cmcon0=%00000111 rem disable comparitors
$00B4 $3007 MOVLW 7
$00B5 $0099 MOVWF CMCON0
;ledlightcontrol for clock.pbas,11 :: PORTC = $00 ' Initialize PORTC digital outputs
$00B6 $0187 CLRF PORTC, 1
;ledlightcontrol for clock.pbas,12 :: Pwm_Init(5000) ' Initialize PWM module, freq = 1.5kHz.
$00B7 $1012 BCF T2CON, T2CKPS0
$00B8 $1092 BCF T2CON, T2CKPS1
$00B9 $1412 BSF T2CON, T2CKPS0
$00BA $30F9 MOVLW 249
$00BB $1683 BSF STATUS, RP0
$00BC $0092 MOVWF PR2
$00BD $20E5 CALL _pwm_init
;ledlightcontrol for clock.pbas,13 :: Pwm_Start ' Start PWM
$00BE $20DD CALL _pwm_start
;ledlightcontrol for clock.pbas,15 :: while true
$00BF $ ledlightcontrol for clock_L_2:
;ledlightcontrol for clock.pbas,16 :: j = adc_read(0)
$00BF $01A2 CLRF FARG_ADC_read, 1
$00C0 $204C CALL _adc_read
$00C1 $0870 MOVF STACK_0, 0
$00C2 $00A0 MOVWF _j
$00C3 $0871 MOVF STACK_0+1, 0
$00C4 $00A1 MOVWF _j+1
;ledlightcontrol for clock.pbas,17 :: if j>255 then j=255
$00C5 $0871 MOVF STACK_0+1, 0
$00C6 $3C00 SUBLW 0
$00C7 $1D03 BTFSS STATUS, Z
$00C8 $28CB GOTO L_main_0
$00C9 $0870 MOVF STACK_0, 0
$00CA $3CFF SUBLW 255
$00CB $ L_main_0:
$00CB $1803 BTFSC STATUS, C
$00CC $28D0 GOTO ledlightcontrol for clock_L_7
$00CD $ ledlightcontrol for clock_L_6:
$00CD $30FF MOVLW 255
$00CE $00A0 MOVWF _j
$00CF $01A1 CLRF _j+1
$00D0 $ ledlightcontrol for clock_L_7:
;ledlightcontrol for clock.pbas,18 :: end if
$00D0 $ ledlightcontrol for clock_L_8:
;ledlightcontrol for clock.pbas,22 :: Pwm_Change_Duty(j) ' Change duty ratio
$00D0 $0820 MOVF _j, 0
$00D1 $00A2 MOVWF FARG_PWM_Change_Duty
$00D2 $2004 CALL _pwm_change_duty
$00D3 $28BF GOTO ledlightcontrol for clock_L_2
;ledlightcontrol for clock.pbas,24 :: wend
$00D4 $28D4 GOTO $
Reply 14 years ago on Introduction
Thank you very much for the assembly version. Appreciate it.
Reply 14 years ago on Introduction
Its much shorter in basic. If you want a copy of the basic script I can let you have that as well:
Reply 14 years ago on Introduction
its much shorter in Basic, if you want a copy of the basic script I can post that for you.
14 years ago on Introduction
url link doesn't work
14 years ago on Step 4
Just a quick question when you first power it on shouldnt the LEDS be off? and only turn on when you shield it? the first paragraph made it sound the other way around Great project though I like it
Reply 14 years ago on Step 4
no sorry, that's the opposite of the desired effect. The idea is that the illumination is just enough to see the clock in the dark and as the light increases, so does the illumination. In other words the light shining on the clock is always a little brighter than the ambient light. I know that sounds crazy, because normally one does the opposite!
Reply 14 years ago on Step 4
No i agree. I wasnt sure which you were using in the first step you said it was inversely proportional to the ambient light . I think having light proportonal to the ambient light is a better idea. How ever can you incorporate limits into it? so that unless turned off in complete darkness there will still be some illumination , and if the ambient light becomes great enough (ie a sunlit bedroom) the LEDs fade to off as well as they wont be needed. sort of maximum and minimums
Reply 14 years ago on Step 4
OK, Good point about my inverse proportionality Hi Hi, I should have considered my wording a little more. Your idea of limiting both ends of the lighting range is fine. The lower end (Darkness) is in fact limited, however in my application I saw now reason to limit the top end as in very bright light one can ignore the clock lighting, and also the small power consumed by the unit is hardly a problem. Perhaps if someone has a reason for a battery powered unit I would incorporate the high (Bright light) lighting turn off function.Thanks for your comments, Brian
14 years ago on Step 4
No i agree. I wasnt sure which you were using in the first step you said it was inversely proportional to the ambient light . I think having light proportonal to the ambient light is a better idea. How ever can you incorporate limits into it? so that unless turned off in complete darkness there will still be some illumination , and if the ambient light becomes great enough (ie a sunlit bedroom) the LEDs fade to off as well as they wont be needed. sort of maximum and minimums
15 years ago on Introduction
Such complexity! One pines for the not-so-good old days when the problem would be solved with a dash of radium paint on the dial. "Oh! those pesky labour standards laws. How they strive to thwart the mighty engine of Market Capitalism."
Reply 15 years ago on Introduction
Radium is a good Idea again, but I think we have enough cancer in our radioactive world!
15 years ago on Introduction
Why not put a switch, a capacitor, an LED and a resistor together like this; resistor connected to LED, LED + resistor connected in parallel to the capacitor capacitor connected to switch, switch connected to power supply, (series connection) Your project is a little bit too complex just for the purpose of illuminating your clock
Reply 15 years ago on Introduction
Thank you for your comment, Sorry you have missed the point! Your suggestions is too simple to meet the requirements of accurate tracking of the light changes. The function is to keep the light at a minimum level that can still allow one to read the clock face in all ranges of low light ambient. You can only slightly alter the brightness range of an LED by a variable voltage (Ie. your suggestion of a capacitor and resistor), if one wishes to have a full range of light to dark or the reverse, one must fool the eye by switching the lED on and off at a variable length of on/off ie. PWM, (pulse width modulation). Naturally, one can achieve this by other methods, but the way it is done with the above circuit is low cost and simple. There is a period in the early hours of the morning and late in the evening where the ambient light changes very gradually, and the above circuitry compensates very accurately for this
Reply 15 years ago on Introduction
oh.... i see For that purpose, it is pretty simple, i though you just wanted the clock illuminated, in no special way