Home ==> Inhaltsverzeichnis ==> 5-6-Zähler
Logo

5-6-Zähler



0 Seitenindex
  1. Die Aufgabe
  2. Schritte zur Lösung mit CMOS
    1. Ein Impulsformer in CMOS
    2. Ein Zähler bis 5/6 in CMOS
    3. Die Relaissteuerung in CMOS
    4. Eine Anzeige in CMOS
      1. Siebensegmentanzeige in CMOS
      2. Anzeige mit sieben LEDs
    5. Impulsdiagramm der CMOS-Schaltung
  3. Schritte zur Lösung mit Mikrocontroller
    1. Auswahl des Controllers
    2. Kontakt und Controller
    3. 5/6-Zähler mit Controller
    4. Relaissteuerung mit Controller
    5. Schaltung mit Controller
      1. 7-Segmentanzeige mit Controller
      2. Anzeige mit 7 LEDs mit Controller
      3. Beides mit ATmega8
    6. Software für den Controller
    7. Videos vom Controller
  4. Vergleich und Fazit
Die Schaltbilder für dieses Projekt gibt es als LibreOffice-Draw-Datei hier, die Berechnungen gibt es hier als LibreOffice-Calc-Datei.

1 Die Aufgabe

Man kennt das: am Anfang steht eine Idee oder eine Aufgabe, irgendwas soll irgendwie gesteuert werden. Aber wie soll man das anfangen, wie kriegt man so ein Projekt ans Laufen? Dieses Dokument hier zeigt, wie man eine etwas anspruchsvollere Aufgabe angeht und wie man sich so einer Lösung annähert.

Ma Ba hat mir folgende Aufgabe gestellt:
Ich habe einen Kontakt der 5 mal schaltet und dann ein Relais für 5sec
schalten soll. Beim 6. mal soll ein 2. Relais (5sec) schalten. Dann beginnt
es wieder von vorn.
LEDs sollen Anzeigen wie oft der Kontakt schon geschaltet hat. (1-6)
Soll ein Ersatz für die Fahrgassenschaltung von einer Sähmaschiene werden.
12V Bordspannung.
Nun denn, eine klare Aufgabenbeschreibung.

Der Lösung kann man sich auf zweierlei Weise nähern: einmal auf klassische Weise, mit einigen CMOS-Bausteinen, oder mit einem einzigen IC, mit einem Mikrocontroller.

Es wird im Folgenden aufgezeigt, wie das geht.

2 Schritte zur Lösung mit CMOS

Die Aufgabe wird erst mal in Teilschritte zerlegt:
  1. Alle mechanischen Kontakte prellen. Damit die ganze Impulszählerei sauber funktioniert, muss erst mal ein Impulsformer her, der nur Impulse mit einer festlegbaren Mindestdauer zulässt und alles Prellen wirksam unterdrückt.
  2. Als zweites brauchen wir einen Zähler bis sechs, der die Impulse zählt, die beiden Relais beim Zählerstand fünf und sechs startet und sich danach wieder auf Null stellt.
  3. Die beiden Relais sollen für jeweils fünf Sekunden lang an bleiben. Das riecht nach zwei Monoflops.
  4. Die Impulszählerei und -anzeige kann man auf zweierlei Weise lösen: mit einer Sieben-Segment-Ziffer oder mit sieben einzelnen Leuchtdioden. Beides ein wenig unterschiedlich, aber machbar.

2.1 Ein Impulsformer in CMOS

Damit der Impuls erst dann zum Zähler gelangt, wenn er eine bestimmte Dauer erreicht hat, brauchen wir eine Kondensatormimik, die erst nach einer gewissen Zeit den Impuls durchlässt.

Erfahrungsgemäß dauert diese Prellzeit etwa 10 bis maximal 20 Millisekunden. Der Schalter, der beim Schließen des Kontakts einen Eingang auf Null zieht, darf dies also erst nach ca. 25 ms tun.

Kontakt-Entpreller Damit er das tut, kommt er in die nebenstehende Schaltungsmühle. Der im offenen Zustand mit dem 10k-Widerstand R1 auf Plus gezogene Kontakt lädt über R2 mit 15 kΩ den Kondensator C1 mit 2,2 µF auf die Betriebsspannung auf, parallel zum R3 mit 47 kΩ.

Der NAND-Schmitt-Trigger 4093-1 hat dann an beiden Eingängen positive Betriebsspannung, sein Ausgang geht auf Low.

Schließt der Kontakt, dann wird sowohl der Widerstand R1 als auch R2 auf Low gezogen. Das entlädt den Kondensator C1 bis herab auf eine Restspannung von Ub * R2 / (R2 + R3), bei 12 V sind das 2,9 V.

Unterschreitet die Spannung am Kondensator die untere Schwellspannung des 4093-NANDs, ca. 5,9 Volt, dann geht sein Ausgang auf Eins. Das dauert ein wenig, da die RC-Kombination eine Verzögerung bewirkt.

Spannung am Kondensator bei geschlossenem Kontakt Wie lange das dauert, kriegt man mit einer Tabellenkalkulation heraus: ein Kondensator beginnt bei 12 V und wird mit einem Strom von I = U / R = UC / 15 kΩ = 0,8 mA entladen. Nimmt die Spannung am Kondensator ab, dann nimmt auch der Entladestrom ab und es kommt der Strom über die 47 kΩ hinzu. Die Spannung des Kondensators errechnet sich zu ΔU = I * Δ t / C, was man in der Tabellenkalkulation in kleinen Schritten (hier waren es 0,5 ms) zu der Entladekurve hingerechnet kriegt.

Spannung am Kondensator bei geoeffnetem Kontakt Wenn man nun den geschlossenen Schalterkontakt wieder öffnet, dann lädt sich der Kondensator von seinen 2,9 V ab wieder auf, und zwar sowohl über die Reihenschaltung von R1 und R2 als auch parallel dazu über R3. Erreicht die Spannung die obere Schwellspannung des 4093, bei 12 V Betriebsspannung sind das ca. 7,8 V, dann geht der Ausgang wieder auf Null.

Hat man einen sehr groben Schalter mit längerer Prellzeit, macht man einfach C1 größer, z. B. mit 3,3 oder 4,7 µF.

Einfach, aber wirkungsvoll. Man sieht auch, dass die drei Widerstände so dimensioniert sind, dass sowohl beim Schließen als auch beim Öffnen dieselbe Verzögerung herauskommt, nämlich ca. 27 ms. Das sollte auch für Sähmaschinen-Kontakte ausreichen.

2.2 Ein Zähler bis 5/6 in CMOS

Mit den sauber entprellten Impulsen geht es jetzt auf einen Zähler. Der muss eigentlich nur drei Bit zählen können (von 0 bis 6), der nächstgrößere kann vier. Und es gibt ihn im Zweierpack in einem 16-poligen Gehäuse. Und zwar zwei davon: nämlich den 4518 und den 4520: der eine zählt binär, der andere dezimal. Da wir sowieso nur bis sechs zählen und dann wieder von vorne anfangen, gehen beide.

5/6-Zähler Der Zähler zählt die Impulse an seinem CLKA-Eingang und gibt den Zählerstand an seinen Q1A-, Q2A- und Q3A-Ausgängen aus. Sind sowohl der Q3A- als auch der Q1A-Ausgang high, dann ist der Zählerstand fünf erreicht, der Ausgang von 4093-NAND-2 geht dann auf Low und triggert damit an dessen Trigger-Minus-Eingang den Monoflop, der das Relais 1 für fünf Sekunden anschaltet.

Ist sowohl der Q3A- als auch der Q2A-Ausgang high, dann wird der Ausgang des 4093-NAND-3 low und der Ausgang des 4093-NAND-4 geht auf High. Über ein Verzögerungsglied aus R4 und C2 setzt dieses den Zähler kurz nach Erreichen dieser Sechs wieder auf Null. Diese Dauer reicht aber aus, um damit am positiven Trigger-Eingang des zweiten Monoflops das zweite Relais zu starten.

Dauer des Rücksetzimpulses Das ist die Dauer des Rücksetzimpulses, wenn der Sechs-Erkenner zuschlägt: das RC-Glied aus R4 und C2 verzögert das Rücksetzen um ca. 12 µs, lang genug, um auch andere Eingänge wie den Trigger-Eingang am Monoflop und die Rücksetz- Eingänge anderer Zähler mit dem Impuls zu versorgen. Wenn die Ladezeit um ist, erfolgt der Reset auch des 4518/20-Zählers A, wodurch der Sechs-Zustand aufgehoben wird und sich der Kondensator wieder entlädt.

Der menschliche Betrachter guckt nicht schnell genug und wird nichts von alledem sehen.

2.3 Die Relaissteuerung in CMOS

Nun brauchen wir noch einen Schaltungsteil, der die beiden Relais noch für genau 5 Sekunden Dauer unter Strom setzt. So was macht man mit einem Monoflop: er erhält von Fünf-Erkenner einen negativen oder vom Sechs-Erkenner einen positiven Trigger-Impuls und legt dann los. Wieder spielt eine RC-Kombination die erste Geige. Ein Widerstand lädt einen Kondensator, hier einen 4,7 µF-Elko. Errreicht der ein bestimmtes Spannungsniveau, ist die Zeit zu Ende und der Q-Ausgang des Flipflops geht wieder auf Low. Bis zum nächsten Trigger-Impuls ...

Relais-Schaltung Der 4098 enthält in einem 16-poligen Gehäuse gleich zwei solcher Monoflops. Sie können sowohl mit einer ansteigenden (positiven) als auch mit einer abfallenden Flanke (negativen) getriggert werden. Die beiden R und C sind auf fünf Sekunden eingestellt.

Die Ausgänge QA und QB treiben über NPN-Transistoren die beiden Relaisspulen an, da die Ausgänge selbst nur ganz wenige mA liefern können, so dass es alleine für die Spulen nicht reichen würde. Auch die invertierten Ausgänge /QA und /QB könnten verwendet werden, wenn man z. B. lieber zwei PNP-Transistoren nehmen wollte.

Die beiden Rückschlagdioden 1N4001 müssen unbedingt sein, denn so eine Relaisspule nimmt einem das Abschalten des Spulenstroms sehr übel: sie produziert einige tausend Volt in der Stromgegenrichtung. Damit die Spule gar nicht erst auf die Idee kommt, den armen kleinen Transistor mit tausenden von Volt zu zerschießen, leitet die Diode schon mal alles in einen Kurzschluss, was die Spule beim Abschalten so zu produzieren droht.

2.4 Eine Anzeige in CMOS

Wie schon geschrieben, könnte die Anzeige des Zählzustands auf zwei verschiedene Arten erfolgen: mit einer Sieben-Segment-Ziffer oder mit sechs einzelnen LEDs. Beides sieht ein wenig anders aus.

2.4.1 Siebensegmentanzeige in CMOS

Eigentlich brauchen wir zum Zählen für die Sieben-Segment- Anzeige gar keinen eigenen Zähler, denn der A-Zähler im 4518/20 liefert an seinen QA-Ausgängen ja schon den Zählerstand. Da der 4518/20 aber halt mal zwei Zähler an Bord hat, lassen wir den auch die Takte vom Entpreller zählen und benutzen den vom A-Zähler produzierten Rücksetz-Impuls auch zum Rücksetzen des B-Zählers.

Sieben-Segment-Anzeige Das ist die Schaltung: sie produziert aus den drei QB-Ausgängen die sechs Ziffern auf der Anzeige.

Die Übersetzungsarbeit von binär in 7-Segment verrichtet ein 4511, die Anzeigeneinheit ist eine solche mit gemeinsamer Kathode.

Die Anzeige hat einen Schönheitsfehler: wenn der Zustand Sechs eintritt, dann müsste sie eigentlich auch Sechs anzeigen. Das tut sie auch, aber nur unsichtbare 12 µs lang: dann wird die Anzeige durch den Rücksetzimpuls ja wieder auf Null gesetzt. Null ist bei dieser Anzeige also eher sechs. Erst wenn der siebte Impuls vom Kontakt einfliegt, stimmt es wieder.

Wenn wir das vermeiden wollten, kämen wir in arge Nöte: entweder müssten wir den Decoder so umbiegen, dass er statt Null sechs anzeigt, oder wir müssten den Zähler mit einem Preset ausstatten, der den Zähler beim Reset auf Sechs setzt und beim nächsten eintreffenden Impuls auf Eins. Auf jeden Fall kriegen wir einen argen Verhau. Mit Mikrocontroller wär das nicht passiert, der kann das alles, wenn man es ihm nur per Programm beibringt.

2.4.2 Anzeige mit sieben LEDs

Die Anzeige mit sieben Einzel-LEDs hat das Problem nicht: bei der ist das nullte Lämpchen einfach das sechste und es ist nur die Frage, wie man die Lampen anordnet.

Anzeige mit sechs LEDs Diese arbeitet mit einem Johnson-Zähler 4022. Der schaltet immer zum nächsten Q-Ausgang, wenn ein Impuls eintrifft. Auch er wird mit dem kurzen Sechs-Impuls auf Null zurückgestellt.

2.5 Impulsdiagramm des Ablaufs in CMOS

Impulsdiagramm Eigentlich fängt so ein Projekt damit an, aber da hatten wir ja noch nicht alle Teilstufen bekannt. Nun denn, hier zum Abschluss das A und O jeden Digitalprojektes: das Impulsdiagramm.

Nachdem nun alle Einzelteile klar sind, zeichnen wir den Ablauf in ein Impulsdiagramm. Ich habe hier mal drauf verzichtet, alle Abhängigkeiten in das Diagramm einzuzeichnen. Das sollte man zumindest im Kopf haben: der Entprellausgang kommt erst 25 ms nach dem Schließen des Kontakts, die Fünf- und die Sechs- Erkennung starten die Relais sofort. Da wir aus der obigen Beschreibung nicht genau wissen, wie schnell oder langsam die Kontakte geschlossen und wieder geöffnet werden, wissen wir auch nicht, ob sich die beiden Relais überlappen können.

Aber: so sieht ein Impulsdiagramm nun einmal vereinfacht aus. Und wer es mag, kann sich mit geschwiffenen Pfeilen auch noch die Abhängigkeiten hineinzeichnen: welcher Impuls oder Zustand führt nach welcher Verzögerung zu welchem anderen Impuls.

Stückliste der CMOS-Varianten Das ist alles, was man so braucht, aufgegliedert nach den beschriebenen Teilschaltungen. Die beiden Gesamtsummen liegen bei etwa 15 Euronen, sind also von recht tragbarem Umfang. Der Unterschied zwischen beiden Anzeige-Varianten ist nicht signifikant.

3 Schritte zur Lösung mit Mikrocontroller

So, und nach der komplizierten nun die einfachere Variante: mit nur einem einzigen 14-poligen Mikrocontroller. Weil der nur maximal 5,25 V verträgt und nicht wie die CMOS-Dinger bis zu 18 V, braucht es noch zusätzlich einen dreipoligen Spannungsregler für die Herabsetzung der 12 V auf 5 V.

3.1 Auswahl des Controllers

Auswahl des Controllers mit avr_sim Um den Controller auszuwählen, geben wir im avr_sim (kriegt man auf dieser Webseite für Windows oder Linux kostenlos heruntergeladen) ein: Mit diesem AVR-Typ ATtiny24 beginnen wir die Entwicklung.

3.2 Kontakt und Controller

Pull-Up und Hysterese beim INT0-Eingang Wie die CMOS-Zähler auch würde es so ein ATtiny24 ebenso krumm nehmen, wenn der Schalter 15 mal prellt, bevor er endgültig zu- oder aufmacht. Im Gegensatz zur CMOS-Mimik bringt aber so ein ATtiny24 schon so einiges mit, was das Schalten mit externen Schaltern erleichtert:
  1. Sie haben einen zuschaltbaren Pull-Up-Widerstand von ca. 50 kΩ eingebaut, der offene Eingänge auf die positive Betriebsspannung ziehen kann. Wenn der Pin in seinem Datenrichtungs- Register DDRB eine Null stehen hat, in seinem Ausgangsregister PORTB aber eine Eins, dann wird der Pull-Up-Widerstand aktiviert. Das spart schon mal einen Widerstand und seine Verdrahtung - und ersetzt sie durch zwei Instruktionen des Herrn Professors.
  2. Noch dazu haben alle Eingänge des ATtiny24 eine eingebaute Hysterese, so dass man gefahrlos langsame Spannungsänderungen an den Eingängen beim Laden/Entladen von Elkos ohne weiteres bewältigt. Ganz so wie ein 4093, aber nicht so arg üppig. Für unseren Kontakt reicht es jedenfalls.
Damit vereinfacht sich unsere Eingangsschaltung aus der CMOS-Entprellerei schon wieder etwas: kein 4093, den 47k machen wir per Software, ansonsten bleibt alles beim Alten.

Der INT0-Eingang kann aber noch mehr als nur die schnöde Impulsformerei: den kann man so programmieren, dass er den Prozessor in seiner Arbeit unterbricht, durch Setzen des Bits INT0 in seinem Interrupt-Maskenregister GIMSK). Mit den beiden Bits ISC00 und ISC01 im Register MCUCR kann man zudem einstellen, ob er nur bei positiven Flanken, nur bei negativen Flanken oder, wie in unserem Fall, bei beiden diese Unterbrechung durchführt.

Mit dem INT0-Interrupt kann man sich das nervöse Herumgerenne im Programm sparen, ob denn die Taste schon gedrückt oder losgelassen sei. Der INT0-Interrupt schlägt schon nach vier Mikrosekunden zuverlässig zu, so dass wir keine Kontaktänderung verpassen.

3.3 5/6-Zähler mit Controller

Nun könnten wir beim Zuschlagen des INT0-Interrupts mit fallender Flanke einfach eines der 32 vorhandenen Register um Eins nach oben zählen und mit der CPI-Instruktion nachschauen, ob schon fünf oder sechs erreicht ist. Aber das wäre ja mal wieder viel zu einfach.

Nein, wir bauen einen ganz anderen Zähler. Für die LED-Anzeige oder den 7-Segment-Anzeiger brauchen wir nämlich eine ganz andere Kombination von Zähler:
  1. LED: Nacheinander gehen die LEDs L1, L2 bis L6 an, wenn ein Impuls eintrifft. Wir mässten also eine Eins nach links schieben, um die Lämpchen korrekt anzuschalten. Da die Lampen an die Portausgänge von Port A des Controllers angeschlossen werden, kriegen wir die folgende Reihe:
    ImpulsBinaerwert auf Port AHex-Wert
    keiner0b0000.00000x00
    10b0000.00010x01
    20b0000.00100x02
    30b0000.01000x04
    40b0000.10000x80
    50b0001.00000x10
    60b0010.00000x20
    70b0000.00010x01
    Und so weiter und so weiter ...
    Port A des Controllers So sieht das Gewerk im Port A beim erreichten Zählerstand 1 aus: Mit dem siebten Impuls springt die LED-Anzeige zurück an die zweite Position der Liste und zeigt das erste Lämpchen an. Mit dem Controller ist also etwas möglich, was mit CMOS nur sehr aufwändig ginge: der Rücksprung erst beim siebten Impuls, dann aber auf Eins.
  2. Siebensegment: Mit der Sieben-Segment-Anzeige ergibt sich eine gänzlich andere Reihenfolge. Sie geht so:
    AnzeigeBinaerHexadezimal
    0b0011.11110x3F
    0b0000.01100x06
    0b0101.10110x5B
    0b0100.11110x4F
    0b0110.01100x66
    0b0110.11010x6D
    0b0111.11010x7D
    Eine solche Reihe hätten wir beim besten Willen nicht mit CMOS hingekriegt, jedenfalls nicht auf einer Euro-Platine voll mit UNDs und ODERs. Der Mikrocontroller macht es ganz einfach möglich.
Wie kriegt man nun dem Controller die beiden Reihen beigebracht?

Das geht mit den folgenden beiden Zeilen ganz einfach:
  
  LedReihe:
    .db 0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00
  SiebenSegReihe:
    .db 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x00
  
  
Das schreibt zwei Tabellen in den Flash-Speicher des Controllers. Weil die AVRs 16-Bit-Werte in ihrem Flash-Speicher haben, unsere .db-Direktive nacheinander aber 8-Bit-Werte einliefert, packt der Assembler jeweils zwei davon in eine Speicherzelle: erst das niedrigere Byte (LSB), dann das höhere (MSB).

Das ist auch der Grund, warum beiden Reihen hinten ein 0x00 hinzugefügt wurde: das Byte für den Anfang und die sechs Zähl-Bytes wären insgesamt sieben, und da immer zwei Bytes in eine Speicherzelle kommen, bliebe am Ende das MSB unbestückt. Aus unbestückten MSBs macht der Assembler eh Nullen, daher könnten wir uns diese 0x00 auch sparen.

Aber die 0x00 brauchen wir unbedingt, denn sie ist ja das Zeichen dafür, dass die Tabelle jetzt zu Ende ist und der Zeiger zurück auf die Eins muss.

Mit den folgenden Instruktionen kann man das erste Byte aus dem Flash-Speicher in das Register R16 lesen:
  
    ldi ZH,High(2*LedReihe)
    ldi ZL,Low(2*LedReihe)
    lpm R16,Z+
  
  
Die Funktionen High und Low trennen die 16-Bit-Adresse der LedReihe, die sich mit zwei malgenommen in den Klammern befindet, in ihre 8-Bit-Bestandteile auf: High liefert die oberen 8 Bits (MSB), Low die unteren (LSB).

Aber warum nur statt LedReihe 2*LedReihe? Nun, man möchte ja gerne auch auf die in der Tabelle gespeicherten MSBs zugreifen und nicht nur auf die LSBs. Daher braucht man ein weiteres Bit, das darüber entscheidet, ob man das LSB oder das MSB auslesen möchte, die ja beide an der Adresse LedReihe im Flash-Speicher stehen. Das 2*LedReihe macht Platz für dieses zusätzliche Bit.

Das kann man prima dazu verwenden, um festzustellen, welcher Code in der Reihe die Nummer Fünf hat, denn das soll ja das erste Relais einschalten. Um den zu lesen, addieren wir einfach fünf zur verdoppelten Anfangsadresse der LedReihe und LPM liefert uns den Code an der fünften Stelle in der Tabelle:
  
    ldi ZH,High(2*LedReihe+5)
    ldi ZL,Low(2*LedReihe+5)
    lpm rRel1Code,Z+
    lpm rRel2Code,Z
  
  
Mit dem Plus hinter dem Z nutzen wir eine schöne und ansprechende Besonderheit der AVR-Instruktions-Bastler: nachdem das Byte gelesen ist, wird die Adresse in Z automatisch um Eins erhöht. Und schwupps, kriegen wir mit einem weiteren LPM auch noch den Code für das zweite Relais aus der Tabelle gelesen. Vielen Dank auch nach Norwegen und an ATMEL.

3.4 Relaissteuerung mit Controller

Nachdem nun die Fünf und die Sechs erkannt sind, startet das Relais seine Arbeit: der Relais-Ausgang wird aktiviert. Der muss nun für fünf Sekunden lang anbleiben.

So ein ATtiny24 wird von seinem internen Taktgenerator mit einer Million Takten pro Sekunde angetrieben. Um das Relais fünf Sekunden lang angezogen zu lassen, müssen wir folglich 5.000.000 Takte abzählen und erst beim Erreichen dieser Anzahl den Pin wieder ausschalten.

So etwas kann man zwar durch Zähler mit Schleifen erledigen, aber da wir nicht wissen, ob vielleicht der Kontakt wieder zuschlägt und parallel zum Relais 1 auch noch Relais 2 anziehen soll, wird das eine komplexe Springerei, jedenfalls etwas, was wir ungern programmieren möchten.

Für so was kann man besser die beiden Timer verwenden, die so ein ATtiny24 an Bord hat. Die beiden Timer heißen TC0 und TC1, TC steht für Timer-/Counter. TC0 ist 8 Bit breit, zählt von 0 bis 255 und fängt dann wieder bei Null an. TC1 ist 16 Bit breit, zählt von 0 bis 65.535 und beginnt dann wieder bei Null.

TC0 bei der Arbeit Beide Zähler haben aber noch etwas: einen Vorteiler. Der teilt den Takt von 1 MHz erst mal durch 1, 8, 64, 256 oder 1.024 und taktet dann den eigentlichen Zähler. Mit dem 8-Bit-Zähler kann man daher maximal bis 1.024 * 256 = 262.144 zählen, bei fünf Sekunden müssten wir dann 19,0734 solcher Überläufe abwarten und dann den Relais-Ausgang abschalten. Stellen wir den Vorteiler auf 256 ein, dann wären es 76,29 mal, bei 64 wären es 305,17 mal. Die beiden ersten Fälle kann man mit einem 8-Bit-Register ohne Weiteres abzählen. Für den dritten Fall bräuchten wir hingegen einen 16-Bit-Zähler.

Über die Kommastellen brauchen wir uns eigentlich keine Gedanken zu machen, denn der interne Taktgenerator ist mit 10% ziemlich ungenau. Und wie lange das Relais braucht, um anzuziehen oder abzufallen, ist auch so gut wie unbekannt (es sei denn wir messen das). Und meistens braucht man die fünf Sekunden auch nicht sehr genau, es reicht irgendwas zwischen 4,5 und 5,5 s völlig aus. Wenn wir eine richtige Uhr bauen würden, wäre das zu viel Abweichung, aber für eine Sähmaschine reicht's.

Wenn wir das noch etwas genauer treffen wollen, könnten wir den 8-Bit-Timer TC0 auch in den CTC-Modus bringen. Bei dem Modus zählt er nicht bis 255, sondern nur bis zu dem Wert, den wir in sein Vergleichsregister A hinein geschrieben haben (CTC = Clear Timer on Compare). Das gibt ein wenig genauere Teilerwerte. In der LibreOffice-Tabellenkalkulation hier findet man das Tabellenblatt "tn24timer", mit dem man für die Vorteiler 256 und 1.024 Genaueres herausfinden kann. Eigentlich bräuchten wir das aber gar nicht, bloß Spielerei.

TC1 bei der Arbeit Das trifft auch auf den TC1 zu. Da dieser bis maximal 65.535 zählen kann, kann die Zählerei der CTC-Durchläufe bei diesem entfallen, weil dieser maximal bis 1.024 * 65.536 = 67.108.864 zählen kann, was etwas mehr als 67 Sekunden entspräche. Den kann man daher mit seinem Compare-Wert exakt genug auf die 5 Sekunden einstellen. Bei einem Vorteilerwert von 256 sind das 5.000.000 / 256 = 19.531. Da der ATtiny24 immer einen Wert erkennen kann, wenn er einen weniger hat, schreiben wir 19.530 in das 16-Bit-Vergleichsregister A von TC1. Damit unterbricht der TC1 den Prozessor nach 19.531 Zählertakten bzw. nach sechs Sekunden und schaltet sowohl das Relais 2 aus als auch sich selbst.

3.5 Die gesamte Schaltung mit Controller

Die Schaltung kann, je nachdem, ob sie mit sieben einzelnen LEDs oder mit einer Sieben-Segment-Anzeige ausgestattet wird, ein wenig anders aussehen, daher gibt es zwei Schaltbilder.

3.5.1 Schaltung mit 7 LEDs und Controller

Schaltbild mit Einzel-LEDs und ATtiny24 Das ist schon die gesamte Schaltung: Mimimalbeschaltung eines Controllers dank fortgeschrittener Controller-Technik.

Für die Stromversorgung des Controllers brauchen wir erst mal einen Spannungsregler 78L05. Der bleibt mit den wenigen mA, die so ein Controller und die beiden LEDs brauchen, unterausgelastet.

Die sechs LEDs sind an den Port A des Controllers angeschlossen. Da immer nur gleichzeitig eine einzige LED an ist, kann man sich den Verhau mit sechs LED- Widerständen auch sparen und eine einzige mit Common-Kathoden-Technik anschließen. Die sechs LEDs sind rot, eine siebte LED ist grün: sie zeigt den Zustand des Kontakts an und geht nur dann aus, wenn der Kontakt geschlossen wird.

An das siebte Port-A-Bit ist ein Jumper angeschlossen: er schaltet im geschlossenen Zustand auf das Sieben-Segment-Display um. Die Software kann daher beides und braucht nicht ausgetauscht zu werden.

Der Kontakt ist, wie bei der CMOS-Schaltung mit R und C, an das Port-Bit PB2 angeschlossen, der 47k-Widerstand wird als interner Pull-Up zugeschaltet. Jeder Pegelwechsel an diesem Pin löst einen INT0-Interrupt aus.

Der Reset-Eingang wird nur beim Programmieren des ICs gebraucht, das in der Schaltung erfolgt (das Programmiergerät wird an die Schnittstelle ISP6 angeschlossen).

Die beiden Port-Ausgänge Port-B-0 und Port-B-1 schalten die beiden Relais an und ab. Durch die Zwischenschaltung eines Treibertransistors können beide Relais mit 12V betrieben werden, wofür es eine größere Auswahl an Typen gibt als für 5V.

Bauteil-Liste mit Controller und Eintel-LEDs Das sind alle Bauteile, die man dafür braucht. Mit knapp mehr als 10 Euronen ist man dabei.

Den ATtiny24(A) liefere ich gerne fertig programmiert, wenn man mir einen Brief mit einem frankierten Rückumschlag und mit drei 85¢-Briefmarken schickt.

3.5.2 Schaltung mit 7-Segmentanzeige und Controller

Controller mit Sieben-Segment-Anzeige Das hier ist die Schaltung mit einer Sieben-Segment-Ziffer. Da hierbei alle sieben Ziffern gebraucht werden, entfällt hier die grüne Betriebsspannungs-LED. Da bei 7-Segment-Darstellung immer mehr als ein einziges Segment an ist, brauchen wir für jedes Segment einen eigenen Vorwiderstand.

Da bei der Null sechs LEDs an sind und der Spannungsregler 78L05 nur 100 mA kann, darf der Segment-Strom 15 mA nicht überschreiten. Das ist in der dargestellten Dimensionierung der Fall. Wer größere LEDs betreiben will, schaltet einen Darlington-Treiber ULN2001/2/3 an den Port A und betreibt die LEDs direkt aus dem 12V-Bordnetz oder nimmt einen 7805 als Spannungsregler.

Das ist auch schon alles, wenn wir noch den Jumper 1 schließen: dann nimmt der Controller die Sieben-Segment-Tabelle und spult sie statt der LED-Tabelle ab.

Bauteil-Liste für Controller mit 7Segment-LED Das sind alle Bauteile, die man dafür braucht. Der Preis ist nicht sehr unterschiedlich bei beiden Varianten.

3.5.3 Schaltung mit beidem und ATmega8

Schaltbild mit ATmega8 Wer sich nicht entscheiden kann und gerne beides hätte, braucht einen etwas größeren Controller mit mehr Pins. Der kann mit seinem C-Port die sechs LEDs und mit seinem B-Port die Siebensegment-Anzeige gleichzeitig ansteuern. Der Punkt der Siebensegment-Anzeige kann hier noch den Zustand am INT0-Eingang anzeigen.

Die nötigen Umbauten am Programm sind bescheiden, nur muss man die Tabelle so umgestalten, dass sie beide Ports jeweils hintereinander hat und mit zwei LPMs und OUTs jeweils beide Ports bedient. Und man muss ein wenig aufpassen beim Fünfer- und Sechser-Erkennen, dass man die richtige Portkonfiguration aus der Tabelle ein liest.

Weil bei dieser Variante bis zu neun LEDs gleichzeitig an sein können, ist ein größerer Spannungsregler sinnvoll.

3.6 Die Software für den Controller

Die Software für den Controller ist in Assembler geschrieben, den Quellcode gibt es hier im asm-Format und zum Anschauen im Browser hier.

Beim Programmieren des gerade mal 167 Worte langen Hexcodes braucht man keine Fuses zu ändern, es geht alles wie fabrikmässig eingestellt.

3.7 Videos vom Controller

3.7.1 Videos von der LED-Version des Controllers

Die LED-Version startet mit dieser Animation:

Hier sind sowohl die sieben Einzel-LEDs als auch die Siebensegmentanzeige an den ATtiny24 angeschlossen. Weil PA7 offen ist, spielt er die Einzel-LED-Version ab.

Hier nun das Zählen bei der LED-Version. PB2 wird dabei sieben Mal auf Null gezogen:



Bei Nummer Fünf und Nummer Sechs gehen die beiden kleinen gelben LEDs an, stellvertretend für die beiden Relais.

3.7.2 Videos von der Siebensegment-Version des Controllers

Die Siebensegment-Version startet, wenn die Betriebsspannung eingeschaltet wird, ebenfalls mit einer Animation:



Die Parallelschaltung von Siebensegment und Einzel-LEDs verursacht nun, dass mehrere Einzel-LEDs angehen (soviele wie Segmente beleuchtet sind).

Das Zählen sieht dann so aus:


4 Vergleich und Fazit

Dieses Beispiel macht folgendes klar:
  1. Mit CMOS braucht die Lösung viel mehr ICs und Verdrahtung als mit einem Controller. Der hat alles was man braucht (Pull-Up-Widerstände, als Ein- oder Ausgang einstellbare Port-Pins, Timer, u.v.a.m) selbst mit an Bord, und man ist mit einem einzigen 6-, 8-, 14- oder 20-poligen IC in der Lage, das gesamte Problem in einem einzigen Rutsch zu lösen.
  2. Die Lösung mit einem Controller bietet jede Menge Varianten zu geringem Zusatzaufwand. Zusätzlich ist hier beim Start auch noch ein schneller Lampentest dazugebaut, für den ich ganze 12 Zusatz-Instruktionen benötigt habe. Auch der Umbau der Software auf weniger Impulse ist kinderleicht und schnell realisiert: nur ein paar wenige Codezeilen geändert und schon funktioniert es auch mit Drei-Vier oder Vier-Fünf.
  3. Preislich kaum ein Unterschied, aber verdrahtungsmäße Welten liegen dazwischen. Da bei der Controller-Variante nur wirklich nötige Verbindungen zu verknüpfen sind, hat die CMOS-Version zusätzlich noch jede Menge Unsinniges zu verbinden. Nehmen wir nur das Beispiel der zwei Relais-Monoflops: jeweils ein R und ein C sind zu verbinden, das hat er im Controller mit seinen beiden Timern und ein paar Programmzeilen alles gar nicht nötig.
  4. So ein Controllerchen kann aber noch viel mehr als wir hier verwendet haben: es hat noch jede Menge Register, statisches SRAM und dauerhaftes EEPROM zur Verfügung, ganz zu schweigen von den acht AD-Wandlern. Wer mehr als zwanzig Portpins braucht, nimmt einfach einen ATmega8, 16 oder 324. Die sprechen die gleiche AVR-Assembler-Sprache und haben nur mehr Pins. AVRs eignen sich auch für noch ganz andere Aufgaben, für die man mit CMOS ganze Euro-Platinen vollpflastern müsste.
  5. Einziger Nachteil der Controller-Lösung: man muss das Programm dafür selbst stricken, am Besten in Assembler natürlich. Und man braucht eine Programmier-Mimik, um die Hexadezimal-codierten Instruktionen einmal in das Flash-Gedächtnis des Controllers zu schieben. Die Anschaffung des Programmiergeräts dafür lohnt sich schon ab der zweiten solchen Anwendung.
©2022 by Gerhard Schmidt