Full Version : Door Chime Privacy Sentry
avr >>HOME & TIME & TEMPERATURE PROJECTS >>Door Chime Privacy Sentry


Admin5- 04-27-2006
Cappel's Door Chime Privacy Sentry

An ATtiny12 controller as a timer and some switching circuitry turns the doorbell off for 10 hours at the same time each day.


The string of resistors across the top of the board are series connected to make a 728 Ohm 2 watt resistor. The slide switch is used to switch the circuit between the test and operate modes and the large round component to the left of the switch is the 0.033 farad capacitor.

Overview

This is a resettable timer and the to circuitry connect it to an 18V to 24V doorbell circuit.

My home is in a nice neighborhood. The front yards are well kept, it is quiet, and people wave when you go down the street. The park nearby is kept clean and green and children there play nicely with each other. Behind this idillic appearance the neighborhood harbors a dark side. Door-to-door solicitors, who ring the doorbell several times a week selling everything from insurance to religion. This isn't a real big problem for me, but because of my wife's schedule, she frequently sleeps until late in the morning. After being startled awake by a doorbell, she can't go back to sleep and suffers because of it the rest of the day. Our first solution was a politely worded note on the door asking people to kindly go away, but that didn't work at all. Disconnecting the door bell wire at the transformer helped some, but that meant that we didn't know when someone we wanted to see was at the door, or when the UPS delivery person dropped something off, leaving switching the bell circuit on and off as the only practical solution.

Mounting a toggle switch on the doorbell would be a simple enough solution, but with the availability of suitable microcontrollers, why not automate the switching? That would eliminate the problems associated with forgetting to switch the bell off before going to bed or back on after waking up.

After a couple of days of turning the problem over in my mind, I decided to modify the ATtiny12 real time clock-calendar firmware I had written previously, to make a resettable timer that would switch the doorbell off on a 24 hour cycle. The device described here does just that. The circuit connects to the doorbell circuit - taking power from the 18 VAC from the doorbell transformer and switching power to the doorbell circuit most of the day. The user interface is a pushbutton, a toggle switch, and two LEDs. One LED - the green one -blinks at 1 Hz, just to give me some comfort that the circuit is working. The amber LED glows whenever the doorbell is disabled.

To set the timer, you just push the button momentarily, and when its released, the amber LED will come on and the doorbell circuit is disabled (the door bell button doesn't work) for a 10 hour period. At the end of the 10 hour period, the amber LED goes off and the doorbell is enabled. 24 Hours after the button was last pushed, the amber LED comes back on and the door chime circuit is disabled again. this cycle repeats every 24 hours, and because its timing is set by a crystal oscillator, it should be able to go for months or years without needing to be reset.

The toggle switch allows the timer to be bypassed in case we want to have the doorbell operating 24 hours a day or in the unlikely event of a circuit failure.

Simple as it is, I have to say that this is one of the more useful projects for the home that I've built.

Link to Site: http://cappels.org/dproj/doorchim/doorchime.html


Admin5- 04-27-2006
CODE

;Copyright 2004 by the Dick Cappels. projects(at)cappels.org www.projects.cappels.org
;Copy and paste this into an assembler file.

.include "tn12def.inc";Note that no path is given for this file.

;DOOR BELL TIMER.
;Description: Keeps Portb B bit 1 low for the first 10 hours of each day. Port B bit 0 is a 1 Hz
;pulse to connect to an indicator LED or other monitoring device to indicate that interrupts are
;occuring - mainly to show that oscillator is working because you can't probe it without stopping it.
;Port B bit 2 is low for the first 30 seconds of each minute and high the rest of the time. This is
;for test purposes.

;This runs on an ATtiny12 with a 32768 Hz crystal connected between pins 2 and 3. No phase shift capacitors
;or other components should be connected to these pins.


;When Programming the chip:
;1. Select the Low Freuqency Crystal oscillator 67ms + 32k clock (CKSEL = 1000)


;VERSIONS
; bt040409D Most recent version.

;Define I/O
.equ testpin  = 2;Port B bit 2 is the test output - low for first 10 seconds.
.equ bellpin  = 1;Port B bit 1 is the bell relay driver -low for first 10 hours.
.equ winkled  = 0;Port B bit 0 winks at 1 Hz, changed during interrupt time.

;Contreg (Control Register) bit descriptions  and associated constants

.equ readclockinh =  1;if 1, inhibits clock from being written to user buffer. Autocleared by write routine
.equ readclockinhflag = 2;value ored with contreg to set flag
.equ readclockinhmask=$FD;used to clear the falg when task completed
.equ writeclock =  2;*if 1, commands user buffer to be written to clock. Autocleared by write routine
.equ writelcockorflag=  4;value ored with contreg to set flag.
.equ writeclockmask =$FB;used to clear the flag when task completed
.equ disableclock =  3;if 1 disables clock and alarm maintenance during interrupt
.equ disableclockorflag=8;value ored with contreg to set flag
.equ disableclockmask=$F7;used to clear flag by anding with contreg

;intflags Internal Flags register bit assignments and associated constants

.equ extintmask =$FE;used to clear flag by anding  with contreg
.equ rbtorflag =  8;used to set bit

;.equ  almaskinitial  =$FF;Defaul value of alarm mask loaded at startup

.def rectimer=  r0;number of t0 interrupts within on second (used to filter attn line)
.def sregtemp=  r1;temporary storage of status register during interrupt time
.def uyear =  r5;user accesible year user register 2
.def umonth =  r6;user accessible month user register 3
.def uday =  r7;user accessible day
.def uhour =  r8;user accessible hour
.def uminute =  r9;user accessible minute
.def usecond = r10;user accessible second
.def ayear = r11;alarm year (user accessible)
.def amonth = r12;alarm month (user accessible)
.def aday = r13;alarm day (user accessible)
.def ahour = r14;alarm hour (user accessible)
.def aminute = r15;alarm minute (user accessible)
.def asecond = r16;alarm second (user accessible)
.def contreg = r17;device control register, user register F
;/////end of user accessible registers
.def intflags= r18;internal flags - not user accessible
.def second  = r19;second
.def minute  = r20;minute
.def hour = r21;hour
.def day = r22;day
.def month   = r23;month
.def year = r24;year
.def temp  = r25;scratch
.def tempi   = r26;scratch for use during interrupt


.ORG $0000
rjmp reset
reti   ;external interrupt handler
reti   ;pin change interrupt -return
rjmp tovflo  ;timer overflow interrupt handler

reset:;SET EVERYTING UP TO RUN.
ldi contreg,$00 ;Preload conreg flags
ldi temp,$80
out ACSR,temp
ldi temp,$03
out TCCR0,temp ;Set timer prescaler
in intflags,eedr ;Get the data into temp
andi intflags,$78  ;MAKE NORMAL STATE "BAILED", only bits 4,5,6 of EEPROM
clr second
clr minute
clr hour
clr day
clr month
clr year
ldi temp,$FF ;Pre-load second in user register with $FF so it can
mov usecond,temp ;be determined if the reigster was read before
   ;values are written by clock
ldi asecond,$FF ;Similarly, put $FF into the alarm seconds
   ;so alarm cab't fire until initialized.
clr tempi  ;presets 500 millisecond counter
ldi temp,0  ;preload timer counter
out TCNT0,temp
ldi temp,$02 ;enable timer overflow interrupts
out TIMSK,temp
ldi temp,$FF ;load data direction value for PORTB
out  DDRB,temp ;no pullups on B0 and B1 ***
andi intflags,$78  ;MAKE NORMAL STATE "BAILED", only bits 4,5,6 of EEPROM


 
main: ;Main loop - do this after each awakening from sleep. Wakes from sleep 2 times per
;second by timer interrupt.

 ;Set state of testpin according to number of seconds elapsed within current minute.
mov temp,usecond
cpi temp,30
brpl havetest    
cbi PORTB,testpin;Come here if test pin is to be off (low). Set test pin low.
rjmp notest
havetest:
sbi PORTB,testpin;Come here if test pin is to be on (high).Make test pin high.
notest:

 ;Set state of bellpin according to number of hours elapsed within current day.
mov temp,uhour
cpi temp,10
brpl havebell    
cbi PORTB,bellpin;Come here if bell pin is to be off (low). Set bell pin low.
rjmp nobell
havebell:
sbi PORTB,bellpin;Come here if bell is to be on (high. Make bell pin high.
nobell:
   ;Go to sleep.
ldi temp,$22 ;enable sleep and set T0 to respond to falling edge
out MCUCR,temp ;enable sleep mode
ldi temp,$40 ;enable external interrupt 0
out GIMSK,temp  
sei   ;assure interrupts are enabled
   sleep                          ;good night. Wait for the attention line to go low (interrupt 0)
 rjmp main
 
;/////////////////////////////////////////////////////////////////////////////////
;///////////////CODE BELOW IS ONLY TIMER INTERRUPT AND CLOCK CODE/////////////////
;/////////////////////////////////////////////////////////////////////////////////
;///////////////TIMER OVERFLOW SERVICE//////////////////
tovflo:    ;twice per second timer interrupt (assumes 32678 hz crystal)    
in sregtemp,SREG ;save the status register contents
tst tempi  ;Since the interrupt is twice a second, tempi will be used
brne even500ms ;to divide by two
cbi PORTB,winkled ;Set wink LED output low.
ldi tempi,1
rjmp lateExit
even500ms:
sbi PORTB,winkled ;Set wink LED output high.  
tst rectimer
breq notimeout
dec rectimer
brne notimeout
ori intflags,rbtorflag
andi intflags,$7F ;**** possible savings of one word - is this redundant with flag clear in bail?
notimeout:

;//////write to clock//////    
sbrs contreg,writeclock;write user time registers to clock
rjmp nowrite        
mov second,usecond
mov minute,uminute
mov hour,uhour
mov day,uday
mov month,umonth
mov year,uyear
andi contreg,writeclockmask ;clear write flag
nowrite:

;/////begin clock/calendar maintenance/////
   ;Year counter runs to 255 years. Leap test year assumes
   ;that the year is a leap year if bits 0 and 1 are low.
   
sbrc contreg,disableclock;Skip clock/alarm maintenance if flag is set  
rjmp skipclocktohere    
inc second
cpi second,60  
breq dominute
rjmp doneclock
dominute:clr second
inc minute
cpi minute,60  
breq dohour
rjmp doneclock
dohour: clr minute
inc hour
cpi hour,24  
breq doday
rjmp doneclock
doday: clr hour  
inc day
cpi day,32  
breq domonth
cpi day,31  
brne check30
cpi month,4  
breq domonth
cpi month,6
breq domonth
cpi month,9
breq domonth
cpi month,11
breq domonth
check30:cpi month,2
brne doneclock
cpi day,30
breq domonth
cpi day,29
brne doneclock
mov tempi,year
andi tempi,$03
breq doneclock
domonth:ldi day,1
inc month
cpi month,13
brne doneclock
ldi month,1
inc year
doneclock:
;/////end clock/calendar maintenance/////


;//////read from clock to user registers//////
sbrc contreg,readclockinh;read from clock to user time registers
rjmp noread        
mov usecond,second
mov uminute,minute
mov uhour,hour
mov uday,day
mov umonth,month
mov uyear,year
noread:
skipclocktohere:  ;Just skipped the clock and alarm
doneint:
clr tempi
lateExit:
andi intflags,extintmask;clear ext interrupt counter **** should move to before lateExit
out SREG,sregtemp ;restore the status register contents
reti

;end of assembly souce listing

.exit


Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.