ATtiny 13 als Vorteiler
Neulich fragte mich ein Kollege nach einer Bezugsquelle für einen
mindestens siebenstelligen Ereigniszähler. Ein pneumatisches Bauteil in
einer Industrieanlage hielt deutlich weniger lange als vom Hersteller
versprochen, und er wollte dem elektrischen 24V-Pneumatikventil einen
elektronischen Zähler parallelschalten, um herauszufinden, nach wie
vielen Schaltspielen das Pneumatikbauteil schlapp macht.
Eine oberflächliche Suche nach dem Begriff "Ereigniszähler"
erbrachte bei Reichelt nur einen fünfstelligen Fittness-Schrittzähler,
den man hätte "schlachten" müssen, um den mechanischen Pendelkontakt
rauszuwerfen und einen Spannungseingang anzuschließen.
Bei Conrad erbrachte der Suchbegriff lediglich einige
sechstellige Zähler mit LC-Display. Später hat der Kollege
herausgefunden, daß die Suche nach "Impulszähler" dann doch einige
geeignete achtstellige Ereigniszähler auswirft.
Ich hatte aber bereits angefangen, nach einem möglichst
einfachen Vorteiler 10:1 bzw. 100:1 zu suchen, der sich direkt aus der
Stromversorgung eines Zählermoduls bzw. umgebauten Schrittzählers
versorgen läßt (die meisten dieser Geräte werden aus einer
3V-Lithium-Knopfzelle gespeist).
Es gibt zwar allerlei CMOS-Zähler-ICs, aber mit einem ATtiny
13 läßt sich das Problem mit besonders wenigen Bauteilen und einigen
trivialen Zeilen BASCOM-Code erschlagen. Nicht so ganz offensichtlich
ist allerdings, wie man den ATtiny möglichst häufig im Zustand
"Powerdown" hält, um maximal Energie zu sparen.
Aus dem Zustand "Powerdown" (in dem der ATtiny-Taktoszillator
abgeschaltet ist), kann man den Controller nicht mit einem
flankengetriggerten, sondern nur mit einem pegelgetriggerten Interrupt
INT0 herausholen, und dieser spricht nur auf Low-Pegel an, was einen
Invertertransistor erfordert hätte.
Besser geeignet sind Pin Change Interrupts. Zumindest in der
(relativ alten) BASCOM-Demo-Version werden sie jedoch nicht vollständig
mit Hochsprache-Befehlen unterstützt, daher ist es besser, direkt die
Register zu konfigurieren.
Pin Change Interrupts reagieren auf steigende UND auf fallende
Flanken; in dieser Anwendung ist das aber durchaus erwünscht, weil man
den Controller auch während der High-Phase des Eingangssignals in
Powerdown schicken kann. Er verbraucht daher (ähnlich wie ein
CMOS-Logik-IC) nur während der Flankenwechsel Strom.
Das Timing muß man eventuell im Programm an die Frequenz der
Eingangsimpulse und die Geschwindigkeit des nachgeschalteten Zählers
anpassen - einerseits sollen keine Eingangsimpulse verlorengehen,
andererseits müssen die Ausgangsimpulse lang genug sein, um den
nachgeschalteten Zähler ansprechen zu lassen. Die obere Grenzfrequenz
habe ich nicht getestet, bei ein paar hundert Hz dürfte aber "Schluß"
sein.
Auch der Wert für Kondensator C1 muß möglicherweise angepaßt
werden. Die Zeitkonstante T = R1 * C1 sollte deutlich kleiner sein als
die Impulsdauer, andererseits aber so lang sein, daß "Schmutz" (z.B.
Schalter-Prellen) weggefiltert wird.
Download des Bascom-Quelltextes: 0116-t13-vorteiler.zip
' Vorteiler 10:1 für einen Ereigniszaehler 0 - 999999
' Compiler: BASCOM 2.0.7.5 Demo
' Gezaehlt werden positive Flanken an PinB.1
' nach 10 Impulsen wechselt PortB.4 entweder fuer 10 msec auf High (auskommentiert)
' oder wird erst bei der nächsten Flanke high -> low zurückgestellt (aktiv)
$Regfile = "Attiny13.dat"
$Crystal = 1200000
$Hwstack = 32
$Swstack = 8
$Framesize = 8
DDRB = &B00010000 ' nur PortB.4 ist Ausgang
DIDR0 = &B00011101 ' Digitaleingaenge bis auf PinB.1 deaktiviert
GIMSK.PCIE = 1 ' Pin Change Interrupt PortB aktiviert
PCMSK.PCINT1 = 1 ' nur Bit 1 (PinB..1) wird durchgelassen
SREG.7 = 1 ' enable Interrupts
Dim I As Byte
Dim M As Byte
Const Overflow = 10 ' ggf. 100 fuer Teilerverhaeltnis 1:100
Do
If PinB.1 = 1 Then
If M = 0 Then ' M verhindert mehrfache Inkrmentierungen von I
Incr I
M = 1
End If
If I >= Overflow Then
PortB.4 = 1
I = 0
' Waitms 10 ' PortB.4 10 msec auf high, dann wieder low
' PortB.4 = 0
End If
' Waitms 1 ' ggf. gegen Kontaktprellen am Eingang
Powerdown
End If
If Pinb.1 = 0 Then
PortB.4 = 0 ' Rueckstellen von PortB.4 erst bei high-low-Flanke
M = 0
Powerdown
End If
Loop
End