Zenn
🤖

ESP32-S3 + PlatformIO + WS2812 LEDでLチカ

2025/02/20に公開

VSCode+PlatformIO拡張機能を使って、ESP32プロジェクトを作成します。
そして、今回は開発ボードに付いているRGB(WS2812)のLEDをLチカしてみます。

ESP32-S3開発ボードのピンレイアウト

今回使っているのは純正ではないボードでUSB Type-Cが2個とLEDが追加されているタイプ。

ピンレイアウトはおそらく純正ボードと同じ。

RGB LED制御 led_strip コンポーネントの追加

Arduino版はいくつかサンプルが出回ってますが、FreeRTOSを使いたいとなると、Espidf を指定する必要がある。こちらの場合、RGB LEDの制御サンプルがなかなかない。

ボードに実装されているRGB LEDはWS2812で制御するタイプで、led_stripライブラリを使う。ただし標準のフレームワークには含まれてない。 その代わり、Espidfのエクストラコンポーネントにライブラリがあるので、これをコピーしてプロジェクトに持ってくる。

https://github.com/espressif/idf-extra-components/tree/master

まずプロジェクトを作成します。ポイントはFrameworkをEspidfにします。
開発ボードはESP32 S3関連ならとりあえず動作すると思います。

プロジェクトが作成できたら、上記のコンポーネントをクローンして、led_stripフォルダを丸ごとコピーして配置する。配置場所は下図のようにすると、自動的にカスタムコンポーネントとして認識してもらえる。

{プロジェクトルート}/components/led_strip

led_stripのライブラリ使うための設定

platformio.iniは特に関係なし。念のためmonitor_speedは設定してます。

[env:esp32-s3-devkitm-1]
platform = espressif32
board = esp32-s3-devkitm-1
framework = espidf
monitor_speed = 115200

CMakeLists.txtを編集します。このファイルはプロジェクトに2個ありますが、編集するのは、src/CMakeLists.txtです。

以下のようにREQUIRES led_stripを追加する。

FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
idf_component_register(SRCS ${app_sources}
REQUIRES led_strip
)

とりあえず、コードを以下のように編集して、led_strip.hがインクルードできてビルドしてみて、環境として正しいかチェックする。

環境が間違っていると、ヘッダインクルードしてビルドするとエラーになる。

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "led_strip.h"

void app_main() {}

ビルドできたら正規のコードを以下のようにします。
順番に300ms間隔で点灯します。

ちなみに私が使っているボードのLEDピンは48番です。(もし使っているボードのRGB LEDピンが違う場合は変更)

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "led_strip.h"

#define LED_PIN 48  // WS2812の制御ピン
#define LED_NUM 1   // LEDの数

static led_strip_handle_t led_strip;

void init_ws2812() {
    led_strip_config_t strip_config = {
        .strip_gpio_num = LED_PIN,
        .max_leds = LED_NUM,
        .led_model = LED_MODEL_WS2812,
        .flags.invert_out = false,
    };

    led_strip_rmt_config_t rmt_config = {
        .resolution_hz = 10 * 1000 * 1000, // 10MHz
    };

    ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
}

void set_color(uint8_t r, uint8_t g, uint8_t b) {
    led_strip_set_pixel(led_strip, 0, r, g, b);
    ESP_ERROR_CHECK(led_strip_refresh(led_strip));
}

void app_main() {
    printf("Initializing WS2812...\n");
    init_ws2812();

    while (1) {
        printf("WS2812 LED ON (Red)\n");
        set_color(255, 0, 0); // 赤色
        vTaskDelay(pdMS_TO_TICKS(300));

        printf("WS2812 LED ON (Green)\n");
        set_color(0, 255, 0); // 緑色
        vTaskDelay(pdMS_TO_TICKS(300));

        printf("WS2812 LED ON (Blue)\n");
        set_color(0, 0, 255); // 青色
        vTaskDelay(pdMS_TO_TICKS(300));

        printf("WS2812 LED (White)\n");
        set_color(255, 255, 255); // 白色
        vTaskDelay(pdMS_TO_TICKS(300));
    }
}

書き込んで動作するか確認する。

Discussion

ログインするとコメントできます