板载WS2812
板载1颗WS2812连接IO21
软件下载
- ESP32-S3-Zero没有板载USB转串口,无法实现自动下载。
- 下载软件时要按住Boot按键再上电,此时电脑会识别到一个USB模拟的COM口,可用于下载软件。
开发环境
编程环境是使用的esp-idf-4.4.2;
安装esp-idf-5.0.2、esp-idf-5.1.2都不能正常使用。
参考教程
https://www.bilibili.com/video/BV1jC4y1W7CZ/?vd_source=916baa0bb6d7382ed550867f84a7d155
参考例程
参考例程是"led_strip"
例程存储路径"ESP-IDF\Espressif\frameworks\esp-idf-v4.4.2\examples\peripherals\rmt\led_strip"
代码
/* USB Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
// DESCRIPTION:
// This example contains minimal code to make ESP32-S2 based device
// recognizable by USB-host devices as a USB Serial Device printing output from
// the application.
#include <stdio.h>
#include <stdlib.h>
#include <sys/reent.h>
#include "esp_log.h"
#include "esp_vfs.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "tinyusb.h"
#include "tusb_cdc_acm.h"
#include "tusb_console.h"
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_log.h"
#include "driver/rmt.h"
#include "led_strip.h"
static const char *TAG = "Main";
static const char *HelloTAG = "Hello";
static const char *WS2812TAG = "WS2812";
#define RMT_TX_CHANNEL RMT_CHANNEL_0
#define EXAMPLE_CHASE_SPEED_MS (10)
#define MY_CONFIG_EXAMPLE_RMT_TX_GPIO (21)
#define MY_CONFIG_EXAMPLE_STRIP_LED_NUMBER (1)
/**
* @brief Simple helper function, converting HSV color space to RGB color space
*
* Wiki: https://en.wikipedia.org/wiki/HSL_and_HSV
*
*/
void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r, uint32_t *g, uint32_t *b)
{
h %= 360; // h -> [0,360]
uint32_t rgb_max = v * 2.55f;
uint32_t rgb_min = rgb_max * (100 - s) / 100.0f;
uint32_t i = h / 60;
uint32_t diff = h % 60;
// RGB adjustment amount by hue
uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60;
switch (i) {
case 0:
*r = rgb_max;
*g = rgb_min + rgb_adj;
*b = rgb_min;
break;
case 1:
*r = rgb_max - rgb_adj;
*g = rgb_max;
*b = rgb_min;
break;
case 2:
*r = rgb_min;
*g = rgb_max;
*b = rgb_min + rgb_adj;
break;
case 3:
*r = rgb_min;
*g = rgb_max - rgb_adj;
*b = rgb_max;
break;
case 4:
*r = rgb_min + rgb_adj;
*g = rgb_min;
*b = rgb_max;
break;
default:
*r = rgb_max;
*g = rgb_min;
*b = rgb_max - rgb_adj;
break;
}
}
static void ws2812_task(void *arg)
{
uint32_t red = 0;
uint32_t green = 0;
uint32_t blue = 0;
uint16_t hue = 0;
uint16_t start_rgb = 0;
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(MY_CONFIG_EXAMPLE_RMT_TX_GPIO, RMT_TX_CHANNEL);
// set counter clock to 40MHz
config.clk_div = 2;
ESP_ERROR_CHECK(rmt_config(&config));
ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
// install ws2812 driver
led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(MY_CONFIG_EXAMPLE_STRIP_LED_NUMBER, (led_strip_dev_t)config.channel);
led_strip_t *strip = led_strip_new_rmt_ws2812(&strip_config);
if (!strip) {
ESP_LOGE(WS2812TAG, "install WS2812 driver failed");
}
// Clear LED strip (turn off all LEDs)
ESP_ERROR_CHECK(strip->clear(strip, 100));
// Show simple rainbow chasing pattern
ESP_LOGI(WS2812TAG, "LED Rainbow Chase Start");
while (true) {
for (int i = 0; i < 3; i++) {
for (int j = i; j < MY_CONFIG_EXAMPLE_STRIP_LED_NUMBER; j += 3) {
// Build RGB values
hue = j * 360 / MY_CONFIG_EXAMPLE_STRIP_LED_NUMBER + start_rgb;
led_strip_hsv2rgb(hue, 100, 30, &red, &green, &blue);/*param1:色调;param2:饱和度;param3:明度;*/
// Write RGB values to strip driver
ESP_ERROR_CHECK(strip->set_pixel(strip, j, red, green, blue));
}
// Flush RGB values to LEDs
ESP_ERROR_CHECK(strip->refresh(strip, 100));
vTaskDelay(200 / portTICK_PERIOD_MS);
//vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
strip->clear(strip, 50);
vTaskDelay(200 / portTICK_PERIOD_MS);
//vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
}
start_rgb += 20;
}
}
static void hello_task(void *arg)
{
static int cnt = 0;
ESP_LOGI(HelloTAG, "Enter hello task.");
while (1) {
if(cnt % 2){
ESP_LOGI(HelloTAG, "Odd num : %d.",cnt);
}
else{
ESP_LOGI(HelloTAG, "Even num : %d.",cnt);
}
if(cnt >= 0xFFFFFFFF){
cnt = 0;
}
else{
cnt++;
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
/* Setting TinyUSB up */
tinyusb_config_t tusb_cfg = { 0 }; // the configuration uses default values
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
tinyusb_config_cdcacm_t amc_cfg = { 0 }; // the configuration uses default values
ESP_ERROR_CHECK(tusb_cdc_acm_init(&amc_cfg));
esp_tusb_init_console(TINYUSB_CDC_ACM_0); // log to usb
vTaskDelay(2000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "APP Version 1.00");
ESP_LOGI(TAG, "USB initialization DONE");
xTaskCreatePinnedToCore(hello_task, "stats", 4096, NULL, 3, NULL, tskNO_AFFINITY);/*启动hello_task*/
xTaskCreatePinnedToCore(ws2812_task, "stats", 4096, NULL, 3, NULL, tskNO_AFFINITY);/*启动ws2812_task*/
while (1) {
ESP_LOGI(TAG, "log -> USB");
vTaskDelay(1000 / portTICK_PERIOD_MS);
fprintf(stdout, "example: print -> stdout\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
fprintf(stderr, "example: print -> stderr\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
编译错误
- 找不到头文件led_strip.h,文件路径"ESP-IDF\Espressif\frameworks\esp-idf-v4.4.2\components\tinyusb\tinyusb\hw\bsp\esp32s3\components\led_strip\include",将该路径下的led_strip.h文件复制到新工程main文件夹下
- 未定义的led_strip_new_rmt_ws2812,找不到这个函数的定义,经查找该函数定义在led_strip_rmt_ws2812.c中,该文件路径"E:\Setup\ESP-IDF\Espressif\frameworks\esp-idf-v4.4.2\components\tinyusb\tinyusb\hw\bsp\esp32s3\components\led_strip\src",将该路径下的led_strip_rmt_ws2812.c文件复制到新工程main文件夹下,修改main文件夹下的CMakeLists.txt添加led_strip_rmt_ws2812.c
现象
-
软件下载完毕后,按下reset按键,电脑会重新识别USB模拟的串口,因此串口号可能会改变;
-
连接串口后,可以看到相应的打印信息;
-
RGB彩灯闪烁;