Hi
Hatte mich Heute (ok, Gestern) an dem Sketch 'Ich habe Feuer gemacht...' probiert - nutze aber WS2812B-Stripes.
Lange Rede, kaum ein Sinn: Bekam den Sketch mit meinen WS2812B nicht ans Laufen.
In der FastLED-Lib gibt's ein Beispiel Fire2012, Welches ich, der Name klang 'artverwandt', etwas angepasst habe.
In meinem Fall soll die Flamme eine Kerze darstellen - die Sankt-Martins-Umzüge stehen vor der Tür und im Moment ermittle ich die Laufzeit der ganzen Mimik bei Versorgung mittels PowerBank.
Mein Aufbau umfasst 31 LED-Pixel auf einem Stripe mit 30 LED/Meter (also die billigsten Streifen), Welcher Sich 7x um eine KloPapierRolle wickeln lässt.
Damit der Arduino, Welcher den Stripe am 5V-Pin versorgen soll (und selbst via USB versorgt wird) nicht dahin schmilzt, sorge ich dafür, daß maximal 'x' LED gleichzeitig leuchten.
Das aber in schneller Abfolge, bei jedem loop()-Durchlauf werden die nächsten 'x' LEDs angezeigt.
Trotzdem wird nur alle zig Millisekunden der Effekt weiter geschaltet.
Ab einer Anzeige von 5 LEDs zur gleichen Zeit zeigt die KloRollenKerze kaum noch Flackern - mit einem Drucker-Papier als Diffusor schaut's schon ganz nett aus - in der Fledermaus-Laterne der Nichte sollte das Teil eine recht gute Figur machen
Ok, in dem Beispiel-Sketch 'Fire2012' wird in der Funktion Fire2012() das Array leds[ x ] mit den Farbwerten gefüllt.
Diese Zuweisung lasse ich auf ein separates Array set_led[ x ] erfolgen, um dann in der loop() in jedem Durchlauf 'die nächsten x Pixel' in das Array leds[] zu kopieren, was eine separate Funktion übernimmt.
Statt dem Delay, um auf die 'Frames_per_second' zu kommen, nutze ich INTERVAL (ebenfalls hier aus dem Forum)
Der Farbwert für WEISS wird wohl als 0xFF000000 (RGBW) oder 0x00FFFFFF (RGB) reichen, schicke in diesem Code aber der Zeit 0xFFFFFFFF (alle Bits gesetzt - ergibt weiß) - möge man, dem Strom Sparen Willen, anpassen.
#include <INTERVAL.h>
//Ein WS2812B-LED-Streifen mit 30 LED/Meter wird um eine Klopapier-Rolle
//drum herum geklebt. Bei meinem Streifen komme ich auf 'knapp über 4 LED
//pro 'Runde' - die 5.te LED sitzt leicht hinter der Ersten.
//Insgesamt bekomme ich 31 LED auf die Rolle.
//Zusätzlich zu 'Fire2012' wurde eine Begrenzung der gleichzeitig
//leuchtenden LED einprogrammiert - ab 5 lässt das Flackern nach -> 300mA max
// ... soll die 5V-Leiterbahnen des verwendeten Arduino schonen, versorgt
//wird Er per PowerBank und USB-Kabel.
//Alle x Frames (im Sketch einstellbar) blitzen (10ms zu 40ms) die LED weiß auf
//Als Diffusor ist ein Blatt Drucker-Papier angedacht
//Leuchtdauertest steht noch aus
#include <FastLED.h>
const uint8_t maxpunkte = 5; //maximal x gleichzeitig leuchtende LED-Pixel
uint8_t lastpixel = 0; //der zuletzt eingeschaltete Pixel
const uint8_t LED_PIN = 10;
#define COLOR_ORDER GRB
#define CHIPSET WS2811
const uint8_t NUM_LEDS = 31;
const uint16_t leuchtcount_normal=600; //Wert : Frames_per_second = Sekunden Laufzeit
const uint16_t leuchtcount_blitz=30;
const uint8_t BRIGHTNESS = 255;
const uint8_t FRAMES_PER_SECOND = 60;
bool gReverseDirection = false;
CRGB leds[NUM_LEDS];
CRGB set_leds[NUM_LEDS]; //hier werden die Farbei eingetragen, um von
//der Begrenzungsfunktion (maximal gleichzeitig
//leuchtender LED) in leds[] kopiert zu werden
void setup() {
delay(3000); // sanity delay
FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness( BRIGHTNESS );
}
void loop()
{
static uint16_t framecounter = 0;
// Add entropy to random number generator; we use a lot of it.
// random16_add_entropy( random());
INTERVAL(1000UL / FRAMES_PER_SECOND) {
Fire2012(); // run simulation frame
framecounter++;
}
if (framecounter > leuchtcount_normal) {
CRGB wert = 0;
if (millis() % 50 > 40) { //10ms Blitz
wert = 0xFFFFFFFF;
}
for (byte u = 0; u < NUM_LEDS; u++) {
set_leds[u] = wert;
}
if (framecounter >= leuchtcount_normal+leuchtcount_blitz) {
framecounter = 0;
}
}
//Begrenzen der gleichzeitig leuchtenden Pixel
kopiere_leds();
FastLED.show(); // display this frame
}
void kopiere_leds(void) {
for (byte u = 0; u < NUM_LEDS; u++) { //Pixel löschen
leds[u] = 0;
}
byte pixelanzahl = 0;
for (byte u = NUM_LEDS; u > 0; u--) { //maximal 'maxpunkte' Pixel anschalten
lastpixel++;
if (lastpixel >= NUM_LEDS) {
lastpixel = 0;
}
if (isPixelOn(lastpixel)) {
// debugPrint("Setze Pixel ");
// debugPrintln(lastpixel);
leds[lastpixel] = set_leds[lastpixel];
pixelanzahl++;
if (pixelanzahl >= maxpunkte) { //wenn bereits die maximale Anzahl an Pixel leuchten, FOR abbrechen
break;
}
}
}
}
boolean isPixelOn(uint8_t pixelnr) {
return set_leds[pixelnr];
}
// Fire2012 by Mark Kriegsman, July 2012
// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
////
// This basic one-dimensional 'fire' simulation works roughly as follows:
// There's a underlying array of 'heat' cells, that model the temperature
// at each point along the line. Every cycle through the simulation,
// four steps are performed:
// 1) All cells cool down a little bit, losing heat to the air
// 2) The heat from each cell drifts 'up' and diffuses a little
// 3) Sometimes randomly new 'sparks' of heat are added at the bottom
// 4) The heat from each cell is rendered as a color into the leds array
// The heat-to-color mapping uses a black-body radiation approximation.
//
// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
//
// This simulation scales it self a bit depending on NUM_LEDS; it should look
// "OK" on anywhere from 20 to 100 LEDs without too much tweaking.
//
// I recommend running this simulation at anywhere from 30-100 frames per second,
// meaning an interframe delay of about 10-35 milliseconds.
//
// Looks best on a high-density LED setup (60+ pixels/meter).
//
//
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames. More cooling = shorter flames.
// Default 50, suggested range 20-100
#define COOLING 35
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire. Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
#define SPARKING 120
void Fire2012()
{
// Array of temperature readings at each simulation cell
static byte heat[NUM_LEDS];
// Step 1. Cool down every cell a little
for ( int i = 0; i < NUM_LEDS; i++) {
heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for ( int k = NUM_LEDS - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
}
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
if ( random8() < SPARKING ) {
int y = random8(7);
heat[y] = qadd8( heat[y], random8(160, 255) );
}
// Step 4. Map from heat cells to LED colors
for ( int j = 0; j < NUM_LEDS; j++) {
CRGB color = HeatColor( heat[j]);
int pixelnumber;
if ( gReverseDirection ) {
pixelnumber = (NUM_LEDS - 1) - j;
} else {
pixelnumber = j;
}
set_leds[pixelnumber] = color;
}
}
Vll. kann ja Wer was mit meinem Versuch anfangen
MfG