/* * Sketchname: sr595_lauflicht.ino * Name: [Ihr Name] * Schulklasse: [Ihre Schulklassenbezeichnung] * Ausbildungsberuf: [Ihr Ausbildungsberuf] * Schularbeit: Lauflichtprojekt 1b * Framework: Arduino * * Beschreibung: * Lauflicht mit 8 LEDs, angesteuert über ein Schieberegister SN74HC595. * Die Ablaufgeschwindigkeit ist über ein 10-kOhm-Potenziometer einstellbar. * Über einen zweipoligen Mini-Dipschalter (2 Bit = 4 Kombinationen) sind * 4 verschiedene Leuchtmuster wählbar. * Es werden KEINE Interrupts verwendet. * * Hardware: * - Arduino mit ATmega328p * - Schieberegistermodul SN74HC595 mit 8 LEDs * - 10 kOhm Potenziometer an A0 * - 2-poliger Mini-Dipschalter an Pins 4 und 5 * * Pinbelegung SN74HC595: * DATA -> Pin 11 (Arduino) * LATCH -> Pin 12 (Arduino) * CLOCK -> Pin 13 (Arduino) */ #include // ── Pin-Definitionen ────────────────────────────────────────────────────────── const int PIN_DATA = 11; // Serieller Dateneingang (DS) des SN74HC595 const int PIN_LATCH = 12; // Latch-Clock (ST_CP) des SN74HC595 const int PIN_CLOCK = 13; // Schiebe-Clock (SH_CP) des SN74HC595 const int PIN_POTI = A0; // Potenziometer für Geschwindigkeitseinstellung const int PIN_DIP1 = 4; // Dipschalter Bit 0 (LSB) const int PIN_DIP2 = 5; // Dipschalter Bit 1 (MSB) // ── Konstanten ──────────────────────────────────────────────────────────────── const int DELAY_MIN = 50; // Minimale Verzögerung in ms (schnellste Geschwindigkeit) const int DELAY_MAX = 500; // Maximale Verzögerung in ms (langsamste Geschwindigkeit) // Anzahl der Leuchtmuster-Schritte je Muster const int PATTERN_LEN = 8; // ── Schieberegister-Objekt ──────────────────────────────────────────────────── // Konstruktor: shiftreg595(dataPin, latchPin, clockPin) shiftreg595 sr(PIN_DATA, PIN_LATCH, PIN_CLOCK); // ── Leuchtmuster ────────────────────────────────────────────────────────────── /* * Jeder Eintrag ist ein Byte, das den Zustand der 8 LEDs beschreibt. * Bit 0 = LED 1, Bit 7 = LED 8. * * Muster 0 (Dipschalter 00): Einzelne LED wandert von links nach rechts * Muster 1 (Dipschalter 01): Einzelne LED wandert von rechts nach links * Muster 2 (Dipschalter 10): LEDs füllen von links auf, dann löschen von links * Muster 3 (Dipschalter 11): Wechselblinken gerade/ungerade LEDs (Lauflicht) */ // Muster 0 – Lauflicht vorwärts (eine LED wandert links → rechts) const byte pattern0[PATTERN_LEN] = { 0b00000001, // LED 1 0b00000010, // LED 2 0b00000100, // LED 3 0b00001000, // LED 4 0b00010000, // LED 5 0b00100000, // LED 6 0b01000000, // LED 7 0b10000000 // LED 8 }; // Muster 1 – Lauflicht rückwärts (eine LED wandert rechts → links) const byte pattern1[PATTERN_LEN] = { 0b10000000, // LED 8 0b01000000, // LED 7 0b00100000, // LED 6 0b00010000, // LED 5 0b00001000, // LED 4 0b00000100, // LED 3 0b00000010, // LED 2 0b00000001 // LED 1 }; // Muster 2 – Auffüllen von links, dann Leeren von links const byte pattern2[PATTERN_LEN] = { 0b00000001, // 1 LED ein 0b00000011, // 2 LEDs ein 0b00000111, // 3 LEDs ein 0b00001111, // 4 LEDs ein 0b00011111, // 5 LEDs ein 0b00111111, // 6 LEDs ein 0b01111111, // 7 LEDs ein 0b11111111 // alle 8 LEDs ein }; // Muster 3 – Wechselblinken: gerade und ungerade LEDs abwechselnd const byte pattern3[PATTERN_LEN] = { 0b01010101, // LEDs 1,3,5,7 0b10101010, // LEDs 2,4,6,8 0b01010101, 0b10101010, 0b01010101, 0b10101010, 0b01010101, 0b10101010 }; // ── Hilfsvariablen ──────────────────────────────────────────────────────────── int currentStep = 0; // Aktueller Schritt innerhalb des Musters int dipMode = 0; // Gewähltes Muster (0–3) unsigned long lastTime = 0; // Zeitstempel des letzten Schritts (für delay-freies Timing) // ── setup() ────────────────────────────────────────────────────────────────── void setup() { // Dipschalter-Pins als Eingang mit internem Pull-up-Widerstand konfigurieren // → Schalter offen = HIGH (logisch 1), Schalter geschlossen = LOW (logisch 0) pinMode(PIN_DIP1, INPUT_PULLUP); pinMode(PIN_DIP2, INPUT_PULLUP); // Alle LEDs beim Start ausschalten sr.setvalue(0x00); } // ── loop() ─────────────────────────────────────────────────────────────────── void loop() { // 1) Dipschalter einlesen und Muster bestimmen // Da Pull-ups aktiv sind, ist "geschlossen" = LOW = 0, "offen" = HIGH = 1. // Invertierung: gedrückt (LOW) → logisch 1 für die Muster-Auswahl. int bit0 = !digitalRead(PIN_DIP1); // Bit 0 des Musters int bit1 = !digitalRead(PIN_DIP2); // Bit 1 des Musters int newMode = (bit1 << 1) | bit0; // Ergibt 0, 1, 2 oder 3 // Muster gewechselt? → Schritt zurücksetzen, damit kein Sprung entsteht if (newMode != dipMode) { dipMode = newMode; currentStep = 0; } // 2) Geschwindigkeit über Potenziometer einlesen // analogRead liefert 0–1023; map() skaliert auf DELAY_MIN–DELAY_MAX. int potiValue = analogRead(PIN_POTI); int stepDelay = map(potiValue, 0, 1023, DELAY_MIN, DELAY_MAX); // 3) Nicht-blockierendes Timing (kein delay(), damit Dipschalter sofort reagiert) unsigned long now = millis(); if ((now - lastTime) >= (unsigned long)stepDelay) { lastTime = now; // 4) Aktuellen Musterschritt ausgeben byte ledValue = 0x00; switch (dipMode) { case 0: ledValue = pattern0[currentStep]; break; case 1: ledValue = pattern1[currentStep]; break; case 2: ledValue = pattern2[currentStep]; break; case 3: ledValue = pattern3[currentStep]; break; default: ledValue = 0x00; break; } // Wert über das Schieberegister-Objekt an die LEDs senden sr.setvalue(ledValue); // 5) Schrittindex weiterzählen und bei Ende des Musters zurücksetzen currentStep = (currentStep + 1) % PATTERN_LEN; } }