Anwendungen von
AVR-Einchip-Prozessoren AT90S, ATtiny, ATmega und ATxmega Eieruhr mit ATtiny
Eigenschaften dieser Eieruhr
Diese Eieruhr hat folgende Eigenschaften:
Sehr einfacher Aufbau, Kosten unter 10 Euro.
Blinkt bei aktueller und bei der nächsten Minuten-LED unterschiedlich lange.
Optimiert für sehr sparsamen Batteriebetrieb.
Macht zu jeder vollen Minute Musik über Lautsprecher.
Die Schaltbilder und Grafiken gibt es in der LibreOffice-Draw-Datei
hier, die Rechenblätter dazu in der
LibreOffice-Calc-Datei hier.
Hardware
Das ist das ganze Schaltbild der Eieruhr: ein µC, zwei Widerstände,
zehn LEDs, ein Kondensator, ein Elko, zwei Batterien mit Schalter, ein
Miniaturlautsprecher und ein abgewinkelter Pfostenstecker zum Programmieren.
Da dank Software-Steuerung immer nur eine der beiden aktuellen LEDs an ist,
kann man sich den Verhau mit LED-Vorständen stark vereinfachen: ein
einziger Widerstand kontrolliert den LED-Strom.
Die Schaltung arbeitet mit einer Betriebsspannung ab 2,4 V
(mit Niedrigstrom-LEDs) bzw. ab 3 V. In dem gezeigten Ausschnitt der
LibreOffice-Calc-Datei kann man sich im Rechenblatt "resistor"
leicht für jeden Betriebsspannungsfall den Vorwiderstand ausrechnen,
mit dem man die vorwählbaren mA LED-Strom kriegt.
Das Rechenblatt ermittelt die LED-Spannung (für Standard-LEDs und
für Niedrigstrom-LEDs) sowie den Spannungsverlust am aktiven Pin.
Beides sind Schätzwerte, wer es ganz genau wissen will, misst es
selbst nach.
Der Strombedarf liegt bei einer LED zwischen 0 und 5 mA, bei zweien
bei 5 mA und bei laufender Melodie maximal bei bis zu 19 mA.
Aufbau
Das ist der Bohrplan der Abdeckung in Originalgröße (40 x 50 mm).
Die Löcher für die LEDs sind 3,2 mm, alle anderen 2,5 mm.
Die Aussparung für den Schalter ist mit 1 mm-Löchern vorzubohren
und dann mit der Laubsäge auszuschneiden. Da hierbei nur wenig Abstand zum
Rand ist, muss das entsprechend vorsichtig erfolgen.
Das sind alle Teile, die man dazu braucht. Mit etwa 10 Euro ist man dabei.
Wer den Lautsprecher in der Mitte der ovalförmig angeordneten LEDs
anbringen will, entscheidet sich für einen Lautsprecher mit maximal
28 mm Durchmesser. Ich habe einen Typ BL 28 probiert, der allerdings
nur 8 Ω hat. Funktioniert trotzdem prima.
Software
Download
Die Software ist in Assembler geschrieben. Der Quellcode kann
hier heruntergeladen werden. Eine
Änderung der werksseitigen Fuses ist nicht erforderlich.
Durch die umfangreichen Melodien nutzt der Quellcode den Flash-Speicher
nahezu vollständig aus. Wer noch an den Melodien basteln und erweitern
möchte, muss eventuell auf den ATtiny44 oder ATtiny84 mit mehr Flash
umstellen.
Ablauf der LED-Steuerung
Das Schalten der LEDs erfolgt mit den beiden Registerpaaren rBitB:rBitA
und rNxtB:rNxtA, die jeweils auf den beiden Ports B und A ausgegeben
werden. Sie schalten abwechselnd die LED der aktuellen Minute (rBitA/B)
und die nächstfolgende LED (rNxtA/B) ein. Zu jeder vollen Minute
werden die Bits in rNxtA/B nach rBitA/B kopiert, dann wird
rNxtA/B um eine Bitposition nach links geschoben.
Das Timing der LED-Ansteuerung erfolgt mit dem 16-Bit-TC1. Er arbeitet
dazu im CTC-Modus mit dem Vergleichswert im Vergleichsregister A.
Jede Minute des Ablaufs teilt sich in 256 PWM-Stufen im Register
rPwm auf, die sich jeweils 256 mal wiederholen und im Register
rPwmCnt hochgezählt werden. Daraus resultiert die folgende
Verzögerung, damit 256 * 256 PWM-Stufen 60 Sekunden ergeben:
tdly = 60 * 1.000.000 / 256 / 256 = 915,5 µs
Diese 916 µs Verzögerung erzeugt TC1 im CTC-Modus.
Die gesamte LED-Steuerung erfolgt in der Interrupt-Service-Routine des
OCIE1A von TC1. Zu jeder vollen Minute, wenn rPwm und rPwmCnt
beide Null werden, beginnt ein neuer Minutenzyklus. Die LED, die dieser
Minute entspricht, wird eingeschaltet. Sie bleibt über den ganzen
folgenden Zyklus (256 PWM-Stufen) lang eingeschaltet.
Mit dem ersten folgenden Zyklus wird die LED, die der aktuellen Minute folgt,
eingeschaltet. Sie bleibt so lange eingeschaltet, wie es der Zyklenfolge
entspricht: zunächst für eine Zyklusdauer von 0,92 ms lang,
beim zweiten Durchlauf über zwei Zyklen lang (1,83 ms), usw.,
zunehmend bis zum Ende des Zyklusses, bei dem die Leuchtdauer der aktuellen
LED abnimmt und die Leuchtdauer der nächsten LED in gleichem Maße
zunimmt.
Programmtechnisch ist diese Aufgabe folgendermaßen gelöst:
Zu jeder vollen Minute werden zwei Register, rNxtA und
rNxtB, um ein Bit nach links geschoben. Beide enthalten eine
einzige Eins, die damit um eine LED weiter geschoben wird.
Vor dem Linksschieben wird der Inhalt von rNxtA/B in die
Register rBitA/B kopiert. Damit wird die aktuelle LED um Eins
weiter geschoben.
Zu jeder vollen Minute beginnt der Zyklus mit dem in rBitA/B
gesetzten Bit, dieses Bit bleibt über den gesamten Zeitraum des
PWM-Zyklusses gesetzt.
Zu jeder vollen Minute wird auch die nächste Melodie gestartet
(siehe unten).
Ist der nächste PWM-Zyklus wieder bei Null angekommen, dann wird
jeweils die LED in rNxtA/B eingeschaltet. Sie bleibt so lange
an, bis der PWM-Zähler rPwm den aktuellen Counter
rPwmCnt erreicht.
Sind weder der Counter rPwmCnt noch der PWM-Zähler
rPwm Null, dann wird überprüft, ob der PWM-Zähler
den Counter erreicht. Ist dies der Fall, wird die vorherige LED in
rBitA/B ein- und die LED in rNxtA/B ausgeschaltet.
Wenn die aktuelle LED L10 erreicht, dann geht die Steuerung in den
Überlaufmodus. Dann torkelt der Lautsprecher-Pin mit einer Frequenz
von 1.000.000 / 916 / 2 = 546 Hz. Ausserdem
blinkt die LED L10 mit einer Frequenz von
1.000.000 / 916 / 256 / 2 =
2,13 Hz.
Es beginnt damit, dass rNxtA auf Eins steht und rBitA auf Null ist.
In der ersten LED-Phase sind alle LEDs aus.
Nach 1.000.000 / 916 / 256 = 0,234 Sekunden
ist der erste PWM-Zyklus zu Ende und rPwm wird Null. Dadurch
erhöht sich rPwmCnt auf Eins und der Zyklus beginnt mit dem
Setzen der LED-Ausgänge in rNxtA/B, was die erste LED L1 anmacht.
Bei allen weiteren PWM-Stufen wird rPwm mit rPwmCnt verglichen.
Bei Gleichheit wird rBitA/B ausgegeben, was die nächste LED
ausmacht (hier: L1) und stattdessen die vorherige LED in rBitA/B
(hier: noch keine) einschaltet.
Mit jedem weiteren PWM-Zyklus erhöht sich rPwmCnt, die aktive Phase
der nächsten LED verlängert sich und die aktive Phase der aktuellen
LED (hier: noch keine) verkürzt sich entsprechend.
Nach 60 Sekunden erreicht rPwmCnt dann wieder Null und die
nächste Minute bricht an.
Links ist die LED-Steuerung zu Beginn der ersten vollen Minute zu sehen, mit
den LEDs L1 und L2. Rechts der Algorithmus der TC1-Interrupt-Service-Routine.
Mit dem ersten PWM-Impuls, wenn rPwm Null ist und rPwmCnt noch
nicht Null ist, wird der LED-Ausgang auf rNxtA/B gesetzt. Dadurch geht
die LED L2 an und L1 geht aus. Nachdem rPwm den Wert von rPwmCnt
erreicht, wird auf dem LED-Ausgang rBitA/B ausgegeben. Dadurch geht
L1 an und L2 aus. Das bleibt dann so bis zum Ende dieses PWM-Zyklusses.
Im Flussdiagramm rechts ist zu Beginn noch der Check zu sehen, ob die Uhr
schon 10 Minuten erreicht hat. Ist das der Fall, dann wird der
Lautsprecher-Ausgang getorkelt (mit einer Frequenz von 1.000.000 / 916 / 2 =
545,9 Hz, irgendwo in der Mitte zwischen C'' und D'').
Ist das um jeweils eins erhöhte Register rPwm ebenfalls Null, dann
wird auch die LED L10 getorkelt (mit 1.000.000 / 916 / 256 / 2 = 2,13 Hz).
Das sollte reichen, damit der User bis zur nächsten Verwendung das Teil
von der Betriebsspannung abtrennt.
Ablauf der Musiksteuerung
Zu Beginn und mit jeder vollen Minute wird eine Melodie abgespielt. Die Melodien
dazu stehen als Tabellen im Flash, als Melody0, Melody1, etc., bis
Melody10. Der Beginn aller Melodien steht in der Tabelle Melodies
als mit zwei malgenommene Adresse.
Das Abspielen der Noten erfolgt mit dem 8-Bit-Timer/Counter TC0 an dessen
OC0A-Ausgang. Dieser ist bei Noten auf Torkeln eingestellt, bei stummen Pausen
auf Low.
Die Melodien sind mittels Musiknoten komponiert, die im Rechenblatt notes
der LibreOffice-Calc-Datei eieruhr_tn24_v2.ods
angegeben sind. Alle Noten sind mit ihren Sollfrequenzen in Hz gelistet, sie
erhalten in der ersten Spalte ihren Namen (Noten unter C ein angehängtes
m). Noten über H und unter C erhalten noch die Oktave als Ziffer.
Die Note ps stellt eine stille Pause dar: der Lautsprecher-Ausgang
bleibt für eine gewählte Dauer lang auf Null.
Für jede der 70 Musiknoten wird
der Teilerwert für den TC0,
der optimale Vorteilerwert,
der daraus resultierende CTC-Teiler minus 1 (CTC-Vergleichswert), und
die Dauer der Note von einer Sekunde Länge in OC0A-Torkelvorgängen
angegeben.
Daraus macht die Tabellenkalkulation zwei Tabellen für den Assembler-Quellcode:
die Noten-Namen erhalten mit .equ eine Zahl zwischen 0 und 70 zugeordnet,
alle Notennamen beginnen mit n, dann folgt die Notenhöhe C bis H,
dann die Oktave (falls nicht Null) und, bei Noten unterhalb von C, noch ein
m,
die NoteTable umfasst für jede Note
im ersten Byte den CTC-Vergleichswert für den TC0,
im zweiten Byte den Vorteilerwert für den TC0,
im dritten und vierten Byte die Anzahl Durchläufe für eine
Dauer von einer Sekunde (= 2 * Notenfrequenz).
Die Tabelle kann noch mehr:
Mit einer anderen Taktrate des Controllers können die Noten auch für
andere Taktfrequenzen berechnet werden. Taktfrequenzen bis 8 MHz
funktionieren.
Soll die Musik mit einem 16-Bit-TC abgespielt werden, gibt man bei TC einfach
eine 1 ein. Das geht dann für alle Noten ohne Vorteiler, die ersten beiden
Bytes der Notentabelle sind dann einfach die 16-Bit-CTC-Werte.
Wird bei manchen AVRs der Timer TC2 gewählt, dann hat der Vorteiler
auch noch weitere Zwischenwerte. Eine 2 im TC-Feld schaltet auf eine solche
Kombination um.
Die Melodien sehen dann z. B. so aus:
; Voel- ker hoert die Sig- na- le!
.db ne1,6,nd1,4,nps,2,nc1,8,nps,2,ng,6,nps,2,ne,2,nps,2,na,8,nps,2,nf,4,nps,4
Zuerst wird die Note E' (329 Hz) für die Dauer von 6/16 einer
Sekunde (= 0,375 s) gespielt, dann die Note D' (293 Hz) für
die Dauer von 4/16 Sekunden lang. Darauf folgt eine Pause von 2/16 Sekunden
Dauer, gefolgt von C' (262 Hz) von 0,5 Sekunden Dauer sowie einer
stummen Pause von 2/16 Sekunden. Danach kommen die Noten G (195 Hz), E
(166 Hz), A (217 Hz) und F (174 Hz), jeweils für unterschiedliche
Dauern und getrennt mit Pausen unterschiedlicher Länge.
Jede Melodie endet mit nEnd als Note (0xFF). Das stellt den Lautsprecher-Ausgang
auf Low und unterbindet die TC0-Timer-Interrupts.
Programmtechnisch
zeigt das Registerpaar X (XH:XL) auf die Melodietabelle, mit dem Abspielen jeder
Melodie steigt der Zeiger um zwei Positionen,
zeigt das Registerpaar Y (YH:YL) auf die nächste abzuspielende Note in der
Melodie, mit dem Abspielen jeder Note wird Y um vier größer.
Eine besondere Methode wurde für die Berechnung der Dauer verwendet:
Die Dauer der Note (1..255) wird in das Register rmp2 eingelesen. Sie
gibt an, wieviel 16-tel einer Sekunde die Note dauern soll.
Die Dauer der Note für eine Sekunde Läge wird aus der Notentabelle
in das Registerpaar rLenH:rLenL eingelesen.
Der 16-Bit-Abwärtszähler in rDurH:rDurL wird auf Null gesetzt.
Er gibt an, wieviele Nulldurchläufe der Ton haben soll und bestimmt die
Dauer des Tons.
Zu Beginn wird das Register rmp auf 16 (= 16/16-tel) gesetzt, denn der
eingelesene Wert entspricht 16 16-tel einer Sekunde.
Falls rmp2 größer oder gleich rmp ist, wird rLenH:rLenL
zu rDurH:rDurL addiert und anschließend um rmp vermindert.
Falls dabei Null herauskommt, ist der Wert in rDurH:rDurL fertig. Falls
bei der Verminderung um rmp (= 16) kein Carry eintritt, wird der Schritt
nochmals wiederholt.
Falls bei der Verminderung weder Null erreicht wird, aber die Carry-Flagge
gesetzt ist, wird der Wert in rLenH:rLenL nach rechts geschoben und damit
halbiert. Falls dabei eine Eins in das Carry herausrollt, wird der halbierte Wert
in rLenH:rLenL um Eins aufgerundet. Der Wert in rmp wird ebenfalls
um ein nach rechts geschoben, so dass sich die Reihe 8, 4, 2 und 1 ergibt. Erreicht
rmp dann Null, ist der Wert ebenfalls fertig. Wenn nicht, wird der
vorausgehende Schritt nochmals wiederholt.
Das Dauer-Byte kann mit Werten über 16 auch auf mehr Sekunden Dauer gesetzt
werden. Bei Noten bis H''' kann das Längen-Byte bis zu 255 betragen,
was eine Tondauer bis 16 Sekunden ergibt. Bei höheren Tönen
funktioniert das nicht mehr, ihre Dauer ist niedriger begrenzt. Bei sehr hohen
Tönen ist es eine Sekunde (diese Maximalwerte siehe Notentabelle).