/// The Yves ESP32_S3 I2S driver is a driver that uses the I2S peripheral on the ESP32-S3 to drive leds. /// Originally from: https://github.com/hpwit/I2SClockLessLedDriveresp32s3 /// /// This is an advanced driver. It has certain ramifications. /// - You probably aren't going to be able to use this in ArduinoIDE, because ArduinoIDE does not allow you to put in the necessary build flags. /// You will need to use PlatformIO to build this. /// - These flags enable PSRAM. /// - Once flashed, the ESP32-S3 might NOT want to be reprogrammed again. To get around /// this hold the reset button and release when the flash tool is looking for an /// an upload port. /// - Put a delay in the setup function. This is to make it easier to flash the device. /// - Serial output will mess up the DMA controller. I'm not sure why this is happening /// but just be aware of it. If your device suddenly stops works, remove the printfs and see if that fixes the problem. /// - You MUST use all the available PINS specified in this demo. Anything less than that will cause FastLED to crash. /// - Certain leds will turn white in debug mode. Probably has something to do with timing. /// /// Is RGBW supported? Yes. /// /// Is Overclocking supported? No. /// /// What about the new WS2812-5VB leds? Kinda. We put in a hack to add the extra wait time of 300 uS. /// /// What are the advantages of using the FastLED bindings over the raw driver? /// - FastLED api is more user friendly since you don't have to combine all your leds into one rectangular block. /// - FastLED api allows you to have different sized strips which will be upscaled to the largest strip internally. /// /// What are the advantages of using the raw driver over the FastLED bindings? /// - The raw driver uses less memory because it doesn't have a frame buffer copy. /// // PLATFORMIO BUILD FLAGS: // Define your platformio.ini like so: // // [env:esp32s3] // platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip // framework = arduino // board = seeed_xiao_esp32s3 // build_flags = // ${env:generic-esp.build_flags} // -DBOARD_HAS_PSRAM // -mfix-esp32-psram-cache-issue // -mfix-esp32-psram-cache-strategy=memw // board_build.partitions = huge_app.csv // // Then in your setup function you are going to want to call psramInit(); // // Want to get a contributor badge for FastLED? This driver has only been lightly tested. // There are certain open questions: // - Can the pins order for the strips be changed? (the pins can be defined arbitrarily,Tested on esp32s3, esp32duino version 3.2.0) // - Are there some combination of pins that can be ommitted? // - What other caveats are there? // // If you know the answer to these questions then please submit a PR to the FastLED repo and // we will update the information for the community. #include #define FASTLED_USES_ESP32S3_I2S #include "FastLED.h" #include "fl/assert.h" #define NUMSTRIPS 16 #define NUM_LEDS_PER_STRIP 256 #define NUM_LEDS (NUM_LEDS_PER_STRIP * NUMSTRIPS) #define EXAMPLE_PIN_NUM_DATA0 19 // B0 #define EXAMPLE_PIN_NUM_DATA1 45 // B1 #define EXAMPLE_PIN_NUM_DATA2 21 // B2 #define EXAMPLE_PIN_NUM_DATA3 6 // B3 #define EXAMPLE_PIN_NUM_DATA4 7 // B4 #define EXAMPLE_PIN_NUM_DATA5 8 // G0 #define EXAMPLE_PIN_NUM_DATA6 9 // G1 #define EXAMPLE_PIN_NUM_DATA7 10 // G2 #define EXAMPLE_PIN_NUM_DATA8 11 // G3 #define EXAMPLE_PIN_NUM_DATA9 12 // G4 #define EXAMPLE_PIN_NUM_DATA10 13 // G5 #define EXAMPLE_PIN_NUM_DATA11 14 // R0 #define EXAMPLE_PIN_NUM_DATA12 15 // R1 #define EXAMPLE_PIN_NUM_DATA13 16 // R2 #define EXAMPLE_PIN_NUM_DATA14 17 // R3 #define EXAMPLE_PIN_NUM_DATA15 18 // R4 const bool gUseFastLEDApi = true; // Set this to false to use the raw driver. int PINS[] = { EXAMPLE_PIN_NUM_DATA0, EXAMPLE_PIN_NUM_DATA1, EXAMPLE_PIN_NUM_DATA2, EXAMPLE_PIN_NUM_DATA3, EXAMPLE_PIN_NUM_DATA4, EXAMPLE_PIN_NUM_DATA5, EXAMPLE_PIN_NUM_DATA6, EXAMPLE_PIN_NUM_DATA7, EXAMPLE_PIN_NUM_DATA8, EXAMPLE_PIN_NUM_DATA9, EXAMPLE_PIN_NUM_DATA10, EXAMPLE_PIN_NUM_DATA11, EXAMPLE_PIN_NUM_DATA12, EXAMPLE_PIN_NUM_DATA13, EXAMPLE_PIN_NUM_DATA14, EXAMPLE_PIN_NUM_DATA15 }; fl::InternalI2SDriver *driver = nullptr; CRGB leds[NUM_LEDS]; void setup_i2s_using_fastled_api() { // Note, in this case we are using contingious memory for the leds. But this is not required. // Each strip can be a different size and the FastLED api will upscale the smaller strips to the largest strip. FastLED.addLeds( leds + (0 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (1 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (2 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (3 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (4 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (5 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (6 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (7 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (8 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (9 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (10 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (11 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (12 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (13 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (14 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.addLeds( leds + (15 * NUM_LEDS_PER_STRIP), NUM_LEDS_PER_STRIP ); FastLED.setBrightness(32); } void setup() { psramInit(); // IMPORTANT: This is required to enable PSRAM. If you don't do this, the driver will not work. // put your setup code here, to run once: Serial.begin(115200); // This is used so that you can see if PSRAM is enabled. If not, we will crash in setup() or in loop(). log_d("Total heap: %d", ESP.getHeapSize()); log_d("Free heap: %d", ESP.getFreeHeap()); log_d("Total PSRAM: %d", ESP.getPsramSize()); // If this prints out 0, then PSRAM is not enabled. log_d("Free PSRAM: %d", ESP.getFreePsram()); log_d("waiting 6 second before startup"); delay(6000); // The long reset time here is to make it easier to flash the device during the development process. if (gUseFastLEDApi) { setup_i2s_using_fastled_api(); } else { driver = fl::InternalI2SDriver::create(); driver->initled((uint8_t *)leds, PINS, NUMSTRIPS, NUM_LEDS_PER_STRIP); // Skips extra frame buffer copy. driver->setBrightness(32); } } void fill_rainbow(CRGB* all_leds) { static int s_offset = 0; for (int j = 0; j < NUMSTRIPS; j++) { for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) { int idx = (i + s_offset) % NUM_LEDS_PER_STRIP + NUM_LEDS_PER_STRIP * j; all_leds[idx] = CHSV(i, 255, 255); } } s_offset++; } void loop() { fill_rainbow(leds); if (gUseFastLEDApi) { FastLED.show(); } else { FASTLED_ASSERT(driver != nullptr, "Did not expect driver to be null"); driver->show(); } }