Bauplan Schaltplan Codeschloss für Atmel Tiny
Hier eine kleine Software für den ATMEL Tiny13, mit der sich die Tiny Experimentierplatine in ein kleines Codeschloss verwandeln lässt.

Link zur Experimentierplatine:

http://www.loetstelle.net/projekte/tinydil/tinydil.php

Normale Code-Schlösser haben meist ein numerisches Tastenfeld, um die Zahlenkombination einzugeben. Das hier vorgestellte Codeschloss hingegen verwendet nur einen einzigen Taster, um den Code einzugeben. Der Code besteht dabei aus Tastenimpulsen verschiedener Länge..

Der Code besteht aus Tastenimpulsen, die entweder "lange" oder "Kurz" sein können. Wurde die Kombination richtig eingegeben, wird ein Ausgang für ca 0.5s aktiviert, damit kann dann ein Türöffner etc betätigt werden..

Um einen eigenen Code einzugeben, muss der Onboard-Taster an PB3 während der Code-Eingabe gedrückt gehalten werden. Das bewirkt, dass die erkannte Tastenfolge im internen EEProm abgelegt wird und somit als neuer Code fungiert. Die Eingabe eines Codes wird dabei durch kurzes Aufblinken der Status-LED an PB3 angezeigt. .

Wurde der Code 3 mal falsch eingegeben, verweigert das Codeschloss für ca 10 Minuten das Aktivieren des Ausgangs. .

Die Schaltung ist sehr gut für Batteriebetrieb geeignet, da der Prozessor die meiste Zeit im Power Down Modus ist und nur wenige uA benötigt. Durch Drücken des Tasters wacht der Controller auf (Pin Change Intrrupt) und ist für die Eingabe eines Codes bereit, wobei der Prozessor dabei ebenfalls meistens im Sleep Modus verweilt. über den Watchdog-Timer erwacht der Controller ca alle 8 Sekunden und gibt einen kurzen "Blitz" mit der Status-LED aus, um die Funktionsbereitschaft anzuzeigen. .

Die Anzahl der benötigten Tastendrücke kann über den Parameter CODELENGTH eingestellt werden, je nachdem wie hoch das "Sicherheitsbedürfnis" des Anwenders ist. Da jeder Tastendruck und jeder Codeteil recht verschwenderisch in einem eigenen Byte abgelegt wird, kann die Codelänge maximal ca 55 Stellen betragen (Beim Tiny13, SRAM-Stack), was mehr als ausreichend sein sollte. .

Ich betreibe diese Schaltung als "verdeckten Türöffner", der mir schon einige male einen Anruf beim Schlüsseldienst und viel ärger erspart hat. Fast jeder kennt das Problem, wenn die Haustür ins Schloss fällt und der Schlüssel in der Wohnung liegt. Man bräuchte jemanden, der von Innen den Türöffner betätigt (Meine Wohnungstüre hat einen Türöffner eingebaut). Genau das kann diese Schaltung: .

über einen Optokoppler habe ich die Schaltung parallel zu meiner Türklingel (über 1 Widerstand , 1 Diode und 1 Kondensator, da meine Klingel mit Wechselspannung läuft..) angeschlossen. Normales Klingeln ignoriert das Codeschloss. Aber wenn das Klingeln mit der richtigen Impulsfolge erfolgt, wird kurz der Türöffner aktiviert, und Voila, Sesam öffne Dich. .

Eine relativ kurze Codelänge ist dabei für mich kein Sicherheitsrisiko, denn wenn ich meinen Schlüssel mal nicht in der Wohnung vegessen habe, sperre ich die Haustüre natürlich noch extra ab, wenn ich weggehe. .

Quellcode: (Klick hier für Download)

.include "tn13def.inc"


.def temp1 = r16
.def presscount = r17
.def rxptr = r18
.def dosleep = r19
.def pulseoutput = r20
.def temp2 = r21
.def temp3 = r22


.def pulsestatus = r23

.def wrongcount = r24
.def lockcount = r25
.def temp4 = r26


//PB BITs der Funktionespins
.equ OUTPUT = 1
.equ STATUS = 2

.equ TASTER_INTERN = 3

.equ TASTER_EXTERN = 4

//Wartezeit bei überschreiten der Fehlversuche
.equ LOCKTIME = 75 //bedeutet ca 75*8 Sekunden

.equ CODELENGTH = 5 //Die Schluessel-Länge, maximal RAM / EEprom Groesse- Stack)
.equ MAX_TRY = 3 //Anzahl der Fehlversuche


.org $0000
rjmp reset

.org WDTAddr
rjmp wdthandler

.org PCI0Addr
rjmp PCIHandler


.org OVF0addr
rjmp OVF0Handler


.org INT_VECTORS_SIZE*2

reset:

//Stack Pointer initialisieren
ldi temp1,low(ramend)
out spl,temp1

//Output und Status-Pins als Ausgang
ldi temp1,(1<<OUTPUT) | (1<<STATUS)
out ddrb,temp1

//Pullups für die Eingaenge anschalten
ldi temp1,0b00111111 ^ ((1<<OUTPUT) | (1<<STATUS))

out portb,temp1

//Timer 0 Interrupt An
ldi temp1,(1<<TOIE0)
out TIMSK0,temp1

//Prescaler sezten und Timer Starten
ldi temp1,0b00000101
out TCCR0B,temp1

//interne Zaehler zurücksetzen
clr presscount
clr rxptr
clr pulseoutput
clr pulsestatus
clr lockcount
clr wrongcount



// Pinchange Interrupt auf externem Taster aktivieren
ldi temp1,(1<<TASTER_EXTERN)
out PCMSK,temp1
ldi temp1,(1<<PCIE)
out GIMSK,temp1

//Semaphore für Sleep loeschen
clr dosleep

//Watchdog init
rcall initwdt


sei


endless:
tst dosleep
brne exec_sleep
//idle
ldi temp1,0b00100000
out MCUCR,temp1
sleep
rjmp endless


exec_sleep: cli
clr presscount
clr rxptr


sbi portb,STATUS

//Pulsieren , dabei wird auch die Sleep-Semaphore wieder geloescht.
delay:

inc dosleep
brne delay

cbi portb,STATUS

//Power Down Modus
ldi temp1,0b00110000
out MCUCR,temp1


sei
sleep
rjmp endless

OVF0Handler:
//Register und Temp1 sichern
in r1,sreg
push temp1
push yl
push yh


tst pulsestatus
breq testpulseout
dec pulsestatus
brne testpulseout
cbi portb,status


testpulseout:
tst pulseoutput
breq testbutton

dec pulseoutput
brne testbutton
cbi portb,OUTPUT

testbutton:

//prüfen, ob taster gedrückt
sbic pinb,TASTER_EXTERN
rjmp releasehandler

//maximal 10 Interrupt-Zyklen lang hochzählen
cpi presscount,$10
breq exitovf0
inc presscount
rjmp exitovf0

// Taster wurde losgelassen
releasehandler:

cpi presscount,$02
brsh valid

//zu kurz gedrückt / entprellung
clr presscount
rjmp exitovf0

valid: ldi temp1,$00
//wenn länger als 8 Zyklen gedrueckt, dann als LANG erkennen
cpi presscount,$05
brlo nolong

inc temp1

//Erkannten Tastendruck im SRAM speichern
nolong: clr presscount
ldi yl,low(rxbuf)
ldi yh,high(rxbuf)
add yl,rxptr
adc yh,presscount
st y,temp1
//Zeiger auf empfangenes Byte erhöhen
inc rxptr
//wenn alle Tastendrücke fertig, dann auswerten
cpi rxptr,CODELENGTH
brne exitovf0

//empfangspointer wieder loeschen
clr rxptr

rcall eval


exitovf0: pop yh
pop yl
pop temp1
out sreg,r1
reti

wdthandler: in r1,sreg
//Sleep-Semaphore setzten
ldi dosleep,$01

//Ausgangssperre herabzaehlen,
tst lockcount
breq exitwdt
dec lockcount
exitwdt:
out sreg,r1



reti

pcihandler: in r1,sreg

wdr

out sreg,r1
reti

//die empfangenen Tastendruecke auswerten

eval: //Wenn alle uebereinstimmen, dann Ausgang aktivieren oder
//wenn onboard-Button gedrueckt, als neuen code abspeichern
sbis pinb,TASTER_INTERN
rjmp setcode

//CODELENGTH aufeinanderfolgende Bytes aus EEPROM lesen und vergleichen
ldi yl,low(rxbuf)
ldi yh,high(rxbuf)

ldi temp2,low(code)
ldi temp4,CODELENGTH
evalloop:
rcall readeeprom
ld temp3,y+
cp temp1,temp3

brne eval_error

dec temp4
brne evalloop

rcall pulse


clr wrongcount

exiteval: rcall status_short
ret


eval_error: inc wrongcount
cpi wrongcount,MAX_TRY
brlo exiteval
ldi lockcount,LOCKTIME

rjmp exiteval

setcode: //code im EEPROM abspeichern
ldi yl,low(rxbuf)
ldi yh,high(rxbuf)
ldi temp4,codelength


ldi temp2,low(code)

writeloop:
ld temp1,y+
rcall writeeeprom
dec temp4
brne writeloop

rcall status_long

ret



initwdt: //watchdog-Interrupt alle 8s
wdr
in temp1,WDTCR
ori temp1,(1<<WDCE) | (1<<WDE)
out WDTCR,temp1
ldi temp1,(1<<WDTIE) | (1<<WDP3) | (1<<WDP0)
out WDTCR,temp1
ret

//Standard-Routinen für eeprom
//der Adresszeiger in TEMP2 wird hier automatisch inkrementiert, da
//dieses Programm sequentiell auf das EEPROM zugreift.

readeeprom:
sbic EECR,EEPE
rjmp readeeprom
out EEARL,temp2
sbi EECR,EERE
in temp1,EEDR
inc temp2
ret
writeeeprom:
sbic EECR,EEPE
rjmp writeeeprom
ldi temp3,(0<<EEPM1)| (0<<EEPM0)
out EECR,temp3
out eearl,temp2
out eedr,temp1
sbi EECR,EEMPE
sbi EECR,EEPE
inc temp2
ret

status_short:
ldi pulsestatus,$02
sbi portb,status
ret

status_long:
ldi pulsestatus,$08
sbi portb,status
ret


pulse: //Ausgang nur dann aktivieren, wenn nicht Ausgangssperre
tst lockcount
brne exit_pulse

//Ausgang aktivieren
sbi pinb,OUTPUT
//wird durch OVF0 wieder abgeschaltet
ldi pulseoutput,$0b
exit_pulse:
ret


.dseg


rxbuf:
.byte CODELENGTH

.eseg

code: .byte CODELENGTH

Bauteile für dieses Projekt - Anzeigen:
Aktive Bauelemente

Passive Bauelemente


Weitere Informationen,Grundlagen,Bauanleitung,Schaltplan, Links zum Thema
Anzeigen:

Neueste Artikel
Anzeigen:
Aktuelle Newsbeiträge
Sie sind Besucher Nr. 882130