/** * @file es2812_rainbow.c * @author Ondřej Hruška, 2016 * * @brief Example of a rainbow effect with * WS2812 connected to GPIO2. * * This demo is in the public domain. */ #include "espressif/esp_common.h" #include "FreeRTOS.h" #include "task.h" #include "esp/uart.h" // uart_set_baud #include // printf #include #include "ws2812.h" #define delay_ms(ms) vTaskDelay((ms) / portTICK_RATE_MS) /** GPIO number used to control the RGBs */ static const uint8_t pin = 2; /** * @brief "rainbow" animation with a single RGB led. */ void demo_single(void) { // duration between color changes const uint8_t delay = 25; ws2812_rgb_t x = {.num = 0xFF0000}; // RED color while (1) { // iterate through the spectrum // note: This would be _WAY_ easier with HSL while(x.c.g < 0xFF) { x.c.g++; ws2812_set(pin, x.num); delay_ms(delay); } // R->RG while(x.c.r > 0x00) { x.c.r--; ws2812_set(pin, x.num); delay_ms(delay); } // RG->G while(x.c.b < 0xFF) { x.c.b++; ws2812_set(pin, x.num); delay_ms(delay); } // G->GB while(x.c.g > 0x00) { x.c.g--; ws2812_set(pin, x.num); delay_ms(delay); } // GB->B while(x.c.r < 0xFF) { x.c.r++; ws2812_set(pin, x.num); delay_ms(delay); } // B->BR while(x.c.b > 0x00) { x.c.b--; ws2812_set(pin, x.num); delay_ms(delay); } // BR->R } } /** * @brief "rainbow" effect on a RGB strip (30 pixels - can be adjusted) * * This example shows how to use the "procedural generation" of colors. * * The pixel colors are calculated on the fly, which saves RAM * (especially with large displays). */ void demo_strip(void *pvParameters) { const uint8_t anim_step = 10; const uint8_t anim_max = 250; // Number of your "pixels" const uint8_t pixel_count = 30; // duration between color changes const uint8_t delay = 25; ws2812_rgb_t color = WS2812_RGB(anim_max, 0, 0); uint8_t step = 0; ws2812_rgb_t color2 = WS2812_RGB(anim_max, 0, 0); uint8_t step2 = 0; while (1) { color = color2; step = step2; // Start a data sequence (disables interrupts) ws2812_seq_start(); for (uint8_t i = 0; i < pixel_count; i++) { // send a color ws2812_seq_rgb(pin, color.num); // now we have a few hundred nanoseconds // to calculate the next color if (i == 1) { color2 = color; step2 = step; } switch (step) { case 0: color.c.g += anim_step; if (color.c.g >= anim_max) step++; break; case 1: color.c.r -= anim_step; if (color.c.r == 0) step++; break; case 2: color.c.b += anim_step; if (color.c.b >= anim_max) step++; break; case 3: color.c.g -= anim_step; if (color.c.g == 0) step++; break; case 4: color.c.r += anim_step; if (color.c.r >= anim_max) step++; break; case 5: color.c.b -= anim_step; if (color.c.b == 0) step = 0; break; } } // End the data sequence, display colors (interrupts are restored) ws2812_seq_end(); // wait a bit delay_ms(delay); } } void user_init(void) { uart_set_baud(0, 115200); printf("--- RGB Rainbow demo ---"); // Configure the GPIO gpio_enable(pin, GPIO_OUTPUT); // Select a demo function: #if true # define demo demo_strip #else # define demo demo_single #endif // Choose how to run it: #if true // Blocking function - works OK, because WiFi isn't // initialized yet & we're hogging the CPU. printf("Starting a blocking function.\r\n"); demo(NULL); #else // Start a task. This is a real-life example, // notice the glitches due to NMI. printf("Starting a task. There may be glitches!\r\n"); xTaskCreate(&demo, (signed char *)"strip demo", 256, NULL, 10, NULL); #endif }