1 /* RMT example -- RGB LED Strip
2 
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4 
5    Unless required by applicable law or agreed to in writing, this
6    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7    CONDITIONS OF ANY KIND, either express or implied.
8 */
9 #include "sdkconfig.h"
10 #include "freertos/FreeRTOS.h"
11 #include "freertos/task.h"
12 #include "esp_log.h"
13 #include "driver/rmt.h"
14 #include "led_strip.h"
15 
16 static const char *TAG = "example";
17 
18 #define RMT_TX_CHANNEL RMT_CHANNEL_0
19 
20 #define EXAMPLE_CHASE_SPEED_MS (10)
21 
22 /**
23  * @brief Simple helper function, converting HSV color space to RGB color space
24  *
25  * Wiki: https://en.wikipedia.org/wiki/HSL_and_HSV
26  *
27  */
led_strip_hsv2rgb(uint32_t h,uint32_t s,uint32_t v,uint32_t * r,uint32_t * g,uint32_t * b)28 void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r, uint32_t *g, uint32_t *b)
29 {
30     h %= 360; // h -> [0,360]
31     uint32_t rgb_max = v * 2.55f;
32     uint32_t rgb_min = rgb_max * (100 - s) / 100.0f;
33 
34     uint32_t i = h / 60;
35     uint32_t diff = h % 60;
36 
37     // RGB adjustment amount by hue
38     uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60;
39 
40     switch (i) {
41     case 0:
42         *r = rgb_max;
43         *g = rgb_min + rgb_adj;
44         *b = rgb_min;
45         break;
46     case 1:
47         *r = rgb_max - rgb_adj;
48         *g = rgb_max;
49         *b = rgb_min;
50         break;
51     case 2:
52         *r = rgb_min;
53         *g = rgb_max;
54         *b = rgb_min + rgb_adj;
55         break;
56     case 3:
57         *r = rgb_min;
58         *g = rgb_max - rgb_adj;
59         *b = rgb_max;
60         break;
61     case 4:
62         *r = rgb_min + rgb_adj;
63         *g = rgb_min;
64         *b = rgb_max;
65         break;
66     default:
67         *r = rgb_max;
68         *g = rgb_min;
69         *b = rgb_max - rgb_adj;
70         break;
71     }
72 }
73 
app_main(void)74 void app_main(void)
75 {
76     uint32_t red = 0;
77     uint32_t green = 0;
78     uint32_t blue = 0;
79     uint16_t hue = 0;
80     uint16_t start_rgb = 0;
81 
82     rmt_config_t config = RMT_DEFAULT_CONFIG_TX(CONFIG_EXAMPLE_RMT_TX_GPIO, RMT_TX_CHANNEL);
83     // set counter clock to 40MHz
84     config.clk_div = 2;
85 
86     ESP_ERROR_CHECK(rmt_config(&config));
87     ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
88 
89     // install ws2812 driver
90     led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(CONFIG_EXAMPLE_STRIP_LED_NUMBER, (led_strip_dev_t)config.channel);
91     led_strip_t *strip = led_strip_new_rmt_ws2812(&strip_config);
92     if (!strip) {
93         ESP_LOGE(TAG, "install WS2812 driver failed");
94     }
95     // Clear LED strip (turn off all LEDs)
96     ESP_ERROR_CHECK(strip->clear(strip, 100));
97     // Show simple rainbow chasing pattern
98     ESP_LOGI(TAG, "LED Rainbow Chase Start");
99     while (true) {
100         for (int i = 0; i < 3; i++) {
101             for (int j = i; j < CONFIG_EXAMPLE_STRIP_LED_NUMBER; j += 3) {
102                 // Build RGB values
103                 hue = j * 360 / CONFIG_EXAMPLE_STRIP_LED_NUMBER + start_rgb;
104                 led_strip_hsv2rgb(hue, 100, 100, &red, &green, &blue);
105                 // Write RGB values to strip driver
106                 ESP_ERROR_CHECK(strip->set_pixel(strip, j, red, green, blue));
107             }
108             // Flush RGB values to LEDs
109             ESP_ERROR_CHECK(strip->refresh(strip, 100));
110             vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
111             strip->clear(strip, 50);
112             vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
113         }
114         start_rgb += 60;
115     }
116 }
117