====== NeoPixel-Beleuchtung für SilentBase 800 Programmversion 0.8 ====== Gegenüber [[silentbase_neopixel:programmversion_0.7|Programmversion 0.7]] enthält dieser Sketch kleinere Verbesserungen am Code und zwei neue Effekte. Beide sollen Feuer nachahmen. Der Effekt Nr. 5 könnte ganz gut bei einer waagerechten Anordnung aussehen.((Siehe dazu https://www.youtube.com/watch?v=-2hk6rxlrGA und http://www.walltech.cc/neopixel-fire-effect/)) In eine zukünftige Version 1.0 würde er es so nicht schaffen. Effekt Nr. 6 ist auch ganz gut gelungen. Der Effekt ist von der Variable load abhängig: Bei ruhendem Desktop lodern die Flammen 15 bis 20 Pixel hoch, bei voller Last schladen sie bis nach oben. Der Sketch enthält Code von [[https://www.baldengineer.com/millis-cookbook.html|Baldengineer]], [[http://www.scynd.de/tutorials/arduino-tutorials/1-taster/1-2-taster-entprellt.html|Scynd]] und [[http://www.walltech.cc]]. // Bibliotheken einbinden #include #include #include // Definiert die Pins #define buttonPin 7 // Taster #define loadPin A0 // analoge Spannungsmessung #define neoPin1 11 // Neopixel-Strip rechte Seite #define neoPin2 12 // Neopixel-Strip linke Seite // Definiert eine Adresse im EEPROM int addr = 0; // An dieser Adresse wird später der ausgewählte Programmmodus gespeichert // Definiert ein ResponsiveAnalogRead Objekt ResponsiveAnalogRead rload(loadPin, true); // Definiert die Variablen int numPixels = 64; // Anzahl der NeoPixel int load; // Variable repäsentiert später die Differenz zwischen minimaler und maximaler Netzteillast in Prozent int buttonstate = HIGH; // aktuelles Signal vom Tasterpin int buttonpressed = 0; // abfragen ob Taster gedrückt war int debouncetime = 50; // Zeit für Entprellung ggf. anpassen float rloadmin = 350; // Messwert am loadPin bei minimaler Netzteillast float rloadmax = 650; // Messwert am loadPin bei maximaler Netzteillast float x = 0; // Zählwert für verschiedene Beleuchtungseffekte boolean sw1 = true; // Schaltvariable für verschiedene Beleuchtungseffekte boolean sw2 = true; // Schaltvariable für verschiedene Beleuchtungseffekte int i; // Zählwert für verschiedene Beleuchtungseffekte int j; // Zählwert für verschiedene Beleuchtungseffekte int k; // Zählwert für verschiedene Beleuchtungseffekte byte programmode = 0; // Programmmodus // Definiert die NeoPixel-Strips Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(numPixels, neoPin1, NEO_GRBW + NEO_KHZ800); Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(numPixels, neoPin2, NEO_GRBW + NEO_KHZ800); // Definiert die globalen RGBW-Werte byte r = 0; byte g = 0; byte b = 0; byte w = 0; // Definiert die Tracking-Variablen für die IF-Abfragen unsigned long previousMillisCalcLoad = 0; unsigned long previousMillisNeoPixel = 0; unsigned long previousMillisSerialPrint = 0; unsigned long buttontime = 0; unsigned long sparkle1on = 0; unsigned long sparkle1off = 0; unsigned long sparkle1ondelay = 100; unsigned long sparkle1offdelay = 500; unsigned long sparkle2on = 0; unsigned long sparkle2off = 0; unsigned long sparkle2ondelay = 100; unsigned long sparkle2offdelay = 500; // Definiert die Intervalle für die IF-Abfragen int intervalCalcLoad = 500; // Delay für Berechnung der Last int intervalNeoPixel = 50; // Delay für Ansteuerung der NeoPixel int intervalSerialPrint = 1000; // Delay für serielle Ausgabe void setup() { // Initialisiere den Button-Pin pinMode(buttonPin, INPUT_PULLUP); // Initialisiere die NeoPixel-Pins pinMode(neoPin1, OUTPUT); pinMode(neoPin2, OUTPUT); // Initialisiere den analogen Pin pinMode(loadPin, INPUT); // Initialisiere die NeoPixel-Strips strip1.begin(); // Initialisiert das Neopixel strip1.show(); // Macht das NeoPixel sichtbar //strip1.clear(); // Macht das NeoPixel aus strip2.begin(); // Initialisiert das Neopixel strip2.show(); // Macht das NeoPixel sichtbar //strip2.clear(); // Macht das NeoPixel aus // Lese den abgespeicherten Wert für den Programmmodus aus dem EEPROM programmode = EEPROM.read(addr); // Initialisiere die serialle Schnittstelle Serial.begin(57600); delay (2000); } void loop() { // Lesen und entprellen des Tasters buttonstate = digitalRead(buttonPin); // Wenn der Taster gedrückt ist... if (buttonstate == LOW) { buttontime = millis(); // aktualisiere tasterZeit buttonpressed = 1; // speichert, dass Taster gedrückt wurde } // Wenn die gewählte entprellZeit vergangen ist und der Taster gedrückt war... if ((millis() - buttontime > debouncetime) && buttonpressed == 1) { buttonpressed = 0; // setzt gedrückten Taster zurück programmode++; // Programmmodus wird um +1 erhöht EEPROM.write(addr, programmode); // Schreibt den Programmmodus ins EEPROM r = 0; // setzt den globalen Farbwert zurück g = 0; // setzt den globalen Farbwert zurück b = 0; // setzt den globalen Farbwert zurück w = 0; // setzt den globalen Farbwert zurück strip1.clear(); // setzt die NeoPixel zurück strip2.clear(); // setzt die NeoPixel zurück } // Aktuelle Zeit abfragen unsigned long currentMillis = millis(); // Messen und Berechnen der Last des Netzteils if ((unsigned long)(currentMillis - previousMillisCalcLoad) >= intervalCalcLoad) { // Auslesen des analogen Eingangs (Last Netzteil) rload.update(); // Berechnung der Netzteillast in Prozent load = 100 - ((rloadmax - rload.getValue()) / (rloadmax - rloadmin)) * 100; //Speichere die aktuelle Zeit in die zughörige Variable previousMillisCalcLoad = currentMillis; } // Steuerung der NeoPixel-Strips // Beleuchtungseffekt für Programmmodus 0 (Atmen rot) if (programmode == 0) { if ((unsigned long)(currentMillis - previousMillisNeoPixel) >= intervalNeoPixel) { if(load < 10) { // Variable soll für diesen Effekt nicht kleiner als 10 werden load = 10; } // Ansteuerung der NeoPixel-Strips x = x + (0.05 * (load/10)); if (x >= 6.28) { x = 0; } // fade led mit x r = ((exp(sin(x)) - 0.36787944) * 108.492061351); for (int i = 0; i < numPixels; i++) { strip1.setPixelColor(i, r, g, b, w); strip2.setPixelColor(i, r, g, b, w); } strip1.show(); strip2.show(); //Speichere die aktuelle Zeit in die zughörige Variable previousMillisNeoPixel = currentMillis; } } //Beleuchtungseffekt für Programmmodus 1 (Atmen weiß) else if (programmode == 1) { if ((unsigned long)(currentMillis - previousMillisNeoPixel) >= intervalNeoPixel) { if(load < 10) { // Variable soll für diesen Effekt nicht kleiner als 10 werden load = 10; } // Ansteuerung der NeoPixel-Strips x = x + (0.05 * (load/10)); if (x >= 6.28) { x = 0; } // fade led mit x w = ((exp(sin(x)) - 0.36787944) * 108.492061351); for (int i = 0; i < numPixels; i++) { strip1.setPixelColor(i, r, g, b, w); strip2.setPixelColor(i, r, g, b, w); } strip1.show(); strip2.show(); //Speichere die aktuelle Zeit in die zughörige Variable previousMillisNeoPixel = currentMillis; } } //Beleuchtungseffekt für Programmmodus 2 (Stabthermometer) else if (programmode == 2) { if ((unsigned long)(currentMillis - previousMillisNeoPixel) >= intervalNeoPixel) { if(load >= numPixels) { // Variable soll für diesen Effekt nicht größer als NeoPixel vorhanden load = 63; } // Weißer Bereich for (int i = 0; i < numPixels; i++) { strip1.setPixelColor(i, r, g, b, 127); strip2.setPixelColor(i, r, g, b, 127); } // Roter Bereich for (int i = 63; i > (63 - load); i--) { strip1.setPixelColor(i, 127, g, b, w); strip2.setPixelColor(i, 127, g, b, w); } strip1.show(); strip2.show(); //Speichere die aktuelle Zeit in die zughörige Variable previousMillisNeoPixel = currentMillis; } } //Beleuchtungseffekt für Programmmodus 3 (Stabthermometer mit Glitzer) else if (programmode == 3) { if ((unsigned long)(currentMillis - previousMillisNeoPixel) >= intervalNeoPixel) { if(load >= numPixels) { // Variable soll für diesen Effekt nicht größer als NeoPixel vorhanden load = 63; } // Blauer Bereich for (int i = 0; i < numPixels; i++) { strip1.setPixelColor(i, r, g, 127, w); strip2.setPixelColor(i, r, g, 127, w); } // Roter Bereich for (int i = 63; i > (63 - load); i--) { strip1.setPixelColor(i, 127, g, b, w); strip2.setPixelColor(i, 127, g, b, w); } // Sparkle NeoPixel-Strip 1 if(sw1) { strip1.setPixelColor(j, r, g, b, 255); if(millis() - sparkle1on >= sparkle1ondelay) { sparkle1offdelay = random (100, 1000); sparkle1off = millis(); sw1 = !sw1; } } if(!sw1) { if(millis() - sparkle1off >= sparkle1offdelay) { j = random(0, (numPixels -1)); sparkle1on = millis(); sw1 = !sw1; } } // Sparkle NeoPixel-Strip 2 if(sw2) { strip2.setPixelColor(k, r, g, b, 255); if(millis() - sparkle2on >= sparkle2ondelay) { sparkle2offdelay = random (100, 1000); sparkle2off = millis(); sw2 = !sw2; } } if(!sw2) { if(millis() - sparkle2off >= sparkle2offdelay) { k = random(0, (numPixels - 1)); sparkle2on = millis(); sw2 = !sw2; } } // Sende die Daten an die Neopixel strip1.show(); strip2.show(); //Speichere die aktuelle Zeit in die zughörige Variable previousMillisNeoPixel = currentMillis; } } //Beleuchtungseffekt für Programmmodus 4 (Feuer 1) else if (programmode == 4) { if ((unsigned long)(currentMillis - previousMillisNeoPixel) >= intervalNeoPixel) { for (int i = 0; i < numPixels; i++) { int flicker = random (0, 150); int r = 255; int g = r-100; int b = 30; r = r - flicker; g = g - flicker; b = b - flicker; if(r < 0) r = 0; if(g < 0) g = 0; if(b < 0) b = 0; strip1.setPixelColor(i, r, g, b, 0); strip2.setPixelColor(i, r, g, b, 0); } // Sende die Daten an die Neopixel strip1.show(); strip2.show(); //Speichere die aktuelle Zeit in die zughörige Variable previousMillisNeoPixel = currentMillis; } } //Beleuchtungseffekt für Programmmodus 5 (Feuer 2) else if (programmode == 5) { if ((unsigned long)(currentMillis - previousMillisNeoPixel) >= intervalNeoPixel) { if(load >= numPixels) { // Variable soll für diesen Effekt nicht größer als NeiPoxel vorhanden load = 63; } int r = 255; int g = 130; int b = 30; int w = 63; for (int i = (numPixels -1); i > 0; i--) { int flicker = random (0, (42 - (load/2))); r = r - flicker; g = g - flicker; b = b - flicker; w = w - (flicker * 3); if(r < 0) r = 0; if(g < 0) g = 0; if(b < 0) b = 0; if(w < 0) w = 0; strip1.setPixelColor(i, r, g, b, w); strip2.setPixelColor(i, r, g, b, w); } // Sende die Daten an die Neopixel strip1.show(); strip2.show(); //Speichere die aktuelle Zeit in die zughörige Variable previousMillisNeoPixel = currentMillis; } } // Wenn der Programmodus auf einen höheren Wert sprngt, wird er zurück auf 0 gesetzt und beginnt von vorne else { programmode = 0; } // Ausgabe an die serielle Schnittstelle if ((unsigned long)(currentMillis - previousMillisSerialPrint) >= intervalSerialPrint) { //Ausgabe der gemessenen Netzteillast an die sereille Schnittstelle //Serial.print("Last (gemessen): "); Serial.println(rlast); //Ausgabe der berechneten Netzteillast an die sereille Schnittstelle Serial.print("Last (prozentual): "); Serial.print(load); Serial.println(" %"); //Ausgabe der Werte von ResponsiveAnalogRead Serial.print("Last (getRawValue): "); Serial.println(rload.getRawValue()); Serial.print("Last (getValue): "); Serial.println(rload.getValue()); // if the repsonsive value has change, print out 'changed' if(rload.hasChanged()) { Serial.println("\tchanged"); } // Ausgabe Zustand Taster Serial.print("Taster: "); Serial.println(buttonstate); // Ausgabe Programmzähler Serial.print("Programm Nr.: "); Serial.println(programmode); // Ausgabe Zufallswerte Serial.print("Randomwert fuer j: "); Serial.println(j); Serial.print("Randomwert fuer t1: "); Serial.println(sparkle1offdelay); Serial.print("Randomwert fuer t2: "); Serial.println(sparkle2offdelay); //Speichere die aktuelle Zeit in die zughörige Variable previousMillisSerialPrint = currentMillis; } } Der Sketch verwendet 10.312 Bytes (31%) des Programmspeicherplatzes. Das Maximum sind 32.256 Bytes. Globale Variablen verwenden 495 Bytes (24%) des dynamischen Speichers, 1.553 Bytes für lokale Variablen verbleiben. Das Maximum sind 2.048 Bytes. Tags: #Arduino # NeoPixel