1 Volt LED Lampe mit AVR

Winfried Mueller, www.reintechnisch.de, Start: 13.10.2006, Stand: 12.12.2006

Mit nur einer Zelle bis 0.9 Volt hinunter eine weiße LED betreiben, wie kann das gehen? Und dann dazu noch einen AVR-Prozessor...

Die Lösung greift auf einen recht neuen Spezial-IC zurück, der ein paar interessante Eigenschaften hat. Er kommt in einem ultrakleinen SOT-23 Gehäuse daher, hat nur 3 Anschlüsse und braucht außer einer Spule keine weiteren externen Komponenten. Er sorgt dafür, dass aus einer Spannung von 0.9-1.5 Volt eine für weiße Leuchtdioden passende Spannung gemacht wird. Oder genauer: Er versorgt eine weiße Leuchtdiode mit einem Strom von ca. 20 mA.

Der Chip heißt PR4401 und kommt von Prema. Bastler bekommen den z.B. bei http://www.ak-modul-bus.de für ca. 1 Euro das Stück. Dazu kann man dort gleich eine ultrakleine passende Spule für 30 Cent kaufen. Nachtrag 12/07: Den PR4401 gibt es nun auch bei http://www.reichelt.de

Die Schaltung

Grafik lässt sich vergrößern: Klick mit rechter Maustaste, Grafik anzeigen

Für die Spannungswandlung ist, wie oben schon geschrieben, der PR4401 verantwortlich (IC2). Er benötigt L1 mit 10 uH. C1 stabilisiert die Eingangsspannung, weil kurzzeitig höhere Ströme durch den Wandler fließen. Am Ausgang (Pin2 IC2) wird gegen Masse die Leuchtdiode angeschlossen (An Pin 2/Pin 3 von SV1). An SV1 Pin 4 und Pin 1 wird die Eingangsspannung (1.5Volt) angeschlossen, in unserem Fall eine Micro-Batterie (AAA). Die hält etwa für 10-15 Stunden.

Die Schaltung soll aber nicht nur eine LED zum leuchten bringen. Ein Mikroprozessor soll dafür sorgen, dass durch einen Tastendruck die Lampe einschaltet. Ein weiterer Tastendruck und die Lampe soll wieder ausschalten. Und zwar so, dass kein Strom mehr verbraucht wird. Außerdem soll die Lampe nach 3 Minuten selbständig abschalten - ein Feature, was ich mir schon immer für eine Taschenlampe gewünscht habe, weil man das Ausschalten gerne mal vergisst.

Hierfür wird an die Schaltung über SV2 ein Mikroschalter angeschlossen. Der gemeinsame Kontakt an Pin 2, der Schließer an Pin3 und der Öffner an Pin1. Leider braucht es für dieses Schaltungskonzept einen Taster mit Öffner und Schließer, wie es jedoch die meisten Mikroschalter/Schnappschalter haben. Bei einer Eingangsspannung von nur 1 Volt ist mir kein Schaltungskonzept mit nur einem einfachen Taster mehr eingefallen.

Wird dieser Taster betätigt, bekommt R3 ein Massepotenzial, worüber dann Q1 durchschaltet. Im ausgeschalteten Zustand wird er sauber über R1 gesperrt. Wenn Q1 durchschaltet, beginnt der PR4401 (IC2) mit seiner Arbeit und versorgt die Leuchtdiode mit Strom. Gleichzeitig wird über D1/R2 der Tiny12 (IC1) mit Spannung versorgt. Das Programm sorgt dafür, dass PB3 auf High gehalten wird, womit dann über R4 der Transistor Q2 durchgesteuert wird. Damit ist dann die Selbsthaltung realisiert. Der Taster kann losgelassen werden und trotzdem fließt in die Basis von Q1 über Q2 ein Strom. Damit der Prozessor weiß, wann der Taster erneut gedrückt wird, ist der Öffner des Mikrotasters an PB4 geklemmt. Normal wird der Pin darüber auf Masse gehalten. Betätigt man den Taster aber, öffnet sich der Kontakt und PB4 wird über den internen Pullup auf High gezogen. Damit erkennt der Prozessor den Schaltvorgang und kann dann ggf. die Lampe wieder abschalten. Dies geschieht über PB3 auf Low.

D2 ist eine 4.7 Volt Zenerdiode, die im normalen Betriebsfall nicht benötigt wird. Wenn aber die externe LED fehlen sollte, würde die Ausgangsspannung des PR4401 einen recht hohen Wert annehmen. Der Prozessor würde sofort zerstört. Hier begrenzt die Zenerdiode auf etwa 4.7 Volt.

Klar, dass der Prozessor der Leuchtdiode etwas Strom "klaut". Diese bekommt damit nicht die vollen 20 mA. Der Prozessor ist aber so sparsam, dass das kaum ins Gewicht fällt. Wegen des geringen Stromes reicht übrigens auch der "mutig dimensionierte" Tiefpass R2/C2 mit C2 = 100nF völlig aus. Die Stromaufnahme sollte deutlich unter 1 mA sein. Vorteilhaft wirkt sich der Spannungsabfall an D1 und R2 aus. Damit sinkt die Betriebsspannung des Prozessors und damit auch der Stromverbrauch. Es stellt sich am Prozessor eine Spannung von etwa 2.5-3 Volt ein.

Hier noch die Eagle-Dateien: Attach:lamp-1V.zip

Programm

Als Basis für das Programm wurde die Software vom 9V-LED-Lampenprojekt II verwendet. Insofern braucht es dafür keine Erläuterungen mehr.

Wichtig ist, beim Tiny 12 eine BOD-Level von 1.8 Volt einzustellen und die BOD-Überwachung zu aktivieren. Der Takt bleibt mit 1.2 MHz internem Oszillator in der Default-Einstellung.

 
; 1V-Lampe mit PR4401 nach Idee vom 13.10.2006
; Interner RC-Oszi, Tiny 12
; Beginn: 13.10.2006, Stand: 13.10.2006
; Author: Winfried Mueller, www.reintechnisch.de  
; Changelog:
;   13.10.2006 Fork von main.asm Projekt 9V-Lampe
;
; PORTB
; PB0: IN    P   NC
; PB1: IN    P   NC
; PB2: IN    P   NC
; PB3: OUT   -   On-Transistor
; PB4: IN    P   Switch (Low aktiv)
; PB5: IN        Reset

.include "tn12def.inc"

; IO-PINS
.equ P_SWITCH    = 4
.equ P_ON        = 3


; Register Definition

;   General Purpose
.def a           = r16
.def b           = r17
.def c           = r18

;   Interrupt
.def i_a         = r19
.def sSREG       = r1

;   sonstig
.def key_0_longcount = r4   ;Counter für key_0 LongPressedEvent

.def sec_divider = r20      ;Timer-Divider Sekundentakt
.def cnt_s       = r21      ;Count Sekunden
.def cnt_m       = r22      ;Count Minuten

.def flags       = r23      ;General Flag Register

.def key_0       = r24      ;Bit 0..2 Prellcount
                            ;Bit 3: Keystatus (0=losgel., 1=gedrückt) 
                            ;Bit 4 Event Key OFF (losgelassen)
                            ;Bit 5 Event Key ON  (gedrückt)
                            ;Bit 6 Event Key LONG_ON (lange gedrückt)
                            ;(Bit 4/5/6 wird von Applika rückgesetzt 
                            ;  und von ISR gesetzt)


; Constants

.equ TM0_PRESET      = 209     ;kalibrieren auf Timereinsprung alle 10ms (256-x)
.equ LAMP_OFF_TIME_S = 0        
.equ LAMP_OFF_TIME_M = 3

.equ FLAG_SEC        = 0
.equ FLAG_MASK_SEC   = 0x01

.equ KEY_EVENT_OFF     = 4
.equ KEY_EVENT_ON      = 5
.equ KEY_EVENT_LONG_ON = 6

.MACRO INIT_IO_ON
              ldi a, 0b00011111
              out PORTB, a
              ldi a, 0b00001000   
              out DDRB, a
.ENDMACRO

.MACRO INIT_IO_OFF
              ldi a, 0b00010111
              out PORTB, a
              ldi a, 0b00001000   
              out DDRB, a
.ENDMACRO

.MACRO INIT_TIMER
              ldi a, 0b00000100   ;Prescale Timer = 256 -> ca alle 213us
              out TCCR0, a        
              ldi a, TM0_PRESET   ;Timer-Counter Preset
              out TCNT0, a
              ; Set Oscillator Calibration default
              ldi a, 0x60
              out OSCCAL, a
.ENDMACRO

.MACRO RESET_TIME
              ldi sec_divider, 0
              ldi cnt_s, 0
              ldi cnt_m, 0
.ENDMACRO

.MACRO INIT_INT_ON
              cli

              ldi a, 0b00000000   ;kein External/Pin-Change Interrupt
              out GIMSK, a

              ldi a, 0b00000010   ;Timer Overflow Interrupt Enable
              out TIMSK, a

              sei
.ENDMACRO

.MACRO INIT_INT_OFF
              cli
.ENDMACRO

.MACRO INIT_COMPARATOR
              cbi ACSR, ACIE      ;No Interrupt
              cbi ACSR, ACD       ;Comparator enable
              sbi ACSR, AINBG     ;Internal Reference
.ENDMACRO

.MACRO INIT_SLEEP
              ldi a, 0b00100000  ;Idle
              out MCUCR, a
.ENDMACRO


.MACRO RESET_KEY
              ldi key_0, 0
.ENDMACRO

.MACRO RESET_KEY_EVENT
              andi key_0, 0b10001111
.ENDMACRO




;--------------------------------------
; Interruptvektoren
;--------------------------------------

              rjmp RESET
              rjmp EXT_INT0
              rjmp PIN_CHANGE
              rjmp TIMER0
              rjmp EE_RDY
              rjmp COMPARATOR


;--------------------------------------
; Interrupt Service Routine
;--------------------------------------
EXT_INT0:     reti

PIN_CHANGE:   reti

EE_RDY:       reti

COMPARATOR:   reti


TIMER0:       in sSREG, SREG
              ldi i_a, TM0_PRESET    ;Timer-Counter Preset
              out TCNT0, i_a
              ;---

              inc sec_divider
              cpi sec_divider, 100
              brne t0_l1    
              ; Endwert erreicht
              ldi sec_divider, 0
              sbr flags, FLAG_SEC
              inc cnt_s
              cpi cnt_s, 60
              brne t0_l2
              ; Sekundenüberlauf
              inc cnt_m
              ldi cnt_s, 0
t0_l2:
t0_l1:   
t0_kb:        ;-- Tastencheck
              sbrc key_0, 3 ; -> Taste gedrückt gemerkt?
              rjmp t0_l5
              ;-> Taste gemerkt losgelassen, Check, ob gedrückt
              sbis PINB, P_SWITCH ;+
              rjmp t0_l8     ;->gemerkt losgelassen, ist losgelassen
              ;-> gemerkt losgelassen, ist gedrückt
              inc key_0
              mov i_a, key_0
              andi i_a, 0x07
              cpi i_a, 0x02
              brne t0_l4    ; -> noch kein Wechsel einleiten
              ;-> gilt jetzt als gedrückt, Event gedrückt
              andi key_0, 0b11111000
              ori  key_0, 0b00101000
              ldi i_a, 200             ;Init LongKeyPressedCount
              mov key_0_longcount, i_a
              rjmp t0_l4

t0_l5:        ;-> Taste gemerkt gedrückt, Check, ob losgelassen
              sbic PINB, P_SWITCH ;+
              rjmp t0_l6    ;->gemerkt gedrückt, ist gedrückt
              inc key_0
              mov i_a, key_0
              andi i_a, 0x07
              cpi i_a, 0x03
              brne t0_l4   ; -> noch kein Wechsel einleiten
              ;-> gilt jetzt als losgelassen, Event losgelassen
              andi key_0, 0b11110000
              ori  key_0, 0b00010000
              rjmp t0_l4

t0_l6:        tst key_0_longcount
              breq t0_l8
              dec key_0_longcount
              brne t0_l8
              ;-> jetzt Null -> KeyLongPressed-Event
              ori key_0, 0b01000000

t0_l8:        ;->Merker und Tastenstatus gleich -> Prellcount Reset
              andi key_0, 0b11111000  ;Count Reset
              rjmp t0_l4     

t0_l4:        ;---
              out SREG, sSREG
              reti

RESET:
MAIN:         INIT_IO_ON
              RESET_TIME
              INIT_SLEEP
              INIT_TIMER
              INIT_INT_ON
              INIT_COMPARATOR

              clr flags



              ; Check, ob Taster noch gedrückt, wenn nicht, dann war es ein Spike
              ; und das Gerät soll sofort wieder ausschalten
              sbis PINB, P_SWITCH ;+
              rjmp m_l2

              ldi a, 200
              rcall WAIT_M         ;Warten damit Taste nicht sofort geprüft wird
              RESET_KEY_EVENT

m_l1:         sleep
              cpi cnt_m, LAMP_OFF_TIME_M
              breq m_l2
              sbrc key_0, KEY_EVENT_ON
              rjmp m_l3
              rjmp m_l1

m_l3:         ;Taste gedrückt, warte bis losgelassen
              sleep
              sbrc key_0, KEY_EVENT_OFF
              rjmp m_l2
              rjmp m_l3

m_l2:         ;Zeit abgelaufen/Taste gedrückt
              INIT_INT_OFF
              INIT_IO_OFF           ;jetzt sollte Prozessor ausschalten
              ldi a, 255
              rcall WAIT_M
              rjmp RESET            ;Reset, falls Fehler




;Zeitschleife
;Übergabe: a - Länge= 10ms * a (a:1..255)
WAIT_M:
WM_0:         ldi b, 0xFF
WM_1:         lpm
              lpm
              lpm
              lpm
              lpm
              lpm
              lpm
              lpm
              lpm
              lpm
              lpm
              lpm
              lpm
              lpm
              wdr
              wdr
              dec b
              brne WM_1
              dec a
              brne WM_0
              ret



Praxiserfahrung

Die Schaltung tut seit Mitte Oktober 2006 ihren Dienst als Nachttischlampe, seit Dezember 2006 auch als Taschenlampe. Gut einsetzen kann man sie auch als Lampe zur kurzzeitigen Ausleuchtung von unbeleuchteten Räumen.

Im Sommer 2008 kam eine kleine Holztaschenlampe aus gedämpfter Robinie hinzu, in der ebenfalls obige Schaltung werkelt. Sie wird mit einer Microzelle betrieben.

Tipps

Der PR4401 schafft es auch, 2 LED's in Reihe zu treiben. Allerdings muss dann die Schaltung angepasst werden, um die Versorgung des Prozessors sicherzustellen. Man könnte z.B. den Mittelabgriff zwischen den beiden Leuchtdioden für die Spannungsversorgung des Prozessors verwenden.

Für höhere Ströme als 20 mA ist der PR4401 leider nicht ausgelegt.

Der PR4401 reagiert sehr empfindlich, wenn die Spannung an VIN einbricht. Evtl. muss der Kondensator C1 vergrößert werden. Auf kurze Anschlußdrähte zur Batterie ist zu achten.

Ein Tiny 13 mit 128KHz internem Oszillator betrieben ist noch wesentlich stromsparender (unter 100uA). Das Programm dafür anzupassen, ist leicht.

Den Code so zu erweitern, das der Watchdog mit eingebunden wird, macht Sinn. Im Fehlerfalle setzt er dann den Chip zurück. Für mich war es übrigens ein interessanter Test, den AVR mal absichtlich ohne Watchdog laufen zu lassen, um zu schauen, wie oft so ein Ausnahmefall vorkommt, dass der AVR sich aufgrund elektromagnetischer Einflüsse aufhängt. Vor 15 Jahren hatte ich bei den PICs diesbezüglich ab und zu mal Probleme: Geräte, die im rauhen Alltagseinsatz betrieben wurden, hängten sich 1-2 mal pro Jahr aus unerfindlichen Gründen einfach auf. Und auch hier hatte ich jetzt den Fall: Im Winter 2008 hängte sich meine Holz-Taschenlampe das erste mal auf. Man konnte sie nicht mehr ausschalten. Nach etwa 20 Minuten und unendlichen Schaltversuchen ging sie dann aber doch aus. Es handelte sich um einen der absolut seltenen Fälle - die aber doch irgendwann vorkommen. Ein Watchdog hätte sicherlich geholfen.

Weblinks