/* -------------------------------------------------------- sr_ledlauflicht.ino Kommentare aus datenschutzrechtlichen Gruenden hier entfernt -------------------------------------------------------- */ #include "sn74hc595.h" // ---------------------------------------------------------------------- // Objektinstanz von shiftreg595 erstellen // Usage: // shiftreg595::shiftreg595(uint8_t clk, uint8_t dat, uint8_t stb) // ---------------------------------------------------------------------- shiftreg595 sr(7, 5, 6); /* ---------------------------------------------------------------------- Lauflichtmuster / -programme. 0. Element ist Laengenbyte und beinhaltet die Anzahl der abzuspielenden Leuchtmuster ---------------------------------------------------------------------- */ uint8_t lauf_bmp0[] = {14, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, // 0x40, 0x20, 0x10, 0x08, 0x04, 0x02 }; uint8_t lauf_bmp1[] = {16, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, // 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 }; uint8_t lauf_bmp2[] = { 4, 0x33, 0x66, 0xcc, 0x99 }; // Schrittmotormuster uint8_t lauf_bmp3[] = { 8, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x81 }; /* ---------------------------------------------------------------------- Dip-Schalter an Pin 4 und Pin 3 angeschlossen ---------------------------------------------------------------------- */ const int dipkey_0= 4; const int dipkey_1= 3; /* ---------------------------------------------------------------------- Trimmer an A0 angeschlossen ---------------------------------------------------------------------- */ const int speedctrl= A0; /* ---------------------------------------------------------------------- schnellste Grundgeschwindigkeit, kleinerer Wert== schneller ---------------------------------------------------------------------- */ #define maxspeed 40 /* ---------------------------------------------------------------------- io_init initialisiert die Anschluesse des DIP-Schalters sowie den Analogeingang an dem der Potenziometer angeschlossen ist ---------------------------------------------------------------------- */ uint8_t io_init(void) { pinMode(dipkey_0, INPUT_PULLUP); pinMode(dipkey_1, INPUT_PULLUP); pinMode(speedctrl, INPUT); } /* ---------------------------------------------------------------------- dipkey_get liest die DIP-Schalter ein und gibt je nach Schalterstellung Werte von 0x00 bis 0x03 zurueck ---------------------------------------------------------------------- */ uint8_t dipkey_get(void) { uint8_t keyval; keyval= 0x00; if (digitalRead(dipkey_0)) keyval = 0x01; if (digitalRead(dipkey_1)) keyval |= 0x02; return keyval; } /* ---------------------------------------------------------------------- runspeed_get liest den ADC, an dem der Potenziometer angeschlossen ist aus und berechnet daraus einen Verzoegerungswert fuer die einzelnen Schritte eines Lauflichtmusters. 10-Bit ADC entspricht 0..1023 ADC / 3 = 341; 341 + maxspeed (40) = 381 Rueckgabewerte je nach Potenziometereinstellung 0..381 ---------------------------------------------------------------------- */ int runspeed_get(void) { return ((analogRead(speedctrl) / 3) + maxspeed); } /* ---------------------------------------------------------------------- polled_delay Verzoegerungsschleife innerhalb dieser Schleife wird der Potenziometer ausgelesen und das Ende der Verzoegerung unmittelbar angepasst, so dass eine Geschwindigkeitsaenderung nicht erst mit Ablauf eines Leuchtmuster- schritts erfolgt. Die Schleife wird unterbrochen, wenn Aenderungen an der Einstellung der Dipschalter erfolgt sind. Uebergabeargument: dipkey_status = aktuelle Stellung des Dipschalters Rueckgabe: 0x80 : Marker dass die Verzoegerungsschleife ohne Aenderung der Dipschalter durchgelaufen ist 0x00..0x03: geaenderte Dipschaltereinstellung ---------------------------------------------------------------------- */ uint8_t polled_delay(uint8_t dipkey_status) { uint32_t start = millis(); uint32_t runtime; uint8_t dipkeys; while (1) { dipkeys = dipkey_get(); // DIP-Schalter pruefen, bei Aenderung Abbruch if (dipkeys != dipkey_status) { return dipkeys; } runtime = millis() - start; // dynamische Laufzeit, Aenderungen am Potenziometer // haben auch waehrend der Delay Auswirkungen auf die // Verzoegerungszeit if (runtime >= runspeed_get()) { return 0x80; // 0x80 == Marker fuer normales Ende ohne DIP-Schalteraenderung } } } /* ---------------------------------------------------------------------- progpointer_get liefert einen Zeiger auf das entsprechende Lauflichtmuster ---------------------------------------------------------------------- */ uint8_t *progpointer_get(uint8_t mode) { switch (mode) { case 0: return lauf_bmp0; case 1: return lauf_bmp1; case 2: return lauf_bmp2; case 3: return lauf_bmp3; default: return lauf_bmp0; } } /* ---------------------------------------------------------------------- setup ---------------------------------------------------------------------- */ void setup() { sr.begin(); io_init(); sr.setvalue(0x00, 1); } /* ---------------------------------------------------------------------- loop ---------------------------------------------------------------------- */ void loop() { static uint8_t mode, event, len; static uint8_t i= 0; static uint8_t last_mode = 0xff; // einen Mode setzen, den es nicht gibt und damit bei Eintritt // in die While-Schleife das Auslesen der Dip-Schalter und setzen // eines Lauflichtprogramms erzwingen => 0xff Marke fuer neusetzen static uint8_t *laufl_prog; mode = dipkey_get(); // DIP-Schalter wurden geaendert => Lauflichtprogramm entspr. der Schalter setzen if (mode != last_mode) { laufl_prog = progpointer_get(mode); len = laufl_prog[0]; i = 0; last_mode = mode; } sr.setvalue(laufl_prog[i + 1], 1); // Ausgabe eines Leuchtmusters event = polled_delay(mode); // potenziometerabhängige Zeitverzoegerung if (event == 0x80) { i++; if (i >= len) i = 0; } else { last_mode = 0xff; // neusetzen des Lauflichtprogramms erzwingen } }