Noch'n Gedicht (Heinz Erhardt)
Anfang November 2014 traf ich auf einer Modellbahnausstellung einen netten älteren Herrn, der eine Hausbeleuchtung mit ATtiny 45 zeigte. Als ich dann ein paar Wochen später eine solche selbst zustande gebracht hatte, freute ich mich ungemein! Das Programm (Sketch) sah ungefähr so aus wie in Post #0. Ich finde, jeder Anfänger darf stolz darauf sein, auch wenn die Experten lächeln!
Darum erlaube ich mir, Uwe (uwefed) vorsichtig zu widersprechen, wenn er in #1 „Du darfst kein delay() verwenden ...“ schreibt. Mein Lernweg führte zunächst zu einer Lösung, bei der ich delay(1) in loop verwendete, und zwei Schleifenzähler, einen für die Hausbeleuchtung, einen für das Blinken, erhöhte. Bei wirklich zeitkritischen Anwendungen (ich lasse gerade zwei ATtinys mittels I2C miteinander reden) funktioniert delay() dann wirklich nicht mehr. Hätte Uwe formuliert, was er mutmaßlich meint, die Lösung mit millis() sei eleganter und zukunftssicherer, so bekäme er meine volle Unterstützung. Die Erklärungen später (#11 und #12) sind dann ja auch prima.
Zur von BR130 in #26 aufgeworfenen Frage der mehrbeinigen ATtinys möchte ich hier meinen derzeitigen Liebling '4313 mit 17 nutzbaren Ein-/Ausgängen erwähnen. Mit der IDE Version 1.5.8 lässt er sich prima programmieren. Ich habe eine Ampelschaltung mit Baustellenblitzern und einen Würfel damit realisiert und verschenkt. Zu beachten ist die Gesamtleistung des IC.
Um einem möglichen Missverständnis vorzubeugen, welches beim Lesen von #32 und #37 entstehen könnte: Sowohl die megas als auch die tinys lassen sich, wenn ich das Datenblatt richtig verstehe, ca. 10000 Mal „umprogrammieren“.
Eine „spannende“ Frage wird in #33 nach der Stromversorgung gestellt. Grundsätzlich wollen die Mikrocontroller 5V. Der schon erwähnte '4313 (1 MHz) tut es aber auch noch bei 3V, weshalb der ebenfalls bereits erwähnte Würfel mit 3 x 1,5V versorgt wird. Um die höheren Spannungen der Modellbahn zu schalten, habe ich auch schon einen Optokoppler verwendet, wobei der 6N139 eine LED mit wenig Strombedarf am Eingang hat.
Wie schön zu lesen, dass es auch andere Menschen mit Träumen gibt. Eigentlich fängt es im Modellbau doch immer damit an. Träumen – Planen – Realisieren.
In #38 erwähnt Serenifly, wie auch schon an anderer Stelle geschehen, die Lösung mittels Schieberegister. Das habe ich mit ATtiny 45 und zwei 74HC595 ausprobiert, funktioniert für eine Hausbeleuchtung (Rathaus Leer) auch prima. Allerdings lasse ich eine LED als Neonröhre beim Einschalten flackern. Da müssen dann wegen der einen LED immer alle 16 Bit übertragen werden, was man beim Planen berücksichtigen sollte. Die notwendige boolsche Algebra zum Setzen einzelner Bits habe ich zwar in der Schule gehabt, war aber doch etwas schwierig. Derzeit würde ich wohl einen '4313 mit zwei PCF8574 Portexpandern über I2C und der flackernden LED direkt am '4313 Ausgang bevorzugen.
Jörg schlägt sich in #60 mit langen Variablen herum. Aus den Antworten habe ich was gelernt, möchte aber für die Hausbeleuchtung mit langen Schaltzeiten noch den Vorschlag ergänzen, die Millisekunden zu teilen. Mittels „millis() >> 10“ teilt man durch 1024, so dass dann möglicherweise wieder unsigned integer reicht.
Stefan wirft in #6 die berechtigte Frage auf, ob jemand lernen will. Ich bitte diesen Eintrag als DANKE an alle netten Menschen zu verstehen, die mir ihr Wissen zur Verfügung gestellt haben. Besonders lerne ich durch die schönen Programmbeispiele von jurs, weshalb ich an dieser Stelle ein allerdings unfertiges Programm extra für ihn veröffentliche. Es handelt sich um eine Abwandlung vom Leuchtturm-Beispiel.
//**************************************************************
// Name : Test Hausbeleuchtung fuer ATtiny 45
// Zweck : Hausbeleuchtung mit der Funktion millis()
//****************************************************************
// ATMEL ATTINY45
//
// +-\/-+
// Ain0 (D 5) PB5 1| |8 Vcc
// Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1
// Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1
// GND 4| |5 PB0 (D 0) pwm0
// +----+
// Anregung durch "Leuchtturm LEDs schalten by Jurs" im Arduino-Forum Deutsch
//
#define B 1 //Bad
#define W 2 //Wohnzimmer
#define K 3 //Küche
#define L 4 //Laden
byte Zimmer[] = {L, K, W, K, K, B, K, B, B, W, B, K, K, B, K, W, B, W, K, L, B}; // Pin-Nummer der zu schaltenden LED
unsigned int HausZeit[] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1}; // Sekunden Wartezeit (genauer Millisekunden/1024)
#define HausZeigerMax (sizeof(Zimmer)/sizeof(int *)) // Feldgroesse
unsigned int HausZeigerakt = 0; // Zeiger auf Feldelement
unsigned int HausZeitalt = 0; // Sekundenzaehler bei letzter Aktion
// a e a e a e a e a e a
unsigned int BlinkZeit[] = {300, 100, 300, 300, 111, 300, 3333, 100, 300, 300, 20000}; // Millisekunden Wartezeit
#define BlinkZeigerMax (sizeof(Zimmer)/sizeof(int *)) // Feldgroesse
unsigned int BlinkZeigerakt = 0; // Zeiger auf Feldelement
unsigned long BlinkZeitalt = 0; // Millisekundenzaehler bei letzter Aktion
boolean ein = LOW; // Wenn LEDs gegen +5V geschaltet sind, negiert sich die Logik
boolean aus = HIGH;
void setup() {
// Definiert die Ausgabepins
pinMode(0, OUTPUT); //Blink
pinMode(B, OUTPUT); //Bad
pinMode(W, OUTPUT); //Wohnzimmer
pinMode(K, OUTPUT); //Küche
pinMode(L, OUTPUT); //Laden
digitalWrite(0, ein);
digitalWrite(B, aus);
digitalWrite(W, aus);
digitalWrite(K, aus);
digitalWrite(L, aus);
}
void Haus()
{
if ((millis() >> 10) > (HausZeitalt + HausZeit[HausZeigerakt])) {
if (HausZeigerakt < HausZeigerMax - 1) { // Der Feldzeiger muss innerhalb des Feldes bleiben
digitalWrite(Zimmer[HausZeigerakt], !digitalRead(Zimmer[HausZeigerakt])); // Beleuchtung umschalten
HausZeitalt = millis() >> 10; // Sekunden merken
HausZeigerakt++; // auf das naechste Feldelement zeigen
}
}
}
void Blink()
{
if (millis() > (BlinkZeitalt + BlinkZeit[BlinkZeigerakt])) { // Zeit abwarten
if (BlinkZeigerakt < BlinkZeigerMax - 1) {
BlinkZeigerakt++;
} else {
BlinkZeigerakt = 0;
}
digitalWrite(0, !digitalRead(0)); // Blink-LED umschalten
BlinkZeitalt = millis(); // Milisekunden merken
}
}
void loop() {
Haus();
Blink();
}