FastLED 3.9.15
Loading...
Searching...
No Matches
FxSdCard.ino
Go to the documentation of this file.
1// @filter: (memory is large)
2
24
25#include "FastLED.h"
26#include "Arduino.h"
27
29// #include "fl/fx/2d/animartrix.hpp"
30#include "fl/fx/fx_engine.h"
31#include "fl/fx/video.h"
33#include "fl/ui/ui.h"
34#include "fl/math/screenmap.h"
36
37
38
39
40#define LED_PIN 2
41#define LED_TYPE WS2811
42#define COLOR_ORDER GRB
43#define FPS 60
44#define CHIP_SELECT_PIN 5
45
46
47
48#define MATRIX_WIDTH 32
49#define MATRIX_HEIGHT 32
50#define NUM_VIDEO_FRAMES 2 // enables interpolation with > 1 frame.
51
52
53#define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT)
54#define IS_SERPINTINE true
55
56
57fl::UITitle title("SDCard Demo - Mapped fl::Video");
58fl::UIDescription description("fl::Video data is streamed off of a SD card and displayed on a LED strip. The video data is mapped to the LED strip using a fl::ScreenMap embedded in the FLED file (with a sidecar screenmap.json fallback for legacy .rgb files).");
59
60
63
67
68fl::UISlider videoSpeed("fl::Video Speed", 1.0f, -1, 2.0f, 0.01f);
69UINumberField whichVideo("Which fl::Video", 0, 0, 1);
70
71
72bool gError = false;
73
74// Open `<base>.fled` if present, otherwise fall back to `<base>.rgb`.
75// Returns the resolved Video; sets gError + warns on hard failure.
76//
77// The screenMap-out param is populated from EITHER the FLED file's
78// embedded JSON OR a sidecar screenmap.json — whichever is available.
79// On legacy .rgb the caller's `sidecarScreenmapPath` is loaded; for FLED
80// the embedded JSON wins and the sidecar path is ignored.
81// Reject any ScreenMap whose LED count disagrees with NUM_LEDS. A silent
82// mismatch corrupts the mapping in addLeds().setScreenMap() — there is no
83// runtime fix once frames start flowing, so fail loud at setup time.
84static bool validateScreenMapSize(const fl::ScreenMap &m, const char *source) {
85 if (m.getLength() != NUM_LEDS) {
86 FL_WARN("Screenmap from " << source << " has "
87 << m.getLength() << " LEDs but NUM_LEDS=" << NUM_LEDS
88 << " — mapping would silently corrupt playback.");
89 gError = true;
90 return false;
91 }
92 return true;
93}
94
95fl::Video openVideoEitherFormat(const char *fledPath,
96 const char *rgbPath,
97 const char *sidecarScreenmapPath,
98 fl::ScreenMap *outScreenMap) {
99 // Try FLED first.
100 fl::Video v = filesystem.openVideo(fledPath, NUM_LEDS, FPS, NUM_VIDEO_FRAMES);
101 if (v && v.hasEmbeddedScreenMap()) {
102 const fl::string &json = v.embeddedScreenMapJson();
103 fl::string parseErr;
104 if (!fl::ScreenMap::ParseJson(json.c_str(), "strip1", outScreenMap, &parseErr)) {
105 FL_WARN("FLED embedded screenmap parse failed: " << parseErr.c_str());
106 gError = true;
107 return v;
108 }
109 validateScreenMapSize(*outScreenMap, fledPath);
110 return v;
111 }
112 // No .fled (or it lacks an embedded map). Fall back to legacy .rgb.
113 fl::Video legacy = filesystem.openVideo(rgbPath, NUM_LEDS, FPS, NUM_VIDEO_FRAMES);
114 if (!legacy) {
115 FL_WARN("Failed to open " << rgbPath << " (and no " << fledPath << " either)");
116 gError = true;
117 return legacy;
118 }
119 if (!filesystem.readScreenMap(sidecarScreenmapPath, "strip1", outScreenMap)) {
120 FL_WARN("Failed to read sidecar " << sidecarScreenmapPath);
121 gError = true;
122 return legacy;
123 }
124 validateScreenMapSize(*outScreenMap, sidecarScreenmapPath);
125 return legacy;
126}
127
128void setup() {
129 Serial.begin(115200);
130 Serial.println("Sketch setup");
131 // Initialize the file system and check for errors
132 if (!filesystem.beginSd(CHIP_SELECT_PIN)) {
133 Serial.println("Failed to initialize file system.");
134 }
135
136 // Open both videos. FLED first (carries its own ScreenMap), legacy
137 // .rgb + sidecar screenmap.json as fallback. Both videos use the same
138 // physical map, so the second screenMap parse is harmless overwrite.
140 "data/video.fled", "data/video.rgb",
141 "data/screenmap.json", &screenMap);
142 if (gError) return;
143
145 "data/color_line_bubbles.fled", "data/color_line_bubbles.rgb",
146 "data/screenmap.json", &screenMap);
147 if (gError) return;
148
149 // Configure FastLED with the LED type, pin, and color order
151 .setCorrection(TypicalLEDStrip)
152 .setScreenMap(screenMap);
153 FastLED.setBrightness(96);
154 Serial.println("FastLED setup done");
155}
156
157void loop() {
158 static bool s_first = true;
159 if (s_first) {
160 s_first = false;
161 Serial.println("First loop.");
162 }
163 if (gError) {
164 // If an error occurred, print a warning every second
165 EVERY_N_SECONDS(1) {
166 FL_WARN("No loop because an error occured.");
167 }
168 return;
169 }
170
171 // Select the video to play based on the UI input
172 fl::Video& vid = !bool(whichVideo.value()) ? video : video2;
174
175 // Get the current time and draw the video frame
176 uint32_t now = fl::millis();
177 vid.draw(now, leds);
178 FastLED.show();
179}
#define COLOR_ORDER
#define NUM_LEDS
fl::CRGB leds[NUM_LEDS]
#define LED_PIN
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
fl::Video video(NUM_LEDS, 2.0f)
fl::Video openVideoEitherFormat(const char *fledPath, const char *rgbPath, const char *sidecarScreenmapPath, fl::ScreenMap *outScreenMap)
Definition FxSdCard.ino:95
void setup()
Definition FxSdCard.ino:128
fl::FileSystem filesystem
Definition FxSdCard.ino:64
#define NUM_VIDEO_FRAMES
Definition FxSdCard.ino:50
fl::UITitle title("SDCard Demo - Mapped fl::Video")
bool gError
Definition FxSdCard.ino:72
fl::UISlider videoSpeed("fl::Video Speed", 1.0f, -1, 2.0f, 0.01f)
static bool validateScreenMapSize(const fl::ScreenMap &m, const char *source)
Definition FxSdCard.ino:84
fl::UIDescription description("fl::Video data is streamed off of a SD card and displayed on a LED strip. The video data is mapped to the LED strip using a fl::ScreenMap embedded in the FLED file (with a sidecar screenmap.json fallback for legacy .rgb files).")
#define CHIP_SELECT_PIN
Definition FxSdCard.ino:44
#define FPS
Definition FxSdCard.ino:43
UINumberField whichVideo("Which fl::Video", 0, 0, 1)
fl::Video video2
Definition FxSdCard.ino:66
void loop()
Definition FxSdCard.ino:157
#define LED_TYPE
u32 getLength() const FL_NOEXCEPT
static bool ParseJson(const char *jsonStrScreenMap, fl::flat_map< string, ScreenMap > *segmentMaps, string *err=nullptr) FL_NOEXCEPT
void draw(DrawContext context) override
Definition video.cpp.hpp:71
void setTimeScale(float timeScale)
bool hasEmbeddedScreenMap() const FL_NOEXCEPT
const fl::string & embeddedScreenMapJson() const FL_NOEXCEPT
const char * c_str() const FL_NOEXCEPT
fl::ScreenMap screenMap
Definition Corkscrew.h:101
@ TypicalLEDStrip
Typical values for SMD5050 LEDs.
Definition color.h:15
#define EVERY_N_SECONDS(N)
Checks whether to execute a block of code every N seconds.
Definition lib8tion.h:1010
#define FL_WARN(X)
Definition log.h:276
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
Demonstrates how to mix noise generation with color palettes on a 2D LED matrix.
Representation of an 8-bit RGB pixel (Red, Green, Blue)
Definition crgb.h:38
#define Serial
Definition serial.h:304
Aggregator header for the fl/ui/ family of per-element UI types.