1735|1

3

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

得捷电子 Follow me 第2期任务提交汇总 全程esp-idf实现方案 [复制链接]

 

视频:https://training.eeworld.com.cn/video/38569

 

大家好,这里是日历,我参与了EEWORLD的“跟着我一起做”活动,采用了espidf方案进行全程开发。在这个项目中,我选择使用了Adafruit ESP32-S3 TFT Feather板,它搭载了强大的ESP32-S3控制器,并提供丰富的外设接口,包括液晶屏、WS2812B RGB灯珠以及i2c接口。
活动内容涉及多个领域,主要包括屏幕显示、网络通信、音乐播放、数据检测与记录等。通过这次活动,我深入学习了espidf的开发方式,同时掌握了在Adafruit ESP32-S3 TFT Feather板上使用不同外设的方法。

 

总算是板子9底月到货了然后我成功的拖更了一整个月(doge),这块Adafruit ESP32-S3 TFT Feather的常规写法各位的方案我看大多是CircuitPython 或者少数arduino的,但是笔者习惯了使用esp-idf方案写esp32的板子的程序的原因,这块板子也稍微扒拉了下引脚配置然后用espidf+lvgl方案完成这块板子的程序
首先说回来最麻烦的屏幕配置部分

MOSI 35

CLK 36

CS 7

DC 39

RESET 40

BLK 45
lvgl的移植部分各位可以直接使用esp官方的组件库的lvgl移植内容,但是在lvgl_esp32_drivers这个依赖的st7789.c的内容我根据arduino那边的对这块屏幕的配置更改了下具体如下
 

  • /**
  • * [url=home.php?mod=space&uid=1307177]@File[/url] st7789.c
  • *
  • * Mostly taken from lbthomsen/esp-idf-littlevgl github.
  • */
  • #include "freertos/FreeRTOS.h"
  • #include "freertos/task.h"
  • #include "sdkconfig.h"
  • #include "esp_log.h"
  • #include "st7789.h"
  • #include "disp_spi.h"
  • #include "driver/gpio.h"
  • /*********************
  • * DEFINES
  • *********************/
  • #define TAG "st7789"
  • /**********************
  • * TYPEDEFS
  • **********************/
  • /*The LCD needs a bunch of command/argument values to be initialized. They are stored in this struct. */
  • typedef struct {
  • uint8_t cmd;
  • uint8_t data[16];
  • uint8_t databytes; //No of data in data; bit 7 = delay after set; 0xFF = end of cmds.
  • } lcd_init_cmd_t;
  • /**********************
  • * STATIC PROTOTYPES
  • **********************/
  • static void st7789_set_orientation(uint8_t orientation);
  • static void st7789_send_color(void *data, size_t length);
  • /**********************
  • * STATIC VARIABLES
  • **********************/
  • /**********************
  • * MACROS
  • **********************/
  • /**********************
  • * GLOBAL FUNCTIONS
  • **********************/
  • void st7789_init(void)
  • {
  • lcd_init_cmd_t st7789_init_cmds[] = {
  • {ST7789_SWRESET, {0}, 0x80}, // Software reset
  • {ST7789_SLPOUT, {0}, 0x80}, // Out of sleep mode
  • {ST7789_COLMOD, {0x55}, 1}, // Set color mode
  • {ST7789_MADCTL, {0x00}, 1}, // Memory access control
  • {ST7789_CASET, {0x00, 0x00, 0x00, 0xEF}, 4}, // Column address set
  • {ST7789_RASET, {0x00, 0x00, 0x01, 0x3F}, 4}, // Row address set
  • {ST7789_INVON, {0}, 0}, // Hack - possibly inverted mode
  • {ST7789_NORON, {0}, 0x80}, // Normal display on
  • {ST7789_DISPON, {0}, 0x80}, // Main screen turn on
  • {0, {0}, 0xFF} // End marker
  • };
  • //Initialize non-SPI GPIOs
  • gpio_reset_pin(ST7789_DC);//esp-idf v5.0和v4.3有差异
  • gpio_set_direction(ST7789_DC, GPIO_MODE_OUTPUT);
  • #if !defined(ST7789_SOFT_RST)
  • esp_rom_gpio_pad_select_gpio(ST7789_RST);
  • gpio_set_direction(ST7789_RST, GPIO_MODE_OUTPUT);
  • #endif
  • //Reset the display
  • #if !defined(ST7789_SOFT_RST)
  • gpio_set_level(ST7789_RST, 0);
  • vTaskDelay(100 / portTICK_PERIOD_MS);
  • gpio_set_level(ST7789_RST, 1);
  • vTaskDelay(100 / portTICK_PERIOD_MS);
  • #else
  • st7789_send_cmd(ST7789_SWRESET);
  • #endif
  • printf("ST7789 initialization.\n");
  • //Send all the commands
  • uint16_t cmd = 0;
  • while (st7789_init_cmds[cmd].databytes!=0xff) {
  • st7789_send_cmd(st7789_init_cmds[cmd].cmd);
  • st7789_send_data(st7789_init_cmds[cmd].data, st7789_init_cmds[cmd].databytes&0x1F);
  • if (st7789_init_cmds[cmd].databytes & 0x80) {
  • vTaskDelay(100 / portTICK_PERIOD_MS);
  • }
  • cmd++;
  • }
  • st7789_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
  • }
  • /* The ST7789 display controller can drive up to 320*240 displays, when using a 240*240 or 240*135
  • * displays there's a gap of 80px or 40/52/53px respectively. 52px or 53x offset depends on display orientation.
  • * We need to edit the coordinates to take into account those gaps, this is not necessary in all orientations. */
  • void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
  • {
  • uint8_t data[4] = {0};
  • uint16_t offsetx1 = area->x1;
  • uint16_t offsetx2 = area->x2;
  • uint16_t offsety1 = area->y1;
  • uint16_t offsety2 = area->y2;
  • offsetx1 += 40;
  • offsetx2 += 40;
  • offsety1 += 53;
  • offsety2 += 53;
  • /*Column addresses*/
  • st7789_send_cmd(ST7789_CASET);
  • data[0] = (offsetx1 >> 8) & 0xFF;
  • data[1] = offsetx1 & 0xFF;
  • data[2] = (offsetx2 >> 8) & 0xFF;
  • data[3] = offsetx2 & 0xFF;
  • st7789_send_data(data, 4);
  • /*Page addresses*/
  • st7789_send_cmd(ST7789_RASET);
  • data[0] = (offsety1 >> 8) & 0xFF;
  • data[1] = offsety1 & 0xFF;
  • data[2] = (offsety2 >> 8) & 0xFF;
  • data[3] = offsety2 & 0xFF;
  • st7789_send_data(data, 4);
  • /*Memory write*/
  • st7789_send_cmd(ST7789_RAMWR);
  • size_t size = (size_t)lv_area_get_width(area) * (size_t)lv_area_get_height(area);
  • st7789_send_color((void*)color_map, size * 2);
  • }
  • /**********************
  • * STATIC FUNCTIONS
  • **********************/
  • void st7789_send_cmd(uint8_t cmd)
  • {
  • disp_wait_for_pending_transactions();
  • gpio_set_level(ST7789_DC, 0);
  • disp_spi_send_data(&cmd, 1);
  • }
  • void st7789_send_data(void * data, uint16_t length)
  • {
  • disp_wait_for_pending_transactions();
  • gpio_set_level(ST7789_DC, 1);
  • disp_spi_send_data(data, length);
  • }
  • static void st7789_send_color(void * data, size_t length)
  • {
  • disp_wait_for_pending_transactions();
  • gpio_set_level(ST7789_DC, 1);
  • disp_spi_send_colors(data, length);
  • }
  • #define ST77XX_MADCTL_MY 0x80
  • #define ST77XX_MADCTL_MX 0x40
  • #define ST77XX_MADCTL_MV 0x20
  • #define ST77XX_MADCTL_ML 0x10
  • #define ST77XX_MADCTL_RGB 0x00
  • static void st7789_set_orientation(uint8_t orientation)
  • {
  • uint8_t madctl = 0;
  • ESP_LOGI(TAG, "0x36 command value: 0x%02X", madctl);
  • madctl = ST77XX_MADCTL_MX | ST77XX_MADCTL_MV | ST77XX_MADCTL_RGB;
  • st7789_send_cmd(ST7789_MADCTL);
  • st7789_send_data((void *)&madctl, 1);
  • }

特别注意的是屏幕的分辨率水平240,垂直135已经配置过,如果颜色出现了问题,请查看下lvgl的有一个CONFIG_LV_COLOR_16_SWAP的配置
 在配置完屏幕驱动项后理应就能正常内容,这个时候就可以开始完成
任务一、控制屏幕显示中文(必做任务)

首先使用lvgl构建页面内容,笔者是使用了gui guider构建配置,相关的移植gui guider方法请各位自行查找或者看下我的程序
特别提醒中文显示的话需要去lvgl字体转换网站Online font converter - TTF or WOFF fonts to C array | LVGL
把你需要转的中文字体导入并且选定要转换的文本,最终结果输出为一个 .c文件保存
此次笔者使用了一个网上找的字体和guiguider默认案例音乐播放器显示完成的第一个任务
rt
 

 

任务二、网络功能使用(必做任务)

这个任务二其实就很简单

ap是构建热点,sta是作为子设备

那么直接照抄官方的程序就可以了

这个地方po出笔者的程序

sta模式:

  • #include <string.h>
  • #include "freertos/FreeRTOS.h"
  • #include "freertos/task.h"
  • #include "freertos/event_groups.h"
  • #include "esp_system.h"
  • #include "esp_wifi.h"
  • #include "esp_event.h"
  • #include "esp_log.h"
  • #include "nvs_flash.h"
  • #include "lwip/err.h"
  • #include "lwip/sys.h"
  • #include "main.h"
  • static const char *TAG = "wifi station";
  • #define EXAMPLE_ESP_WIFI_SSID "TP-LINK_CC60"
  • #define EXAMPLE_ESP_WIFI_PASS "stc15f104w"
  • #define EXAMPLE_ESP_MAXIMUM_RETRY 5
  • #define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
  • /* FreeRTOS event group to signal when we are connected*/
  • static EventGroupHandle_t s_wifi_event_group;
  • /* The event group allows multiple bits for each event, but we only care about two events:
  • * - we are connected to the AP with an IP
  • * - we failed to connect after the maximum amount of retries */
  • #define WIFI_CONNECTED_BIT BIT0
  • #define WIFI_FAIL_BIT BIT1
  • static int s_retry_num = 0;
  • static void event_handler(void* arg, esp_event_base_t event_base,
  • int32_t event_id, void* event_data)
  • {
  • if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
  • esp_wifi_connect();
  • } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
  • if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
  • esp_wifi_connect();
  • s_retry_num++;
  • ESP_LOGI(TAG, "retry to connect to the AP");
  • } else {
  • xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
  • }
  • ESP_LOGI(TAG,"connect to the AP fail");
  • } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
  • ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
  • ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
  • s_retry_num = 0;
  • xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
  • }
  • }
  • void wifi_init_sta(void)
  • {
  • esp_err_t ret = nvs_flash_init();
  • if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  • ESP_ERROR_CHECK(nvs_flash_erase());
  • ret = nvs_flash_init();
  • }
  • ESP_ERROR_CHECK(ret);
  • ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
  • s_wifi_event_group = xEventGroupCreate();
  • ESP_ERROR_CHECK(esp_netif_init());
  • ESP_ERROR_CHECK(esp_event_loop_create_default());
  • esp_netif_create_default_wifi_sta();
  • wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  • ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  • esp_event_handler_instance_t instance_any_id;
  • esp_event_handler_instance_t instance_got_ip;
  • ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
  • ESP_EVENT_ANY_ID,
  • &event_handler,
  • NULL,
  • &instance_any_id));
  • ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
  • IP_EVENT_STA_GOT_IP,
  • &event_handler,
  • NULL,
  • &instance_got_ip));
  • wifi_config_t wifi_config = {
  • .sta = {
  • .ssid = EXAMPLE_ESP_WIFI_SSID,
  • .password = EXAMPLE_ESP_WIFI_PASS,
  • /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
  • * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
  • * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
  • * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
  • */
  • .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
  • .sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
  • },
  • };
  • ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
  • ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
  • ESP_ERROR_CHECK(esp_wifi_start() );
  • ESP_LOGI(TAG, "wifi_init_sta finished.");
  • /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
  • * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
  • EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
  • WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
  • pdFALSE,
  • pdFALSE,
  • portMAX_DELAY);
  • /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
  • * happened. */
  • if (bits & WIFI_CONNECTED_BIT) {
  • ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
  • EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
  • } else if (bits & WIFI_FAIL_BIT) {
  • ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
  • EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
  • } else {
  • ESP_LOGE(TAG, "UNEXPECTED EVENT");
  • }
  • xTaskNotify(xtask_lvgl,1,eSetBits);
  • }

只需要在main里面调用void wifi_init_sta(void)就可以

 
ap:

  • /* WiFi softAP 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.
  • */
  • #include <string.h>
  • #include "freertos/FreeRTOS.h"
  • #include "freertos/task.h"
  • #include "esp_mac.h"
  • #include "esp_wifi.h"
  • #include "esp_event.h"
  • #include "esp_log.h"
  • #include "nvs_flash.h"
  • #include "lwip/err.h"
  • #include "lwip/sys.h"
  • /* The examples use WiFi configuration that you can set via project configuration menu.
  • If you'd rather not, just change the below entries to strings with
  • the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
  • */
  • #define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
  • #define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
  • #define EXAMPLE_ESP_WIFI_CHANNEL CONFIG_ESP_WIFI_CHANNEL
  • #define EXAMPLE_MAX_STA_CONN CONFIG_ESP_MAX_STA_CONN
  • static const char *TAG = "wifi softAP";
  • static void wifi_event_handler(void* arg, esp_event_base_t event_base,
  • int32_t event_id, void* event_data)
  • {
  • if (event_id == WIFI_EVENT_AP_STACONNECTED) {
  • wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
  • ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
  • MAC2STR(event->mac), event->aid);
  • } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
  • wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
  • ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
  • MAC2STR(event->mac), event->aid);
  • }
  • }
  • void wifi_init_softap(void)
  • {
  • esp_err_t ret = nvs_flash_init();
  • if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  • ESP_ERROR_CHECK(nvs_flash_erase());
  • ret = nvs_flash_init();
  • }
  • ESP_ERROR_CHECK(ret);
  • ESP_ERROR_CHECK(esp_netif_init());
  • ESP_ERROR_CHECK(esp_event_loop_create_default());
  • esp_netif_create_default_wifi_ap();
  • wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  • ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  • ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
  • ESP_EVENT_ANY_ID,
  • &wifi_event_handler,
  • NULL,
  • NULL));
  • wifi_config_t wifi_config = {
  • .ap = {
  • .ssid = EXAMPLE_ESP_WIFI_SSID,
  • .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
  • .channel = EXAMPLE_ESP_WIFI_CHANNEL,
  • .password = EXAMPLE_ESP_WIFI_PASS,
  • .max_connection = EXAMPLE_MAX_STA_CONN,
  • #ifdef CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT
  • .authmode = WIFI_AUTH_WPA3_PSK,
  • .sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
  • #else /* CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT */
  • .authmode = WIFI_AUTH_WPA2_PSK,
  • #endif
  • .pmf_cfg = {
  • .required = true,
  • },
  • },
  • };
  • if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
  • wifi_config.ap.authmode = WIFI_AUTH_OPEN;
  • }
  • ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
  • ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
  • ESP_ERROR_CHECK(esp_wifi_start());
  • ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
  • EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
  • }

 

  

 

任务3:控制WS2812B(必做任务)

比较简单,说下笔者的方案

esp官方依赖封装按键绑定以色轮输出rgb值的任务

使用官方案例的rmt 驱动ws2812b

要注意提前打开ws2812b的电源控制引脚

然后色轮输出rgb值的任务向lvgl任务发送任务通知

通过位操作把rgb通道存到任务通知的uint_t32
lvgl任务显示一个lv_led组件显示实际灯的颜色

 

 

   

     

任务4  分任务2:WS2812B效果控制

这个地方偷个  懒改个灯珠数量和针脚所以如下

是不是太偷懒了()

再写个任务四吧()

分任务1:日历&时钟

注册个ntp客户端去请求ntp时间

这个地方使用的esp idf的sntp(sample ntp)案例

把重要的几行程序提一下

  • void ntp_gettime(){
  • char strftime_buf[64];
  • time_t now;
  • struct tm timeinfo;
  • time(&now);
  • localtime_r(&now, &timeinfo);
  • // Is time set? If not, tm_year will be (1970 - 1900).
  • if (timeinfo.tm_year < (2016 - 1900)) {
  • ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
  • esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("pool.ntp.org");
  • esp_netif_sntp_init(&config);
  • esp_netif_sntp_start();
  • // update 'now' variable with current time
  • time(&now);
  • }
  • setenv("TZ", "CST-8", 1);
  • tzset();
  • while (1)
  • {
  • time(&now);
  • localtime_r(&now, &timeinfo);
  • strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
  • ESP_LOGI(TAG, "The current date/time in Shanghai is: %s", strftime_buf);
  • xQueueSend(ntp_time,(void*)strftime_buf, 0);
  • vTaskDelay(pdMS_TO_TICKS(1000));
  • }
  • }

把获取ntp时间封装位rtos任务,每1s请求一次时间

通过队列发送到lvgl任务

效果如图

 

任务5:通过网络控制WS2812B(可选任务,非必做)

写一个色盘网页从ws发送rgb到esp32s3上

esp32s3上websocket使用ws_echo_server案例改一下接受并解析rgb json文件

通过任务队列发送给ws2812的显示任务里

 

  后记:

■  分任务3:数据检测与记录——按一定时间间隔连续记录温度/亮度信息,保存到SD卡,并可以通过按键调用查看之前的信息,并在屏幕上绘图

建议搭配器件:Adafruit ESP32-S3 TFT Feather、光传感器、温度传感器、微型 SD卡模块

■  分任务4:音乐播放功能——实现音乐播放器功能,可以在屏幕上显示列表信息和音乐信息,使用按键进行切换,使用扬声器进行播放

建议搭配器件:Adafruit ESP32-S3 TFT Feather、音频放大器、扬声器

■  分任务5:AI功能应用——结合运动传感器,完成手势识别功能,至少要识别三种手势(如水平左右、前后、垂直上下、水平画圈、垂直画圈,或者更复杂手势

建议搭配器件:Adafruit ESP32-S3 TFT Feather、运动传感器
这几个任务我这现在要不就是缺能和这块板子适配的元件(i2s codec比如),要不就是这段时间稍微忙点等短时间我可能会做一下补一下

只管稍微说一下在espidf上跑这几个功能的思路:

sd卡使用sdio 1line/4line或者spisd卡都可,去案例找一下引脚配置就可

iic自行找自己使用的外设

音乐播放功能可以使用esp-adf的组件自行配置adc/codec,楼主测试过es8311和es7210都是适配没问题,使用pipline或者element方法都可以写一下这个功能的还算是比较简单的

AI功能应用的话mpu6050的数据读取不做另行说明,但是这地方使用ai相关配置我还真的不太了解,如果各位有了解请麻烦分享一下


代码包下载地址:https://download.eeworld.com.cn/detail/eew_MsNISU/629815

 

心得体会

这次活动让我更深入地了解了ESP32-S3的开发生态和丰富的外设支持。通过实际操作,我积累了更多的硬件开发经验,同时也感受到了espidf在实际项目中的灵活性和强大功能。希望未来的活动能够继续涵盖更多领域,激发更多创意和技术探讨。感谢EEWORLD和DigiKey提供这样一个学习与交流的平台!

最新回复

lvgl任务显示一个lv_led组件显示实际灯的的RGB颜色,这个确实是不错的   详情 回复 发表于 2023-11-6 07:22
点赞 关注
 
 

回复
举报

7017

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

lvgl任务显示一个lv_led组件显示实际灯的的RGB颜色,这个确实是不错的

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条
有奖直播报名| TI 面向楼宇和工厂自动化行业的毫米波雷达解决方案
【内容简介】TI 60GHz IWRL6432和 IWRL1432毫米波雷达传感器如何帮助解决楼宇和工厂自动化应用中的感应难题
【直播时间】5月28日(周三)上午10:00
【直播礼品】小米双肩包、contigo水杯、胶囊伞、安克充电器

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 8

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表