Hallo Zusammen,
Ich habe gerade ein kleines Projekt am laufen wobei ich mit Hilfe von Programmierbaren LED Strips einen Countdown anzeigen lassen möchte.
Hier ein paar Einblicke:
Der Titel verrät bereits dass ich Schwierigkeiten habe. Genauer gesagt bringe ich den code nicht zum laufen.
Ich versuche mal zu erläutern wo meine Probleme liegen.
Ich habe mal einen anfänglichen Code auf die Beine gestellt welcher nur einen Countdown eines definierten wertes herunterzählen soll. Dieser funktioniert auch nicht schlecht, wobei es Probleme mit der Hundertstelle der Tage gibt. Das Format welches angezeigt werden soll ist folgendermassen: DDD:HH:MM:SS. Meiner Logik nach müsste ich jetzt einen maximalen Wert darstellen können von 999:23:59:59, dies ist aber nicht möglich. Wenn ich aber einen wert von 005:23:59:59 eingebe, funktioniert es.
Folgender Code habe dafür erstellt:
#include <Adafruit_NeoPixel.h>
//Definiere Countdown Zeit:
#define Tage 5 // Anzahl Tage in TTT
#define Stunden 20 // Anzahl Stunden in HH
#define Minuten 15 // Anzahl Minuten in MM
#define Sekunden 15 // Anzahl Sekunden in SS
// Pin-Definitionen für die NeoPixel-Streifen
#define PIN_LED_STRIP_1 2 // Pin für Hundertstelle Tage
#define PIN_LED_STRIP_2 3 // Pin für Zehnerstelle Tage
#define PIN_LED_STRIP_3 4 // Pin für Einerstelle Tage
#define PIN_LED_STRIP_4 5 // Pin für Zehnerstelle Stunden
#define PIN_LED_STRIP_5 6 // Pin für Einerstelle Stunden
#define PIN_LED_STRIP_6 7 // Pin für Zehnerstelle Minuten
#define PIN_LED_STRIP_7 8 // Pin für Einerstelle Minuten
#define PIN_LED_STRIP_8 9 // Pin für Zehner stelle Sekunden
#define PIN_LED_STRIP_9 10 // Pin für Einerstelle Sekunden
#define PIN_LED_STRIP_10 12 // Pin für Buchstabenbeleuchtung
#define NUM_LEDS 7 // Anzahl der LEDs Strip 1-9
#define NUM_LEDS_STRIP_10 12 // Anzahl der LEDs in Strip 10
#define NUM_STRIPS 10
// Array für die NeoPixel-Streifen
Adafruit_NeoPixel strips[NUM_STRIPS] = {
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_1, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_2, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_3, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_4, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_5, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_6, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_7, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_8, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_9, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS_STRIP_10, PIN_LED_STRIP_10, NEO_GRB + NEO_KHZ800)// Anpassung für 12 LEDs
};
unsigned long startTime;
unsigned long countdownDuration;
// Definition der 7-Segment Zahlen
// -->
// ¦ ¦
// ------>
// ¦ ¦
// <--
int segments[10][7] = {
{0, 1, 1, 1, 1, 1, 1}, // 0
{0, 1, 0, 0, 0, 0, 1}, // 1
{1, 0, 1, 1, 0, 1, 1}, // 2
{1, 1, 1, 0, 0, 1, 1}, // 3
{1, 1, 0, 0, 1, 0, 1}, // 4
{1, 1, 1, 0, 1, 1, 0}, // 5
{1, 1, 1, 1, 1, 1, 0}, // 6
{0, 1, 0, 0, 0, 1, 1}, // 7
{1, 1, 1, 1, 1, 1, 1}, // 8
{1, 1, 1, 0, 1, 1, 1} // 9
};
// Definition der Zuordnung von Ziffern zu den LED-Strips
int digitStrips[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
void setup() {
Serial.begin(9600);
startTime = millis(); // Initialisiere startTime
// Initialisiere die Anfangszustände der Strips 1-9
for (int i = 0; i < NUM_STRIPS; i++) {
strips[i].begin();
strips[i].show(); // Zeige die Anfangszustand der Strips
}
// Initialisiere den Anfangszustand von Strip 10
for (int i = 0; i < NUM_STRIPS; i++)
strips[NUM_STRIPS-1].begin();
strips[NUM_STRIPS-1].show(); // Zeige den Anfangszustand von Strip 10
// Setze die Anfangszeit des Countdowns
unsigned long initialDays = Tage;
unsigned long initialHours = Stunden;
unsigned long initialMinutes = Minuten;
unsigned long initialSeconds = Sekunden;
countdownDuration = (initialDays * 24UL * 60UL * 60UL + initialHours * 60UL * 60UL + initialMinutes * 60UL + initialSeconds) * 1000UL;
Serial.print("Initial Countdown Time: ");
Serial.print(initialDays);
Serial.print(" days, ");
Serial.print(initialHours);
Serial.print(" hours, ");
Serial.print(initialMinutes);
Serial.print(" minutes, ");
Serial.print(initialSeconds);
Serial.println(" seconds");
}
void loop() {
displayCountdown();
}
void displayCountdown() {
unsigned long currentTime = millis();
unsigned long elapsedTime = currentTime - startTime;
unsigned long remainingTime = countdownDuration - elapsedTime;
if (remainingTime < 0) {
remainingTime = 0;
}
// Calculate remaining days, hours, minutes, and seconds
unsigned long remainingDays = remainingTime / (24UL * 60UL * 60UL * 1000UL);
remainingTime %= (24UL * 60UL * 60UL * 1000UL);
unsigned long remainingHours = remainingTime / (60UL * 60UL * 1000UL);
remainingTime %= (60UL * 60UL * 1000UL);
unsigned long remainingMinutes = remainingTime / (60UL * 1000UL);
remainingTime %= (60UL * 1000UL);
unsigned long remainingSeconds = remainingTime / 1000UL;
displayDigitsOnStrip(remainingDays / 100, 0); // Hundertstelle der Tage
displayDigitsOnStrip((remainingDays / 10) % 10, 1); // Zehnerstelle der Tage
displayDigitsOnStrip(remainingDays % 10, 2); // Einerstelle der Tage
displayDigitsOnStrip(remainingHours / 10, 3); // Zehnerstelle der Stunden
displayDigitsOnStrip(remainingHours % 10, 4); // Einerstelle der Stunden
displayDigitsOnStrip(remainingMinutes / 10, 5); // Zehnerstelle der Minuten
displayDigitsOnStrip(remainingMinutes % 10, 6); // Einerstelle der Minuten
displayDigitsOnStrip(remainingSeconds / 10, 7); // Zehnerstelle der Sekunden
displayDigitsOnStrip(remainingSeconds % 10, 8); // Einerstelle der Sekunden
// Funktion für LED Strip 10
displayColorOnStrip(strips[NUM_STRIPS - 1].Color(255, 0, 0)); // Rote LEDs für Strip 10
}
void displayDigitsOnStrip(int digit, int stripIndex) {
for (int j = 0; j < 7; j++) {
if (stripIndex >= 0 && stripIndex <= 2 && digit >= 100) {
// Zeige nur die Hundertstelle der Tage an
if (segments[digit / 100][j]) {
strips[digitStrips[stripIndex]].setPixelColor(j, strips[digitStrips[stripIndex]].Color(255, 0, 0));
} else {
strips[digitStrips[stripIndex]].setPixelColor(j, strips[digitStrips[stripIndex]].Color(0, 0, 0));
}
} else {
// Zeige die Ziffer normal an
if (segments[digit][j]) {
strips[digitStrips[stripIndex]].setPixelColor(j, strips[digitStrips[stripIndex]].Color(255, 0, 0));
} else {
strips[digitStrips[stripIndex]].setPixelColor(j, strips[digitStrips[stripIndex]].Color(0, 0, 0));
}
}
}
strips[digitStrips[stripIndex]].show();
}
// Funktion für LED Strip 10
void displayColorOnStrip(uint32_t color) {
for (int j = 0; j < strips[NUM_STRIPS - 1].numPixels(); j++) {
strips[NUM_STRIPS - 1].setPixelColor(j, color);
}
strips[NUM_STRIPS - 1].show();
}
Der finale Countdown soll über eine IR-Fernbedienung eingestellt werden können.
Ich konnte die Hex-Werte der Fernbedienung auslesen.
HEX-Wert: 45 -> 1
HEX-Wert: 46 -> 2
HEX-Wert: 47 -> 3
HEX-Wert: 44 -> 4
HEX-Wert: 40 -> 5
HEX-Wert: 43 -> 6
HEX-Wert: 7 -> 7
HEX-Wert: 15 -> 8
HEX-Wert: 9 -> 9
HEX-Wert: 19 -> 0
HEX-Wert: 18 -> up
HEX-Wert: 5A -> right
HEX-Wert: 52 -> down
HEX-Wert: 8 -> left
HEX-Wert: 1C -> ok
Mein erster versuch war einfach mal den Countdown über die Taste "OK" Starten und Stoppen zu können.
Wofür ich dieses Programm erstellt habe:
#include <Adafruit_NeoPixel.h>
#include <IRremote.h>
// Pin-Definition für den IR-Empfänger
const byte IR_RECEIVE_PIN = 11;
IRrecv irReceiver(IR_RECEIVE_PIN);
decode_results results;
bool countdownRunning = true;
// Pin-Definitionen für die NeoPixel-Streifen
#define PIN_LED_STRIP_1 2 // Pin für den ersten NeoPixel-Streifen
#define PIN_LED_STRIP_2 3 // Pin für den zweiten NeoPixel-Streifen
#define PIN_LED_STRIP_3 4 // Pin für den dritten NeoPixel-Streifen
#define PIN_LED_STRIP_4 5 // Pin für den vierten NeoPixel-Streifen
#define PIN_LED_STRIP_5 6 // Pin für den fünften NeoPixel-Streifen
#define PIN_LED_STRIP_6 7 // Pin für den sechsten NeoPixel-Streifen
#define PIN_LED_STRIP_7 8 // Pin für den siebten NeoPixel-Streifen
#define PIN_LED_STRIP_8 9 // Pin für den achten NeoPixel-Streifen
#define PIN_LED_STRIP_9 10 // Pin für den neunten NeoPixel-Streifen
#define PIN_LED_STRIP_10 12 // Pin für Buchstabenbeleuchtung
#define NUM_LEDS 7 // Anzahl der LEDs Strip 1-9
#define NUM_LEDS_STRIP_10 12 // Anzahl der LEDs in Strip 10
#define NUM_STRIPS 10
// Array für die NeoPixel-Streifen
Adafruit_NeoPixel strips[NUM_STRIPS] = {
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_1, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_2, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_3, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_4, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_5, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_6, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_7, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_8, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, PIN_LED_STRIP_9, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS_STRIP_10, PIN_LED_STRIP_10, NEO_GRB + NEO_KHZ800)// Anpassung für 12 LEDs
};
unsigned long startTime;
unsigned long countdownDuration = 2UL * 365UL * 24UL * 60UL * 60UL * 1000UL; // 2 Jahre in Millisekunden
// Definition der 7-Segment Zahlen
// -->
// ¦ ¦
// ------>
// ¦ ¦
// <--
int segments[10][7] = {
{0, 1, 1, 1, 1, 1, 1}, // 0
{0, 1, 0, 0, 0, 0, 1}, // 1
{1, 0, 1, 1, 0, 1, 1}, // 2
{1, 1, 1, 0, 0, 1, 1}, // 3
{1, 1, 0, 0, 1, 0, 1}, // 4
{1, 1, 1, 0, 1, 1, 0}, // 5
{1, 1, 1, 1, 1, 1, 0}, // 6
{0, 1, 0, 0, 0, 1, 1}, // 7
{1, 1, 1, 1, 1, 1, 1}, // 8
{1, 1, 1, 0, 1, 1, 1} // 9
};
// Definition der Zuordnung von Ziffern zu den LED-Strips
int digitStrips[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
void displayCountdown();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600);
Serial.print("Empfänger Starten");
//irReceiver.enableIRIn(); // Starte den Infrarot-Empfänger
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
startTime = millis(); // Initialisiere startTime
for (int i = 0; i < NUM_STRIPS; i++) {
strips[i].begin();
strips[i].show(); // Zeige die Anfangszustand der Strips
}
// Setze die Anfangszeit des Countdowns
unsigned long initialDays = 0;
unsigned long initialHours = 0;
unsigned long initialMinutes = 0;
unsigned long initialSeconds = 0;
countdownDuration = (initialDays * 24UL * 60UL * 60UL + initialHours * 60UL * 60UL + initialMinutes * 60UL + initialSeconds) * 1000UL;
Serial.print("Initial Countdown Time: ");
Serial.print(initialDays);
Serial.print(" days, ");
Serial.print(initialHours);
Serial.print(" hours, ");
Serial.print(initialMinutes);
Serial.print(" minutes, ");
Serial.print(initialSeconds);
Serial.println(" seconds");
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
if (irReceiver.decode()) {
handleIRCommand(results.value);
irReceiver.resume(); // Empfang für das nächste Signal vorbereiten
}
if (countdownRunning) {
displayCountdown();
}
}
void handleIRCommand(unsigned long irValue) {
Serial.print("Unknown signal: 0x");
Serial.println(results.value);
Serial.println(IrReceiver.decodedIRData.command);
switch (irValue) {
case 0x1C: // "OK"-Taste
if (countdownRunning) {
stopCountdown();
Serial.println("Countdown gestoppt.");
} else {
startCountdown();
Serial.println("Countdown gestartet.");
}
break;
}
}
void startCountdown() {
startTime = millis();
countdownRunning = true;
}
void stopCountdown() {
countdownRunning = false;
}
void displayCountdown() {
unsigned long currentTime = millis();
unsigned long elapsedTime = currentTime - startTime;
unsigned long remainingTime = countdownDuration - elapsedTime;
// Calculate remaining days, hours, minutes, and seconds
unsigned long remainingDays = remainingTime / (24UL * 60UL * 60UL * 1000UL);
remainingTime %= (24UL * 60UL * 60UL * 1000UL);
unsigned long remainingHours = remainingTime / (60UL * 60UL * 1000UL);
remainingTime %= (60UL * 60UL * 1000UL);
unsigned long remainingMinutes = remainingTime / (60UL * 1000UL);
remainingTime %= (60UL * 1000UL);
unsigned long remainingSeconds = remainingTime / 1000UL;
displayDigitsOnStrip(remainingDays / 100, 0); // Hundertstelle der Tage
displayDigitsOnStrip((remainingDays / 10) % 10, 1); // Zehnerstelle der Tage
displayDigitsOnStrip(remainingDays % 10, 2); // Einerstelle der Tage
displayDigitsOnStrip(remainingHours / 10, 3); // Zehnerstelle der Stunden
displayDigitsOnStrip(remainingHours % 10, 4); // Einerstelle der Stunden
displayDigitsOnStrip(remainingMinutes / 10, 5); // Zehnerstelle der Minuten
displayDigitsOnStrip(remainingMinutes % 10, 6); // Einerstelle der Minuten
displayDigitsOnStrip(remainingSeconds / 10, 7); // Zehnerstelle der Sekunden
displayDigitsOnStrip(remainingSeconds % 10, 8); // Einerstelle der Sekunden
// Neue Funktion für LED Strip 10
displayColorOnStrip(strips[NUM_STRIPS - 1].Color(255, 0, 0)); // Rote LEDs für Strip 10
}
void displayDigitsOnStrip(int digit, int stripIndex) {
for (int j = 0; j < 7; j++) {
if (segments[digit][j]) {
strips[digitStrips[stripIndex]].setPixelColor(j, strips[digitStrips[stripIndex]].Color(255, 0, 0)); // Rote LEDs für die Ziffer
} else {
strips[digitStrips[stripIndex]].setPixelColor(j, strips[digitStrips[stripIndex]].Color(0, 0, 0)); // Ausschalten der LEDs für inaktive Segmente
}
}
strips[digitStrips[stripIndex]].show(); // Zeige die Ziffer auf dem entsprechenden LED-Streifen
}
// Seperate Funktion für LED Strip 10
void displayColorOnStrip(uint32_t color) {
for (int j = 0; j < strips[NUM_STRIPS - 1].numPixels(); j++) {
strips[NUM_STRIPS - 1].setPixelColor(j, color);
}
strips[NUM_STRIPS - 1].show();
}
In diesem Programm erkennt er aber die Signale der Fernbedienung nicht. Beziehungsweise stimmen die Tastenwerte nicht überein mit den ausgelesen Werten.
Eigentlich möchte ich es wie eine Backofenuhr einstellen können. Sprich die knöpfe rechts/links sollen zwischen den zahlen navigieren wobei die gewählte stelle Blinken soll, hoch/runter soll den Wert +1/-1 verändern und die Zahlen sollen den definierten wert direkt schreiben. Dann noch "OK für Start und Stopp.
Diese Aufgabe ist leider über meinen Kenntnissen, ich hoffe jemand kann mir weiterhelfen
Grüsse