überlege dir mal, wie du eine Blinkleuchte realisieren würdest, weil man im Schmuckladen deines Bahnhofs eingebrochen hat.
--> Blink without delay
also mach erst mal eine Blinkled.
Wenn die Blinkerei läuft, kannst du deinen TV angehen.
Jetzt überleg dir mal was du für deinen TV tun müsstest:
erste For schleife: die regelt den Ablauf, also merk dir das i
zweite For schleife: ist eigentlich jetzt schon ein nonsense, da hätte ein delay(20j) auch gereicht.
Das verwendest du als künftigen Intervall
Auflösen des delay(20) --> ergibt den intervall 20j
Du hast nun einen Zähler als Statemachine (dein i), und einen Intervall (für dein Blink Without Delay)
ungeprüft unter der Annahme, dass die Funktion so oft wie möglich aufgerufen wird, wenn der TV laufen soll
void simulation_TV ()
{
static uint32_t previousMillis = 0; // static, damit der Wert nach Ende der Funktion erhalten bleibt, spart uns eine globale Variable.
static uint16_t intervall = 0; // ersetzt j
static uint16_t actual = 0; // früher i
if (millis() - previousMillis > intervall) // analog "Blink Without Delay"
{
intervall = pgm_read_byte(&(brightness[actual][0])) * 20; // gelesenen Wert gleich vervielfachen, ersetzt unser delay(20)
byte red = pgm_read_byte(&(brightness[actual][1]));
byte green = pgm_read_byte(&(brightness[actual][2]));
byte blue = pgm_read_byte(&(brightness[actual][3]));
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
previousMillis = millis(); // aktuelle Zeit als Aufrufzeit merken
actual++; // actual fürs nächste mal weiterdrehen. Ist wohl geschmackssache ob du das am ende oder am Anfang machst, jedenfalls wollen wir den nächsten Aufruf mit dem nächsten "i" haben
if (actual >= elements) actual = 0;
}
}
}
P.S.:
{198, 1, 1, 1},
{ 1, 1, 1, 1}
ich bezweifle, dass man ein PWM 1 auf einer LED sieht, das heißt hier schaltet der TV für 19820 millis ab und dann noch mal für 120 millis. D.h. du verschwendest hier weitere 4 Byte Progmem. Der Fernseher ist somit "schwarz" obwohl er noch läuft.