(c) C. Winter
2009, v1.1
Als
Wetterinteressierter haben mich Blitze schon immer fasziniert. Durch diese
Seite (http://www.techlib.com/electronics/lightning.html)
bin ich auf einen Blitzdetektor und eine Möglichkeit, darüber seine Kamera bei
Blitzen auslösen zu lassen („Readers Versions“), aufmerksam geworden.
Da ein Blitz
normalerweise aus mehreren Entladungen besteht, die im Abstand weniger Millisekunden
den gleichen Entladungskanal entlang laufen (s. auch Wikipedia), besteht eine
gute Chance, beim Auslösen der Kamera im ersten Entladungsfall noch weitere
Entladungen (=Blitz) aufs Bild zu bannen.
Leider hat meine
Kamera keine Möglichkeit, über ein externes Signal zur Aufnahme bewegt zu
werden. Außerdem suchte ich schon seit längerem nach einen Fernauslöser.. Also
musste ich einen Weg suchen, die Kamera über den normalen Druckknopf-Auslöser
zu betätigen. Dafür biete sich ein Servo an, dessen Ruderhorn statt meines
Fingers auf den Knopf drückt.
Das vorliegende
Programm läuft auf einem ATtiny25. Mit einer (!) LED werden die
Betriebszustände angezeigt:
Die folgenden
Punkte können in beliebiger Reihenfolge ausgeführt werden:
Nun noch das
Servo an der Kamera angebracht (kann durchaus der schwierigere Teil sein ;)),
und schon hat man einen Fernauslöser (Schalter 3), der auch durch
Gewitterblitze ausgelöst werden kann :)
Zum Programm:
Vorab: dies ist
erst mein drittes AVR-Projekt, bin also kein Profi :)
Der ATtiny25
wird auf 8 MHz getaktet (Vorteiler wird auf 1 zurückgestellt), die Fuses
bleiben unberührt. Damit lässt sich der Servo-Befehl gut ausführen. Alle Pins
des Controllers werden entweder als Schalter-PINs oder LED- und Servo-PORT
genutzt. Timer0 (Servo) und Timer1 werden geschaltet, letzter als
Zeitintervall. Der Timer1 wird derzeit von BASCOM nicht über alle BASCOM-Codes
unterstützt, hier muss man diverse Register direkt ansprechen – dank an
FarmTech für den Tipp).
Zum Schaltbild:
Vorab: Dies ist
mein erster selbst gezeichneter Schaltplan. Fehler dürfen korrigiert werden und
gehören dem Finder.
Schalter wurden
gegen GND und nicht gegen 5V geschaltet, um Bauteile zu sparen. SV1 sind die
Stecker für die Spannungsversorgung (a.k.a. „Stecker“), J2 sind drei Pins einen
Pinleiste als Steckseite für die Buchse des Servos (JR-Kupplung).
Schaltplan als Eagle-Datei auf Anfrage!
Das Bild zeigt
die Servosteuerung (grün umrandet) mit dem Blitzdetektor (rot umrandet) auf
einer Lochrasterplatine. Nur die Stromversorgung und der Trigger für den Blitzt
verbindet beide Bauabschnitte.
Schalter 1 und 2
wurden als Wechselschalter realisiert. Ein zusätzlicher, optionaler
1µF-Kondensator wurde zwischen den Stromversorgungs-Pins zum Servo geschaltet.
Der Servo wurde
mit einem Telefonkabel/Telefonbuchse als Verlängerungskabel verbunden.
Für die
Beschaltung des Blitzdetektors siehe http://www.techlib.com/electronics/lightning.html
Verdrahtungsseite
(nicht hübsch, aber funktioniert!):
Servo-Montage an
der Kamera mithilfe eines Blitzhalters.
Ruhe- und
Auslöseposition des Servos (das Ruderhorn wurde geknickt, um eine einfacheres
Auslösen zu ermöglichen).
... selbiges von
vorne.
Code:
'-------------------------------------------------------------------------------
' Filename :
FernausloeserATtiny25_2.bas
' Zweck :
Fernauslösersteuerung mit Servo für Kameras ohne externe Auslösemöglichkeit.
' Datum : 06.06.2009,
28.06.09
' Autor : Dr.
Christoph Winter
' Funktion : siehe
http://www.jurmo.de/AVR
' Controller : ATtiny25
' Compiler : BASCOM-AVR Rev.
1.11.9.4
'
' Features:
' - Conrad BestNr: 227726 - Top Line Standard Servo ES-30 JR
' - Arbeitet mit dem Blitzdetektor von
http://www.techlib.com/electronics/lightning.html zusammen
'
' To Do:
' -
'
' Features for the future:
' -
'
' History:
' - V1.0 06.06.2009 Fertigstellung
' - V1.11 28.06.2009 Position setzen am Anfang nur mit Taster1+2 o.
1+3 o. 2+3, nicht 3 allein!
'
' Free for noncomercial use!
' For commercial use contact avr@jurmo.de
' All rights reserved!
'--------------------------------------------------------------
'-------------------------------------------------------------------------------
' Testaufbau auf Pollin+BreadBoard + Lochrasterplatine.
' ATMEL Evaluations-Board V2.0.1 mit
ATtiny25
'-------------------------------------------------------------------------------
'$sim
' Pin Configuration ATtiny25
'
+-------+
' PB5 |1 8| VCC
' PB3 |2 7| PB2
' PB4 |3 6| PB1
' GND |4 5| PB0
'
+-------+
' Nicht relevant, aber zu merken:
' On ATtiny25, the programmable I/O ports
PB3 and PB4 (pins 2 and 3) are exchanged in ATtiny15 Compatibility Mode for
supporting the backward compatibility with ATtiny15.
'
$regfile="ATtiny25.dat"
$crystal=8000000 ' externer Quarz oder interner Oszillator mit
Vorteiler 1 (Fuse CKSEL0=0 CKSEL1=0 CKSEL2=1 CKSEL3=0 SUT0=0 SUT1=0)
0=programmiert, 1=nicht programmiert
' Setzt CLKPR auf Vorteiler=1 -> Kein Vorteiler -> 8 MHz
statt 1MHz
$ASM
Ldi R16 , &B10000000
Out CLKPR,R16
Ldi R16, &B00000000
Out CLKPR,R16
$END ASM
$hwstack=40
$swstack=30
$framesize=30
'$Baud =4800 'Baudrate
für UART
$EEPROMHEX ' Nicht mit
PonyProg!!!
$eepleave
'===============================================================================
' BELEGUNGEN PIN und PORT
DDRB =&B11111000
PortB=&B00000111 'pullup (0= low
level; 1= high level)
Taste3 alias PinB.0 ' Pin benamsen
Taste2 alias PinB.1 ' Pin benamsen
Taste1 alias PinB.2 ' Pin benamsen
LED1 alias PortB.4
' Port Signalausgabe-Anzeige (flackert schell)
SignalServo1 alias PortB.3 ' Port für Servosignal - Pin #20 im
Mega16-Sockel
'===============================================================================
' VARIABLEN
' Werte aus dem EEPROM:
dim BDummy as ERAM
Byte ' die erste EEPROM-Speicherstelle leer lassen
dim EEChk as ERAM
Byte ' Prüfen, ob EEPROM schon belegt ist
dim E_Ruhe as ERAM
Byte ' Ruheposition
dim E_Vorspannen as ERAM Byte ' Position "Vorgespannt"
dim E_Ausloesen as ERAM
Byte ' Position "Auslösen"
' Vorbelegungen:
' Verwendetes Servo: Conrad ES-05 BestNr. 230500
dim Ruhe as Byte '
Position
dim Vorspannen as Byte '
Position
dim Ausloesen as Byte '
Position
dim B as Byte '
Hilfsvariable
dim PosVal as Byte '
Hilfsvariable Positionierung
dim Bitleiste as Byte '
Bitleistenvariable
Flag_Mitte alias Bitleiste.0 ' mittlerweise obsolet
Flag_Timer1_Overflow alias Bitleiste.1 ' Überlaufindikator
Flag_Taste1 alias Bitleiste.2 ' Tastenindikator
Flag_Taste2 alias Bitleiste.3 ' Tastenindikator
Flag_Taste3 alias Bitleiste.4 ' Tastenindikator
Flag_Vorgespannt alias Bitleiste.5 ' Positionsindikator
const Timervorgabe=62000 '62000 ' 49911 ' 34286
dim Timersetting as Word ' Blink- und Überlauffrequenz
dim MaxDrehung as Byte '
Ginge auch als CONST
dim MinDrehung as Byte '
Ginge auch als CONST
'===============================================================================
' TIMER
' config Timer1=Timer, prescale=8192
'-> s. page 87 of datasheet, geht nicht mit ATtiny25!
Tccr1 = &B00001110
on Timer1 Timer1_IRQ
' TIMER0 = Servo
config Servos=1, Servo1=SignalServo1,
Reload=10
enable Interrupts
Servo(1)=60
'===============================================================================
' DEFINITIONS
declare Sub Presetting(Wert as Byte)
'===============================================================================
' INIT
#IF _SIM
E_Ruhe=60
E_Vorspannen=70
E_Ausloesen=80
#ELSE
if EEChk<>127 then
LED1=0 ' ROT! Kein EEPROM gebrannt!
end
end if
#ENDIF
Ruhe=E_Ruhe ' fixer Positionswert (empirisch bestimmt)
Vorspannen=E_Vorspannen ' fixer Positionswert (empirisch bestimmt)
Ausloesen=E_Ausloesen ' fixer Positionswert (empirisch bestimmt)
MaxDrehung=150 ' Maximalwert! Anschlag!
MinDrehung=30 ' Minimalwert! Anschlag!
enable timer0
enable timer1
enable Interrupts
Servo(1)=Ruhe ' In Startstellung
B=0 ' hier: Zeitintervall-Zähler
wait 1 ' Entprellen nach Einschalten (Kondensatoren laden, Servo
in Startposition fahren, etc...)
Timersetting=65000 ' Schnell blinken!
do
if Flag_Timer1_Overflow=1 then
Flag_Timer1_Overflow=0
toggle LED1
incr B
end if
' Mindestens 2 Tasten
müssen gleichzeitig gedrückt sein -> kein Entprellen notwendig!
if Taste1=0 and Taste2=0 then
Flag_Taste3=1 ' Ändern? Dann einfach mal flaggen!
if Taste1=0 and Taste3=0 then
Flag_Taste3=1 ' Ändern? Dann einfach mal flaggen!
if Taste2=0 and Taste3=0 then
Flag_Taste3=1 ' Ändern? Dann einfach mal flaggen!
if Flag_Taste3=1 then
B=255
end if
loop until B>=100 ' 50 mal blinken
(100x toggle)
if Flag_Taste3=0 then goto Main ' Keine Änderung der Settings! Mit
GOTO! (urgs!)
LED1=1 ' Aus
wait 1 ' Loslassen aller Tasten!
' Voreinstellungen ändern
Flag_Taste1=0
Flag_Taste2=0
Flag_Taste3=0
Timersetting=63500 ' Step- und Blinkfrequenz etwas langsamer
' Positionen einstellen
call Presetting(Ruhe)
E_Ruhe=Ruhe
'MinDrehung=Ruhe
Vorspannen=Ruhe ' Position übernehmen
call Presetting(Vorspannen)
E_Vorspannen=Vorspannen
'MinDrehung=Vorspannen
Ausloesen=Vorspannen ' Position übernehmen
call Presetting(Ausloesen)
E_Ausloesen=Ausloesen
Timersetting=65000 ' Schneller ISR, aber Zähler für Blinken (s.u.)
Main:
Servo(1)=Ruhe ' In Startstellung
Flag_Taste1=0
Flag_Taste2=0
Flag_Taste3=0
'===============================================================================
' MAIN
do
if Flag_Timer1_Overflow=1 then
Flag_Timer1_Overflow=0
incr B
if B>=35 or Flag_Vorgespannt=1 then
B=0
LED1=0
else
LED1=1
end if
PosVal=Servo(1)
Servo(1)=PosVal ' Immer
mal wieder aktualisieren zum Stabilisieren (*nicht* dringend benötigt!)
end if
debounce Taste1, 0, SubTaste1, sub
debounce Taste2, 0, SubTaste2, sub
debounce Taste3, 0,
SubTaste3, sub
if Flag_Taste2=1 then '
Bei Taste 2 Vorspannen
Flag_Taste2=0
Servo(1)=Ruhe
Flag_Vorgespannt=0
end if
if Flag_Taste1=1 then ' Bei Taste 1 Ruhen
Flag_Taste1=0
Servo(1)=Vorspannen
Flag_Vorgespannt=1
end if
if Flag_Taste3=1 then '
Bei Taste 3 Auslösen
Flag_Taste3=0
Servo(1)=Ausloesen
Flag_Vorgespannt=1
B=0
do
waitms 25
incr B
toggle LED1
loop until B>=10 and
Taste3=1 ' Wenn Schalter gedrückt bleibt, bleibt auch das Servo in
Auslöseposition (Serienaufnahmen).
Servo(1)=Ruhe
B=0
do
waitms 25
incr B
loop until B>=10
Servo(1)=Vorspannen
end if
loop
end
'===============================================================================
' SUBROUTINEN
Timer1_IRQ:
tcnt1=Timersetting
'"Timer1=Timervorgabe" geht nicht
Flag_Timer1_Overflow=1
return
SubTaste1: ' rechts
Flag_Taste1=1
return
SubTaste2: ' links
Flag_Taste2=1
return
SubTaste3:
Flag_Taste3=1
return
Rechts:
LED1=0
do
if Flag_Timer1_Overflow=1 then
Flag_Timer1_Overflow=0
incr PosVal
if PosVal>MaxDrehung then PosVal=MaxDrehung
Servo(1)=PosVal
end if
loop until Taste1=1
waitms 25 ' Debounce
return
Links:
LED1=0
do
if Flag_Timer1_Overflow=1 then
Flag_Timer1_Overflow=0
decr PosVal
if PosVal<MinDrehung then PosVal=MinDrehung
Servo(1)=PosVal
end if
loop until Taste2=1
waitms 25 ' Debounce
return
Sub Presetting(byref Wert as Byte)
PosVal=Wert ' Voreinstellen
Servo(1)=PosVal
do
if Flag_Timer1_Overflow=1 then
Flag_Timer1_Overflow=0
toggle LED1
Servo(1)=PosVal '
immer mal wieder...
end if
debounce Taste1, 0, SubTaste1, sub
debounce Taste2, 0, SubTaste2, sub
debounce Taste3, 0, SubTaste3, sub
if Flag_Taste1=1 then
Flag_Taste1=0
gosub Rechts
end if
if Flag_Taste2=1 then
Flag_Taste2=0
gosub Links
end if
if Wert<>PosVal then ' Wenn sich
was geändert hat...
Wert=PosVal
Servo(1)=Wert
end if
' Wenn Taste 3 gedrückt
wurde
if Flag_Taste3=1 then '
Im Eeprom speichern
LED1=0
wait 1
LED1=1
end if
Flag_Taste1=0 ' jetzt obsolet, Code-Leiche ;-)
Flag_Taste2=0 ' jetzt obsolet, Code-Leiche ;-)
loop until Flag_Taste3=1
Flag_Taste1=0
Flag_Taste2=0
Flag_Taste3=0
waitms 25 ' Debounce
end Sub
'===============================================================================
'
.NNNL. JNNN_ N)JNN_
(NJNN JNNN. (N.NNL.JNN.
' (NN"4NN. NNF"NNL NNN"NNL (NN"N NNF"NN)
(NN"NNNF4NN
' NN___JN)(NL___NN NN NN
(N) (N) NN (N) NF (N
' NNNNNNN)(NNNNNNN N) (N
(N (N (N (N N) (N
' NN ._.(N) __ NN
NN (N (N) NN
(N N)
(N
' (NNLJNN` NNN_NNF NNN_NN) (N
NNL_NN) (N N) (N
' `NNNF` 4NNN"
NF4NN" (N 4NNN`
(N N) (N
' N)
'==================N)===========================================================
$eeprom
DATA 0 ' 1. Stelle - immer ungenutzt!
DATA 127 ' 2. Stelle:
Kennung: Beschrieben! (default ist 255):
DATA 50, 60, 70 '
Initial-Positionen
DATA "Fernausloeser
(c) C. Winter 2009"
$data
end
Christoph
Winter, 2009
Alle Rechte
vorbehalten
Last change: freigeschaltet | C. Winter, 7. Juni 2009 |