diff --git a/firmware/include/app.h b/firmware/include/app.h index cf2353a..b73b3c8 100644 --- a/firmware/include/app.h +++ b/firmware/include/app.h @@ -22,4 +22,10 @@ struct FFTTestApp: public App { void init(); void deinit(); void loop(); +}; + +struct FackelApp: public App { + void init(); + void deinit(); + void loop(); }; \ No newline at end of file diff --git a/firmware/src/applications/fackel.cpp b/firmware/src/applications/fackel.cpp new file mode 100644 index 0000000..e852760 --- /dev/null +++ b/firmware/src/applications/fackel.cpp @@ -0,0 +1,146 @@ +#include "app.h" +#include "pt1.h" +#include "zauberstab.h" +#include + +static unsigned long last_sample_time; +static unsigned long sample_counter; +static float rms_avg; + +static uint8_t energy[NUM_LEDS]; +static uint8_t spark_energy[NUM_LEDS]; + +Pt1 energy_pt1{1.f, 1.f}; +CRGB palette[128]; + +static void hsl_to_rgb(uint32_t hue, uint32_t sat, uint32_t lum, uint8_t *r, uint8_t *g, uint8_t *b) +{ + uint32_t v; + + v = (lum < 128) ? (lum * (256 + sat)) >> 8 : (((lum + sat) << 8) - lum * sat) >> 8; + + if (v <= 0) + { + *r = *g = *b = 0; + } + else + { + int32_t m; + int32_t sextant; + int32_t fract, vsf, mid1, mid2; + + m = lum + lum - v; + hue *= 6; + sextant = hue >> 8; + fract = hue - (sextant << 8); + vsf = v * fract * (v - m) / v >> 8; + mid1 = m + vsf; + mid2 = v - vsf; + switch (sextant) + { + case 0: + *r = v; + *g = mid1; + *b = m; + break; + case 1: + *r = mid2; + *g = v; + *b = m; + break; + case 2: + *r = m; + *g = v; + *b = mid1; + break; + case 3: + *r = m; + *g = mid2; + *b = v; + break; + case 4: + *r = mid1; + *g = m; + *b = v; + break; + case 5: + *r = v; + *g = m; + *b = mid2; + break; + } + } +} + +static void update_engery(uint8_t *energy, size_t s) +{ + for (int i = s; i >= 2; i--) + { + energy[i] = (uint8_t)((float)(energy[i - 1] + energy[i - 2]) * 0.485f); + } +} + +void FackelApp::init() +{ + memset(&energy, 0, NUM_LEDS); + memset(&spark_energy, 0, NUM_LEDS); + + // generate palette + for (int i = 0; i < 128; i++) + { + uint8_t r, g, b; + hsl_to_rgb(i / 5, 255, i * 2 > 128 ? 128 : i * 2, &r, &g, &b); + g = g == 1 ? 0 : g; + b = b == 1 ? 0 : b; + palette[i].r = r; + palette[i].g = g; + palette[i].b = b; + } +} + +void FackelApp::deinit() +{ +} + +void FackelApp::loop() +{ + if (micros() - last_sample_time >= 500) + { + last_sample_time = micros(); + int32_t sample = get_sample(); + float in = sample * sample; + sample_counter++; + rms_avg += (in - rms_avg) / (sample_counter + 1); + } + + EVERY_N_MILLISECONDS(10) + { + float e_f = energy_pt1.update(rms_avg, 0.01f); + + if (rms_avg > 1.15 * e_f) + { + energy[0] = 128; + energy[1] = 128; + } + else + { + energy[0] = 50; + energy[1] = 50; + } + + rms_avg = 0.0f; + sample_counter = 0; + } + + EVERY_N_MILLISECONDS(45) + { + update_engery(energy, NUM_LEDS); + + for (int i = 0; i < NUM_LEDS; i++) + { + leds[i] = palette[energy[i]]; + } + + FastLED.show(); + } +} \ No newline at end of file diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index ed6e54d..e6fa42d 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -1,18 +1,28 @@ +#include "app.h" +#include "driver/adc.h" #include "zauberstab.h" #include -#include "app.h" -struct BeatDetectApp beat_detect_app{}; -struct VuMeterApp vu_meter_app {}; -struct FFTTestApp fft_test_app {}; +struct BeatDetectApp beat_detect_app +{ +}; +struct VuMeterApp vu_meter_app +{ +}; +struct FFTTestApp fft_test_app +{ +}; +struct FackelApp fackel_app +{ +}; std::vector> apps = { std::ref(beat_detect_app), std::ref(vu_meter_app), std::ref(fft_test_app), -}; + std::ref(fackel_app)}; -unsigned int current_app = 0; +unsigned int current_app = 3; unsigned int next_app; void setup() @@ -26,7 +36,14 @@ void setup() void loop() { - if (next_app != current_app) { +/* EVERY_N_SECONDS(30) + { + next_app++; + next_app = next_app % apps.size(); + } */ + + if (next_app != current_app) + { apps[current_app].get().deinit(); apps[next_app].get().init(); current_app = next_app;