Elektronik_Header_3LŘftersteuerung mit ESP-01

 

AtTiny-W├╝rfel reloaded

Basierend auf dem W├╝rfel-Design von 2009 und Sammlung von Erfahrung im Umgang mit AtTinys und deren Stromsparmodi habe ich jetzt ein Programm f├╝r meinen W├╝rfel erstellt, das den Betrieb mit einer Knopfzelle erlaubt.

Da der Code diesmal im Arduino-Umfeld entstehen soll, wird ein anderer Programmierer zum Einsatz kommen, der Programmieranschluss muss also ├╝berarbeitet werden. Ich habe deshalb zuerst die uns├Ąglichen Programmier-Strippen entfernt - der Link zeigt den PIC-W├╝rfel - der AtTiny-W├╝rfel hatte noch eine Strippe mehr:

AtTiny-W├╝rfel mit Programmier-Strippen

Daf├╝r wurde ein Stecker im 1 mm Raster eingebaut, wie das schon beim FS20 S3 Erfolg zeitigte.

Programmieranschluss - 1 mm Raster Stecker

Der Batteriehalter nimmt eine 3 V Lithium Mangan Knopfzelle der Gr├Â├če CR16xx auf. Der von mir eingesetzte Keystone 502 Knopfzellenhalter passt gut f├╝r eine CR1616, soll aber auch dickere Zellen (CR1620, CR1625, CR1632) aufnehmen. Eine CR1632 kontaktiert zwar gut, “passt” allerdings meiner Meinung nach nicht, die Zelle sitzt schr├Ąg in der Halterung. Andere Knopfzellengr├Â├čen habe ich nicht getestet.

Der Halter hat einen Abstand von der Platinenunterseite da ich die F├╝hrungsstifte nicht in L├Âchern versenkt habe. Durch diesen Abstand kann der Stecker teilweise unterhalb des Batteriehalters angeordnet werden und ist von oben unsichtbar.

Batteriehalter und Programmieranschluss

Der linke Pin, Pin 6 des Steckers, f├╝hrt GND. Diesen Pin habe ich vorsichtig direkt hinter dem Plastikk├Ârper nach unten abgeknickt und durch ein Loch in die Massefl├Ąche am Taster gef├╝hrt und dort festgel├Âtet. Anschlie├čend wurde der Stecker mit Sekundenkleber an der Platine befestigt. Die restlichen Signale sind mit Kupferlackdr├Ąhten “unsichtbar” unterhalb des Batteriehalters an den Stecker gef├╝hrt.

Die f├╝r die Verbindung des Steckers zur Schaltung notwendigen L├Âcher in der Platine sind im Layout nicht vorgesehen und wurden nachtr├Ąglich mit einem 0,8 mm Bohrer in oder neben die vorhandenen Pads f├╝r den Programmer-Anschluss gebohrt.

Die Draufsicht zeigt, die Anschl├╝sse sind nur durchgesteckt und von oben kaum sichtbar:

AtTiny13 W├╝rfel mit Programmieranschluss (unsichtbar)

Gegen├╝ber der ersten Abbildung des AtTiny-W├╝rfels sind die SMD-Vorwiderst├Ąnde der LEDs hier durch bedrahtete Typen ersetzt. Den gew├╝nschten Wert von jetzt 1,3 kÔäŽ gegen├╝ber dem vorgesehenen Wert von 1 kÔäŽ und dem damals verbauten Wert von 680 ÔäŽ hatte ich nicht in SMD vorr├Ątig.

Auch hier passt der f├╝r den FS20 S3 erstellte Programmieradapter:

Programmieradapter

Die Anschlussbelegung wurde sinnigerweise identisch wie beim FS20 S3 gew├Ąhlt :-)


Wie die Arduino-IDE vorbereitet werden muss, um einen AtTiny13 programmieren zu k├Ânnen, ist im Netz beschrieben, darauf m├Âchte ich hier nicht n├Ąher eingehen.
Nur soviel: In der Arduino IDE muss unter Voreinstellungen der Download-Link auf einen passenden Tiny-Core gesetzte werden.

Ich habe ”Optiboot” von James Sleeman verwendet. Der Eintrag unter “Zus├Ątzliche Boardverwalter-URLs” in den Voreinstellungen muss dann

https://raw.githubusercontent.com/sleemanj/optiboot/master/dists/package_gogo_diy_attiny_index.json

lauten. Danach kann im Boardverwalter AtTiny13 gesucht und dessen Unterst├╝tzung installiert werden.

Hinweis
Im Zuge der Implementierung des Programms bin ich darauf gesto├čen, dass das Einschalten des internen PullUp an Pin5 (PB0) nicht ausreicht, es muss ein externer PullUp eingel├Âtet werden. Ich habe hierf├╝r einen 30 kÔäŽ Widerstand verwendet.

    Aktualisierung
    Der Grund f├╝r das fehlerhafte Verhalten des internen PullUp war meine Sparfuchs -L├Âsung zum Abschalten aller LEDs auf einen Schlag. Ich habe daf├╝r “PORTB = 0” verwendet. Die LEDs wurden auch abgeschaltet, allerdings wurde durch diese Bedienung auch der Eingang mit PullUp f├╝r den Taster auf 0 gesetzt.

    Laut Datenblatt kann auf einem als Eingang geschalteten Pin durch Ausgabe des entsprechenden Wertes ein Software-Interrupt ausgel├Âst werden. Das habe ich durch Schreiben einer “0” (Null) auf dem gesamten Port B getan.
    In Folge wurden im Programmlauf etliche IRQs mehr ausgel├Âst, als mein Programm erwartet hat, daher die Fehlfunktion.
    Das ist jetzt ge├Ąndert, der externe PullUp kann entfallen.

Der im AtTiny13 vorhandene Speicher f├╝r das Programm ist mit 1 kByte nicht ├╝ppig bemessen, so dass ich im ersten Ansatz wirklich nur einen einfachen Zufallszahlengenerator mit entsprechenden Anzeigeroutinen und den Deep Sleep Mode implementiert habe. F├╝r mehr war kein Platz, da muss ich noch ein bisschen optimieren, denke ich.

Aber immerhin kann mit diesem Programm der AtTiny-W├╝rfel jetzt endlich auch mit Batteriebetrieb eingesetzt werden, denn ohne Anzeige der Augenzahl, also im Sleep Mode, verbraucht der Microcontroller maximal 0,1 ┬ÁA oder 100 nA.

Bei 55 mAh Kapazit├Ąt einer CR 1616 Knopfzelle (beispielhaft von VARTA) sollte der W├╝rfel also viele Jahre (berechnet ca. 50-60 Jahre) im Sleepmode durchhalten. Genaugenommen liegt dieser gemessene “Verbrauch” noch unterhalb der Selbstentladung solcher Zellen.

Im Betrieb, also in den kurzen Zeiten wenn das Programm die Augenzahl errechnet und anzeigt, liegt der Strom bei 4..15 mA.


Der in der Arduino-Umgebung eingesetzte Zufallszahlengenerator erzeugt prinzipiell  keine echten Zufallszahlen, sondern nur eine pseudozuf├Ąllige Aneinanderreihung von Zahlen. Bei jedem Einschalten des W├╝rfels, also dem Einsetzen einer neuen Batterie, werden immer Zahlen in der gleichen Reihenfolge ausgegeben werden. Das w├Ąre eigentlich kein Grund zum Jammern, die Batterie muss ja nur selten getauscht werden, aber es gibt Abhilfe, also wird sie implementiert.

Um den Zufallszahlengenerator zuf├Ąlliger zu machen, muss er ├╝ber einen Startwert randomisiert werden. Dieser Startwert bestimmt den Einstiegspunkt in die pseudozuf├Ąllige, immer gleiche Zahlenfolge, wodurch die erzeugten Zahlenwerte dann tats├Ąchlich zuf├Ąllig erscheinen.

In einem Microcontroller sind allerdings die M├Âglichkeiten zur Erzeugung eines zuf├Ąlligen Startwertes naturgem├Ą├č eher eingeschr├Ąnkt. Die Literatur schl├Ągt vor, einen unbeschalteten Analogeingang einzulesen. Durch elektromagnetische Einstrahlung k├Ânnte eine zuf├Ąllige Zahl zwischen 0 und 1023 erzeugt werden. Untersuchungen haben aber ergeben, dass diese Methode bei weitem nicht so zuf├Ąllige Werte ergibt wie man erwarten k├Ânnte. Zudem w├╝rde die Aktivierung der Analog-Funktionalit├Ąt den Stromverbrauch erh├Âhen und vor allem die Programmgr├Â├če negativ beeinflussen (der AtTiny13 hat nur 1024 Byte Programmspeicher, der bereits von Anzeigefunktionen und Tastenabfrage zu 90% gef├╝llt ist).

Selbst der Versuch, ├╝ber die Tastendruckdauer eine Variabilit├Ąt einzubringen ist an den engen Speichergrenzen gescheitert.

Letztlich kam ich nur voran, indem ich Standardfunktionen der Arduino Umgebung durch  direkte Portmanipulationen ersetzt habe. Durch folgendes Konstrukt habe ich ausreichend Platz gewonnen, um einen Z├Ąhler zu implementieren, der einmalig nach Einsetzen der Batterie eine Zahl aus der Dauer des Tastendrucks ableitet, die zur Randomisierung des Zufallszahlengenerators herangezogen wird:

// Optimierungen
#undef digitalRead()
#define
digitalRead(pinnummer) ((PINB) & (1 << (pinnummer)))

Der Trick kann funktionieren, da die Macher von Arduino in ihren Libs immer versuchen, alle Eventualit├Ąten zu ber├╝cksichtigen. So ist z.B. beim Einlesen eines digitalen Eingangs ber├╝cksichtigt, dass dieser Eingang mit einem der Timer verkn├╝pft sein k├Ânnte. Um diese M├Âglichkeit korrekt abzuhandeln, ist Einiges an Code in der Library vorgesehen, das bei jedem Aufruf von digitalRead() mit in das resultierende Programm eingebaut wird.

Da ich wei├č, dass mein Eingang ausschlie├člich zum Einlesen des Status des Tasters verwendet wird, muss ich solche Eventualit├Ąten nicht ber├╝cksichtigen, kann also den Pin direkt abfragen und somit wertvollen Programmspeicher einsparen.

Einen ├Ąhnlichen Trick habe ich beim Setzen der Ausgangs-Bits der LEDs verwendet, musste aber feststellen, dass die Implementierung von bitSet() bereits optimal umgesetzt ist. Hierdurch konnte keine Einsparung am resultierenden Code erreicht werden - im Gegenteil, die im Code noch als Kommentar vorhandenen Befehle
bitSet(PORTB, LEDXuY) w├╝rden das Programm in der Tat um 4 Byte kleiner machen.
Nur die auskommentierte Zeile mit PORTB = 0 darf auf keinen Fall aktiviert werden!

Das ge├Ąnderte Programm stelle ich als C-Sourcen in Arduino Syntax zur Verf├╝gung.


├ťbrigens: Der interne PullUp ist nat├╝rlich doch in der Lage, den Eingangspin des Tasters sauber auf High zu ziehen, der Grund f├╝r das Versagen dieses Ansatzes ist ein Anderer.

Der oben bereits verlinkte Code enth├Ąlt das erneut ge├Ąnderte Programm mit eingeschaltetem internem PullUp am Taster. Der externe Widerstand muss nicht eingebaut werden.

Viel Spa├č!


Besucherzaehler

Besucher seit
25.11.2000

>