|
4 | 4 | #include <string.h>
|
5 | 5 | #include <list>
|
6 | 6 | #include <stdlib.h>
|
| 7 | +#include <math.h> |
7 | 8 | #include "esp_wifi.h"
|
8 | 9 | #include "esp_system.h"
|
9 | 10 | #include "nvs_flash.h"
|
@@ -83,6 +84,7 @@ struct action_flame_t{
|
83 | 84 | int length;
|
84 | 85 | float freq;
|
85 | 86 | int random;
|
| 87 | + int nb_leds; |
86 | 88 | };
|
87 | 89 |
|
88 | 90 | enum class action_type_t { flash, wave, wavelet, flame };
|
@@ -129,6 +131,83 @@ float flash_progress_to_intensity(int progress_ms,int duration_ms)
|
129 | 131 | return 2*pos;//so that 0.5 => 1
|
130 | 132 | }
|
131 | 133 |
|
| 134 | +void simple_fire(WS2812* leds,action_flame_t &flame) |
| 135 | +{ |
| 136 | + // Flicker, based on our initial RGB values |
| 137 | + for(int i=0; i<g_nb_led; i++) |
| 138 | + { |
| 139 | + int flicker = rand() % flame.random; |
| 140 | + int r1 = flame.color.red-flicker; |
| 141 | + int g1 = flame.color.green-flicker; |
| 142 | + int b1 = flame.color.blue-flicker; |
| 143 | + if(g1<0) g1=0; |
| 144 | + if(r1<0) r1=0; |
| 145 | + if(b1<0) b1=0; |
| 146 | + leds->setPixel(i,r1,g1, b1); |
| 147 | + } |
| 148 | +} |
| 149 | + |
| 150 | +//https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectFire |
| 151 | +void t4all_fire(WS2812* leds,action_flame_t &flame) |
| 152 | +{ |
| 153 | + int Cooling = 55; |
| 154 | + int Sparking = 120; |
| 155 | + int SpeedDelay = 15; |
| 156 | + static uint8_t heat[g_nb_led];//max nb leds is g_nb_leds |
| 157 | + int cooldown; |
| 158 | + |
| 159 | + // Step 1. Cool down every cell a little |
| 160 | + for( int i = 0; i < flame.nb_leds; i++) |
| 161 | + { |
| 162 | + cooldown = rand() % (((Cooling * 10) / flame.nb_leds) + 2); |
| 163 | + |
| 164 | + if(cooldown>heat[i]) |
| 165 | + { |
| 166 | + heat[i]=0; |
| 167 | + } |
| 168 | + else |
| 169 | + { |
| 170 | + heat[i]=heat[i]-cooldown; |
| 171 | + } |
| 172 | + } |
| 173 | + |
| 174 | + // Step 2. Heat from each cell drifts 'up' and diffuses a little |
| 175 | + for( int k= flame.nb_leds - 1; k >= 2; k--) |
| 176 | + { |
| 177 | + heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3; |
| 178 | + } |
| 179 | + |
| 180 | + // Step 3. Randomly ignite new 'sparks' near the bottom |
| 181 | + if( (rand()%255) < Sparking ) |
| 182 | + { |
| 183 | + int y = (rand()%7); |
| 184 | + heat[y] = heat[y] + 160+(rand() % (255-160)); |
| 185 | + //heat[y] = random(160,255); |
| 186 | + } |
| 187 | + |
| 188 | + // Step 4. Convert heat to LED colors |
| 189 | + for( int j = 0; j < flame.nb_leds; j++) |
| 190 | + { |
| 191 | + uint8_t temperature = heat[j]; |
| 192 | + int Pixel = j; |
| 193 | + // Scale 'heat' down from 0-255 to 0-191 |
| 194 | + uint8_t t192 = round((temperature/255.0)*191); |
| 195 | + |
| 196 | + // calculate ramp up from |
| 197 | + uint8_t heatramp = t192 & 0x3F; // 0..63 |
| 198 | + heatramp <<= 2; // scale up to 0..252 |
| 199 | + |
| 200 | + // figure out which third of the spectrum we're in: |
| 201 | + if( t192 > 0x80) { // hottest |
| 202 | + leds->setPixel(Pixel, flame.color.red, flame.color.green, heatramp); |
| 203 | + } else if( t192 > 0x40 ) { // middle |
| 204 | + leds->setPixel(Pixel, flame.color.red, heatramp, flame.color.blue); |
| 205 | + } else { // coolest |
| 206 | + leds->setPixel(Pixel, heatramp, flame.color.green, flame.color.blue); |
| 207 | + } |
| 208 | + } |
| 209 | +} |
| 210 | + |
132 | 211 | bool action_t::run(WS2812* leds,int delay_ms)
|
133 | 212 | {
|
134 | 213 | bool done = false;
|
@@ -160,18 +239,8 @@ bool action_t::run(WS2812* leds,int delay_ms)
|
160 | 239 | break;
|
161 | 240 | case action_type_t::flame :
|
162 | 241 | {
|
163 |
| - // Flicker, based on our initial RGB values |
164 |
| - for(int i=0; i<g_nb_led; i++) |
165 |
| - { |
166 |
| - int flicker = rand() % flame.random; |
167 |
| - int r1 = flame.color.red-flicker; |
168 |
| - int g1 = flame.color.green-flicker; |
169 |
| - int b1 = flame.color.blue-flicker; |
170 |
| - if(g1<0) g1=0; |
171 |
| - if(r1<0) r1=0; |
172 |
| - if(b1<0) b1=0; |
173 |
| - leds->setPixel(i,r1,g1, b1); |
174 |
| - } |
| 242 | + //simple_fire(leds,flame); |
| 243 | + t4all_fire(leds,flame); |
175 | 244 | }
|
176 | 245 | break;
|
177 | 246 | default:
|
@@ -442,6 +511,7 @@ void led_test_flame(const char * payload,int len)
|
442 | 511 | flame.color.green = root["g"];
|
443 | 512 | flame.color.blue = root["b"];
|
444 | 513 | flame.random = root["random"];
|
| 514 | + flame.nb_leds = root["nb_leds"]; |
445 | 515 | animation.add_flame(flame,duration_ms);
|
446 | 516 | ESP_ERROR_CHECK(esp_timer_stop(periodic_timer));
|
447 | 517 | ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, period));
|
@@ -641,7 +711,7 @@ void app_main()
|
641 | 711 | {
|
642 | 712 | ESP_LOGI(TAG, "[APP] Startup..");
|
643 | 713 |
|
644 |
| - ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); |
| 714 | + ESP_LOGI(TAG, "[APP] Free memory: %d uint8_ts", esp_get_free_heap_size()); |
645 | 715 | ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
646 | 716 |
|
647 | 717 | esp_log_level_set("*", ESP_LOG_INFO);
|
|
0 commit comments