Hi
Habe die letzten Tage damit verbracht, meine letzte chinesische Lieferung, einem Grafik-LCD, Leben einzuhauchen.
Dazu nur so viel: Es wehrt Sich ... ich brauchte 'einen Erfolg'!
Da ich auch eine Rolle WS2812 bekommen hatte (5 Meter a 30 LED/m), wurde Die an einen Nano getackert und die Bude die Nacht über illuminiert.
Heute kramte ich den Sketch für das Auf-/Abdimmen benachbarter Pixel hervor (als Beispiel für eine Uhr -> Sekundenzeiger entstanden).
Diesen umgeschrieben/angepasst, daß jetzt ein 'Lichtpunkt' den Stripe entlang 'gleitet'.
Ab und zu glitzern vereinzelt Sterne (Blitze), Die den Lichtpunkt natürlich wieder zurück 'in Wagenfarbe' verlassen, sollte der Blitz in aktiv leuchtendem Bereich aufgeleuchtet sein.
Ganz nebenbei fiel mir die Funktion setBrightness(xx); der Adafruit_NeoPixel Lib in die Finger (v1.1.3 ... sehe gerade, 1.1.5 ist aktuell).
Mit Dieser kann die 'Grundhelligkeit' eingestellt werden - nachfolgende Farben werden auf diese Helligkeit 'herunter gedimmt' - also ein 255,255,255 ist dann keinesfalls 'volle Kanne weiß', sondern weiß in 'brightness'-Wert.
Das aber nur nebenbei bemerkt - vll. hat's ja wer noch nicht entdeckt und kann Damit 'was anfangen'.
Edit 04.02. @19:11 Hier Beitrag #8 gibt's den halbwegs laufenden Sketch
Dann der Sketch:
/*
Weihnachtsbaum-Lichterkette
An der Kette sollen grüne Leuchtpunkte (mehr oder minder) gemächlich rauf/runter gleiten
Zufällig werden Blitze (funkelnde Sterne ;) ) erzeugt, Diese werden nicht durch die Animation gestört
Akut ist nur ein Leuchtpunkt unterwegs - geplant sind MEEEHR, Die mit unterschiedlicher Geschwindigkeit
den Stripe rauf oder runter gleiten. Wenn diese Leuchtpunkte sich überschneiden, bestimmt die hellere
LED, wie hell der Punkt leuchten soll. Vll. die Leuchtpunkte nur mit 30% Helligkeit laufen lassen und
die Helligkeit addieren - wird auf einen Test hinaus laufen, wie Das aussieht.
*/
#include <Adafruit_NeoPixel.h> //v1.1.3, aus der Bibkliotheks-Verwaltung
//Anzahl der verbauten WS2812, bei der 4x4-Platine dann hier 16
const uint16_t PixelCount = 150; // Anzahl der Pixel
const uint8_t PixelPin = 13; // angeschlossen an Pin
//Die Maximal-Farbe für 100% - r Rot, g Grün, b Blau - also hier den RGB-Wert der maximalen Helligkeit eintragen
const byte rmax = 18; //Wert 0...255 bei maximaler Helligkeit
const byte gmax = 127;
const byte bmax = 11;
//ein Grün - für 'in den Baum'
//Die Wartezeit zwischen zwei 'benachbarten' LED - für den Sekundenzeiger hier 1000 für 1000ms verwenden, unter 300 ist von dem Aus/Abdimmen nicht mehr viel zu sehen.
const int wartezeit = 30; //Zeit zwischen den Einzelpixeln
const int animationszeit = 30; //Wartezeit für die Anfangs-Animation
const int blitzwartezeit = 10; //wie lange soll der Blitz AN sein?
//Hilfsvariablen, um die vergangene Zeit mitzuhalten
long lasttime; //Zeit, als der letzte Mittel-Pixel gewechselt wurde
long aktutime; //aktuelle Zeit, wird im Script laufend neu auf millis() gesetzt
//mit welcher LED soll begonnen werden? Hier müssen händisch die LEDs davor/dahinter eingetragen werden
//wenn der Abstand größer als 1 ist, leuchten halt mehrere LEDs im Zwischenraum in voller Helligkeit
//die LEDs davor und danach werden je nach 'Abstand' zur Zeit hoch/runter gedimmt
//es ist immer eine LED voll an
byte LED_davor = 0, LED_danach = 1; //mindestens 1 Abstand!!
//Den Stripe initialisieren
Adafruit_NeoPixel rgbstripe = Adafruit_NeoPixel(PixelCount, PixelPin, NEO_GRB + NEO_KHZ800);
void setup() {
rgbstripe.begin(); //Stripe initiieren, RAM vorbereiten
rgbstripe.setBrightness(255); //Helligkeit auf bestimmten Wert
//Der Sketch soll geschwätzig sein
Serial.begin(9600);
//Das Auge will auch was davon haben - eine 'Start-Animation'
aktutime = millis();
for (int t = 0; t < PixelCount; t++) {
rgbstripe.setPixelColor(t, rmax, gmax, bmax);
rgbstripe.show();
while (millis() - aktutime < animationszeit); //ohne delay ;)
aktutime += animationszeit;
}
for (int t = 0; t < PixelCount; t++) {
rgbstripe.setPixelColor(t, 0, 0, 0);
rgbstripe.show();
while (millis() - aktutime < animationszeit); //außerdem bleibt so das 'Raster' auf festen ms-Werten
aktutime += animationszeit;
}
//damit der Start nett aussieht, werden alle LEDs von 'davor' bis 'dahinter' auf 100% gesetzt
//im Sketch werden die 'äußeren' LEDs dann hoch/runter gedimmt
byte x = LED_davor;
while (x != LED_danach) {
rgbstripe.setPixelColor(x, rmax, gmax, bmax);
x = (x + 1) % PixelCount;
}
// die eingestellten Farben im Stripe anzeigen/die Daten in die WS2812 schicken
rgbstripe.show();
lasttime = millis(); //unsere Berechnungsgrundlage - die 'allererste' Zeit
}
void loop() {
static long unsigned blitzstart = 0;
static boolean blitz = 0;
static int blitzpixel;
if (millis() - blitzstart > blitzwartezeit) {
if (blitz == 1) {
//war der Blitz in einem voll leuchtendem Segment? Dann auf Leuchtfarbe, sonst löschen
//(die dimmenden Segmente werden eh neu gesetzt, daher egal ... sonst <= und >=)
Serial.print("von ");
Serial.print(LED_davor);
Serial.print(" bis ");
Serial.print(LED_danach);
Serial.print(" Blitz:");
Serial.print(blitzpixel);
if ((LED_davor < blitzpixel && LED_danach > blitzpixel) || (LED_davor>LED_danach&&(LED_davor > blitzpixel || LED_danach < blitzpixel) ) ) {
Serial.println(" INNEN -> auf Farbe");
rgbstripe.setPixelColor(blitzpixel, rmax, gmax, bmax);
} else {
Serial.println(" -> auf Schwarz");
rgbstripe.setPixelColor(blitzpixel, 0, 0, 0);
}
blitz = 0;
}
blitzpixel = random(0, 0xFFFF); //Variable wird für Zufallszahl missbraucht - ist hier in diesem Moment eh unbenutzt
if (blitzpixel > 0xFF00) {
//Zufallspixel aufblitzen lassen
blitzstart = millis(); //die Zeit merken, wann der Blitz begonnen hat
blitzpixel = random(0, PixelCount); //den Pixel bestimmen
//blitzpixel = 3; //zu Testzwecken, damit man weiß, wo's gleich blitzt
rgbstripe.setPixelColor(blitzpixel, 255, 255, 255); //auf Weiß und 100% setzen
blitz = 1;
}
}
//die aktuelle Zeit einlesen
aktutime = millis();
//die Differenz zwischen dem letzten Umsetzen der Mittel-Pixel
int milisek = aktutime - lasttime; //ergibt irgenbdwas bis knapp über 1000, alsp die ms, seit dem letzten Pixel-Wechsel
//wenn die bereits vergangene Wartezeit größer oder zumindest gleich der Wartezeit zwischen den Pixeln ist, werden die Nachbar-Pixel an, bzw. aus gestellt.
if (milisek >= wartezeit) {
//die 'Umsetz-Zeit' wird um die Wartezeit erhöht - so wird die Wartezeit immer eingehalten, auch, wenn der Script Mal irgendwo etwas langsamer war
lasttime += wartezeit;
//die Pixel davor/danach voll an/aus schalten
if (blitzpixel != LED_danach) rgbstripe.setPixelColor(LED_danach, rmax, gmax, bmax);
if (blitzpixel != LED_davor) rgbstripe.setPixelColor(LED_davor, 0, 0, 0);
LED_davor = (LED_davor + 1) % PixelCount;
LED_danach = (LED_danach + 1) % PixelCount;
} else {
//ansonsten, werden die Farben je nach 'Abstand' rauf/runter gedimmt, 100% entspricht der anfangs definierten Farbe
if (blitzpixel != LED_danach) rgbstripe.setPixelColor(LED_danach, map(milisek, 0, wartezeit, 0, rmax), map(milisek, 0, wartezeit, 0, gmax), map(milisek, 0, wartezeit, 0, bmax));
if (blitzpixel != LED_davor) rgbstripe.setPixelColor(LED_davor, rmax - map(milisek, 0, wartezeit, 0, rmax), gmax - map(milisek, 0, wartezeit, 0, gmax), bmax - map(milisek, 0, wartezeit, 0, bmax));
}
//Und wieder raus mit den Daten an den Stripe
rgbstripe.show();
}
Vll. bin ich nicht ganz 'auf der Zeit' - aber das nächste Weihnachten kommt bestimmt - und dann bin ich gerüstet.
MfG