10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Raspberry Pi Pico C/C++ SDK で LVGL

Last updated at Posted at 2025-12-30

lvgl_rpp.jpg

前回記事はこちらです。
 Raspberry Pi Pico でタッチディスプレイを動かす

LVGLは、オープンソースのグラフィックス・ライブラリーです。多くのハードウェアに対応し、OSレスのベアメタルでも動きます。GUI作成(ボタンなどの配置)やイベント(ボタン押時の処理など)はLVGLを利用し、ハード固有の処理(ディスプレイ制御、タッチ位置取得など)はユーザーで作成するような使い方も出来ます。
詳細はこちらをご覧下さい。
Light and Versatile Graphics Library

今回は VSCode と Pico C++ SDK の環境へ LVGL を導入し、タッチスクリーンディスプレイを動かしてみます。
使用したタッチスクリーンディスプレイはこちらです。
Waveshare 3.5型静電容量式タッチスクリーンディスプレイ(320 x 480、SPI/I2C接続)
3.5inch Capacitive Touch LCD Wiki

次の項目順にすすめます。
     空のプロジェクト作成
     LVGLのダウンロード
     lv_conf.h の編集
     CMakeLists.txt の編集
     タッチスクリーンディスプレイのコーディング
     LVGLのコーディング

空のプロジェクト作成

General > New C/C++ Project でプロジェクトを作成します。SPI・I2C・C++にチェックしましたが、後でCMakeLists.txtを編集しても良いです。
Screenshot from 2025-12-26 19-07-56.png

LVGLのダウンロード

こちらからダウンロードできます。
The LVGL Repository
執筆時点のバージョンはv9.5でした。lvglフォルダーをプロジェクト先頭フォルダーへコピーします。プロジェクト内は次の画像のようになります。
Screenshot from 2025-12-28 10-26-12.png

lv_conf.h の編集

lvglフォルダーにある lv_conf_template.h をプロジェクト先頭フォルダーへコピーしてファイル名をlv_conf.hへ変更します(上の画像をご覧下さい)。
最初の方(v9.5では15行目)にある if 0 を #if 1 へ変更します(下記は変更後です)。

lv_conf h
/* clang-format off */
#if 1 /* Set this to "1" to enable content */

今回は大きめのフォントを使用したので、ついでに
#define   LV_FONT_MONTSERRAT_36    1   も 0から1へ変更しました。

CMakeLists.txt の編集

次の2行を最後に追加すると、LVGLもビルドするようになります。
     set(LV_CONF_INCLUDE_SIMPLE OFF)
     add_subdirectory(lvgl)
ビルドが終わると、build/lvgl/lib へ liblvgl.a というスタティックライブラリーを生成します。
target_include_directories と target_link_libraries を編集して /lvgl/lvgl.h へパスを通し、build/lvgl/lib/liblvgl.a をリンクすることで、ユーザーアプリケーションからLVGLを利用することが可能になります。

CMakeLists.txt
# Generated Cmake Pico project file

cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)

# == DO NOT EDIT THE FOLLOWING LINES for the Raspberry Pi Pico VS Code Extension to work ==
if(WIN32)
    set(USERHOME $ENV{USERPROFILE})
else()
    set(USERHOME $ENV{HOME})
endif()
set(sdkVersion 2.2.0)
set(toolchainVersion 14_2_Rel1)
set(picotoolVersion 2.2.0-a4)
set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)
if (EXISTS ${picoVscode})
    include(${picoVscode})
endif()
# ====================================================================================
set(PICO_BOARD pico CACHE STRING "Board type")

# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)

project(rpp1_app C CXX ASM)

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()

# Add executable. Default name is the project name, version 0.1

add_executable(rpp1_app main.cpp LocalTouchLcd.cpp)

pico_set_program_name(rpp1_app "rpp1_app")
pico_set_program_version(rpp1_app "0.1")

# Modify the below lines to enable/disable output over UART/USB
pico_enable_stdio_uart(rpp1_app 0)
pico_enable_stdio_usb(rpp1_app 1)

# Add the standard library to the build
target_link_libraries(rpp1_app
        pico_stdlib
        pico_multicore
        hardware_spi
        hardware_gpio
        hardware_i2c
        ${CMAKE_CURRENT_LIST_DIR}/build/lvgl/lib/liblvgl.a
)

# Add the standard include files to the build
target_include_directories(rpp1_app PRIVATE
        ${CMAKE_CURRENT_LIST_DIR}
        ${CMAKE_CURRENT_LIST_DIR}/lvgl
)

pico_add_extra_outputs(rpp1_app)

set(LV_CONF_INCLUDE_SIMPLE OFF)
add_subdirectory(lvgl)

タッチスクリーンディスプレイのコーディング (LocalTouchLcd.cpp)

前回の記事で作成したコードを活用しました。
今回使用したタッチスクリーンディスプレイは320x480の縦長がディフォルトですが、本記事では480x320の横長として使用しています。ST7796SのMemory Data Access Controlコマンド(36h)にあるRow/Column Exchangeビットを利用しています。
タッチパネルはLCDと独立して別々に動いていますので、こちらも縦横を反転します。

なお、ハード側は縦長のまま、LVGL側で横長画面を90度(または270度)回転する方法もあります。詳細はこちらをご覧下さい。

LocalTouchLcd.cpp
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
#include "hardware/i2c.h"
#include "LocalTouchLcd.h"

#define	LDEF_LCD_WIDTH		480
#define	LDEF_LCD_HEIGHT		320


//==============================================================================
// LCD class
//==============================================================================
#define LDEF_SPI_PORT		spi1
#define	LDEF_SPI_SCK		10
#define	LDEF_SPI_MOSI		11
#define	LDEF_SPI_MISO		12
#define	LDEF_LCD_RST		13
#define	LDEF_LCD_BL			15
#define	LDEF_LCD_DC			14
#define	LDEF_LCD_CS			9


CLocalLcd::CLocalLcd()
{
}


CLocalLcd::~CLocalLcd()
{
}


void CLocalLcd::Init(void)
{
	InitRpp();
	InitLcd();
}


void CLocalLcd::DrawLvgl(int nX1, int nY1, int nX2, int nY2, uint8_t *bpData, int nQty)
{
	SetWindows(nX1, nY1, nX2, nY2);
	gpio_put(LDEF_LCD_DC, 1);
	gpio_put(LDEF_LCD_CS, 0);
	SpiWriteBase(bpData, nQty);
	gpio_put(LDEF_LCD_CS, 1);
}


void CLocalLcd::InitRpp(void)
{
	gpio_init(LDEF_LCD_CS);
	gpio_set_dir(LDEF_LCD_CS, GPIO_OUT);
	gpio_init(LDEF_LCD_RST);
	gpio_set_dir(LDEF_LCD_RST, GPIO_OUT);
	gpio_init(LDEF_LCD_BL);
	gpio_set_dir(LDEF_LCD_BL, GPIO_OUT);
	gpio_put(LDEF_LCD_BL, 1);
	gpio_put(LDEF_LCD_CS, 1);

	spi_init(LDEF_SPI_PORT, (125*1000*1000));
	gpio_set_function(LDEF_SPI_MISO, GPIO_FUNC_SPI);
	gpio_set_function(LDEF_SPI_SCK, GPIO_FUNC_SPI);
	gpio_set_function(LDEF_SPI_MOSI, GPIO_FUNC_SPI);

	gpio_init(LDEF_LCD_DC);
	gpio_set_dir(LDEF_LCD_DC, GPIO_OUT);
	gpio_put(LDEF_LCD_DC, 1);
}


void CLocalLcd::InitLcd(void)
{
	gpio_put(LDEF_LCD_RST, 0);
	busy_wait_us(100*1000);
	gpio_put(LDEF_LCD_RST, 1);
	busy_wait_us(10*1000);

	SpiWriteCmd(0x11);

	busy_wait_us(120*1000);

	SpiWriteCmd(0x36);
	SpiWriteData(0xe8);			// original 0x08  changed "Row/Column Exchange"

	SpiWriteCmd(0x3A);
	SpiWriteData(0x05);

	SpiWriteCmd(0xF0);
	SpiWriteData(0xC3);

	SpiWriteCmd(0xF0);
	SpiWriteData(0x96);

	SpiWriteCmd(0xB4);
	SpiWriteData(0x01);

	SpiWriteCmd(0xB7);
	SpiWriteData(0xC6);

	SpiWriteCmd(0xC0);
	SpiWriteData(0x80);
	SpiWriteData(0x45);

	SpiWriteCmd(0xC1);
	SpiWriteData(0x13);

	SpiWriteCmd(0xC2);
	SpiWriteData(0xA7);

	SpiWriteCmd(0xC5);
	SpiWriteData(0x0A);

	SpiWriteCmd(0xE8);
	SpiWriteData(0x40);
	SpiWriteData(0x8A);
	SpiWriteData(0x00);
	SpiWriteData(0x00);
	SpiWriteData(0x29);
	SpiWriteData(0x19);
	SpiWriteData(0xA5);
	SpiWriteData(0x33);

	SpiWriteCmd(0xE0);
	SpiWriteData(0xD0);
	SpiWriteData(0x08);
	SpiWriteData(0x0F);
	SpiWriteData(0x06);
	SpiWriteData(0x06);
	SpiWriteData(0x33);
	SpiWriteData(0x30);
	SpiWriteData(0x33);
	SpiWriteData(0x47);
	SpiWriteData(0x17);
	SpiWriteData(0x13);
	SpiWriteData(0x13);
	SpiWriteData(0x2B);
	SpiWriteData(0x31);

	SpiWriteCmd(0xE1);
	SpiWriteData(0xD0);
	SpiWriteData(0x0A);
	SpiWriteData(0x11);
	SpiWriteData(0x0B);
	SpiWriteData(0x09);
	SpiWriteData(0x07);
	SpiWriteData(0x2F);
	SpiWriteData(0x33);
	SpiWriteData(0x47);
	SpiWriteData(0x38);
	SpiWriteData(0x15);
	SpiWriteData(0x16);
	SpiWriteData(0x2C);
	SpiWriteData(0x32);

	SpiWriteCmd(0xF0);
	SpiWriteData(0x3C);

	SpiWriteCmd(0xF0);
	SpiWriteData(0x69);

	busy_wait_us(120*1000);

	SpiWriteCmd(0x21);

	SpiWriteCmd(0x29);
}


void CLocalLcd::SetWindows(int nXstart, int nYstart, int nXend, int nYend)
{
	unsigned char bData;

	SpiWriteCmd(0x2A);
	bData = (unsigned char)((nXstart >> 8) & 0xff);
	SpiWriteData(bData);
	bData = (unsigned char)(nXstart & 0xff);
	SpiWriteData(bData);
	bData = (unsigned char)((nXend >> 8) & 0xff);
	SpiWriteData(bData);
	bData = (unsigned char)(nXend & 0xff);
	SpiWriteData(bData);

	SpiWriteCmd(0x2B);
	bData = (unsigned char)((nYstart >> 8) & 0xff);
	SpiWriteData(bData);
	bData = (unsigned char)(nYstart & 0xff);
	SpiWriteData(bData);
	bData = (unsigned char)((nYend >> 8) & 0xff);
	SpiWriteData(bData);
	bData = (unsigned char)(nYend & 0xff);
	SpiWriteData(bData);

	SpiWriteCmd(0x2C);
}


void CLocalLcd::SpiWriteBase(unsigned char *bpTxBuf, int nLen)
{
	spi_write_blocking(LDEF_SPI_PORT, bpTxBuf, nLen);
}


void CLocalLcd::SpiWriteCmd(unsigned char bCmd)
{
	gpio_put(LDEF_LCD_DC, 0);
	gpio_put(LDEF_LCD_CS, 0);
	SpiWriteBase(&bCmd, 1);
}


void CLocalLcd::SpiWriteData(unsigned char bData)
{
	gpio_put(LDEF_LCD_DC, 1);
	gpio_put(LDEF_LCD_CS, 0);
	SpiWriteBase(&bData, 1);
	gpio_put(LDEF_LCD_CS, 1);
}


//==============================================================================
// Touch class
//==============================================================================
#define LDEF_I2C_PORT				i2c1
#define LDEF_I2C_ADDRESS			0x38
#define	LDEF_I2C_SDA				6
#define	LDEF_I2C_SCL				7
#define	LDEF_I2C_IRQ				8
#define	LDEF_I2C_RST				5
#define	LDEF_I2C_REG_NUM			0X02
#define	LDEF_I2C_REG_XY				0X03

static CLocalTouch *sctp;

CLocalTouch::CLocalTouch()
{
	CP = new tagClassParameter;
	memset(CP, 0, sizeof(tagClassParameter));
	sctp = this;
}


CLocalTouch::~CLocalTouch()
{
	delete CP;
}


void CLocalTouch::Init(void)
{
    i2c_init(LDEF_I2C_PORT, 400 * 1000);
    gpio_set_function(LDEF_I2C_SDA, GPIO_FUNC_I2C);
    gpio_set_function(LDEF_I2C_SCL, GPIO_FUNC_I2C);
    gpio_pull_up(LDEF_I2C_SDA);
    gpio_pull_up(LDEF_I2C_SCL);

    gpio_init(LDEF_I2C_IRQ);
    gpio_set_dir(LDEF_I2C_IRQ, GPIO_IN);
    gpio_pull_up(LDEF_I2C_IRQ);

	gpio_init(LDEF_I2C_RST);
	gpio_set_dir(LDEF_I2C_RST, GPIO_OUT);
    gpio_put(LDEF_I2C_RST, 1);
	sleep_ms(200);
    gpio_put(LDEF_I2C_RST, 0);
	sleep_ms(200);
    gpio_put(LDEF_I2C_RST, 1);
	sleep_ms(200);

	gpio_set_irq_enabled_with_callback(LDEF_I2C_IRQ, GPIO_IRQ_EDGE_FALL, true, CLocalTouch::IrqHandler);
}


int CLocalTouch::GetTouchXy(int *npOutX, int *npOutY)
{
	if((CP->nPointCount)==0) {
		return(-1);
	}
	(CP->nPointCount) = 0;
	(*npOutX) = (CP->nPosX);
	(*npOutY) = (CP->nPosY);
	return(0);
}


void CLocalTouch::IrqHandler(uint gpio, uint32_t events)
{
	unsigned char bCmd;
	unsigned char sRxBuf[64];
	int nRet, nLen, nLocalPC;
	//--------
	bCmd = LDEF_I2C_REG_NUM;
    i2c_write_blocking(LDEF_I2C_PORT, LDEF_I2C_ADDRESS, &bCmd, 1, false);
	nRet = i2c_read_blocking(LDEF_I2C_PORT, LDEF_I2C_ADDRESS, sRxBuf, 1, false);
	if(nRet==0) {
		return;
	}
	nLocalPC = (int)(sRxBuf[0]);
	nLen = (int)(sRxBuf[0]) * 6;
	//--------
	bCmd = LDEF_I2C_REG_XY;
    i2c_write_blocking(LDEF_I2C_PORT, LDEF_I2C_ADDRESS, &bCmd, 1, false);
	nRet = i2c_read_blocking(LDEF_I2C_PORT, LDEF_I2C_ADDRESS, sRxBuf, nLen, false);
	if(nRet==0) {
		return;
	}
	//--------
	(sctp->CP->nPosY) = 0 + (((int)((sRxBuf[0])&0x0f) << 8) + (int)(sRxBuf[1]));
	(sctp->CP->nPosX) = LDEF_LCD_WIDTH - (((int)((sRxBuf[2])&0x0f) << 8) + (int)(sRxBuf[3]));
	(sctp->CP->nPointCount) = nLocalPC;
	//printf("tpirq x=%03d y=%03d\n", (sctp->CP->nPosX), (sctp->CP->nPosY));
}
LocalTouchLcd.h
class CLocalLcd {
public:
	CLocalLcd();
	virtual ~CLocalLcd();
	void Init(void);
	void DrawLvgl(int nX1, int nY1, int nX2, int nY2, uint8_t *bpData, int nQty);

private:
	void InitRpp(void);
	void InitLcd(void);
	void SetWindows(int nXstart, int nYstart, int nXend, int nYend);
	void SpiWriteCmd(unsigned char bCmd);
	void SpiWriteData(unsigned char bData);
	void SpiWriteBase(unsigned char *bpTxBuf, int nLen);
};


class CLocalTouch {
public:
	CLocalTouch();
	virtual ~CLocalTouch();
	void Init(void);
	int GetTouchXy(int *npOutX, int *npOutY);
	typedef struct {
		int nPointCount;
		int nPosX;
		int nPosY;
	} tagClassParameter;
	tagClassParameter *CP;

private:
	static void IrqHandler(uint gpio, uint32_t events);
};

LVGLのコーディング (main.cpp)

まず、LVGLを利用するために #include "lvgl.h" を記述して下さい。

ディスプレイ表示

最低限のコードについての説明が次のサイトにあります。
Learn the Basics
かいつまんで箇条書きすると次の手順です。
     ハードウェア初期化
     lv_init();
     ミリ秒単位の経過時間を通知するコールバック関数作成
     画面の作成。バッファー確保、画面のコールバックを関数作成
     ポーリング(無限ループ)内で5ミリ秒間隔でlv_timer_handler()をコール

ミリ秒単位の経過時間を通知するコールバック関数は次のWebサイトを参考にしました。
LVGL Demo on Raspberry Pi Pico with Attached HUB75 RGB LED Matrix

使用したタッチスクリーンディスプレイではエンディアンの問題がありました。
今回は、各ピクセルの色をRGB565というフォーマットで指定しています。赤5ビット、緑6ビット、青5ビットの計16ビット(65536色)で表現する方法です。例えば緑は (00000 111111 00000) = 0x07E0 なので、0x07 0xE0 の2バイトをSPIで送れば良いのですが...。
Raspberry Pi Pico というか RP2040 というか arm はリトルエンディアンなので、LVGLが出力するワード(=2バイト)のデータは 1バイトめが0xE0、 2バイトめが0x07 となっていて、このままLCDへ送ると正しい色が表示出来ません。
そこで、lv_display_set_color_format()を使って LV_COLOR_FORMAT_RGB565 ではなくLV_COLOR_FORMAT_RGB565_SWAPPED を設定します。

画面のコールバック関数は、描画エリアの座標とデータが引数にありますので、この内容をタッチスクリーンディスプレイへ送ります。
終了前に lv_display_flush_ready(disp); が必要です。

ここまで出来たら、Learn the Basics のサンプルコードが動くと思います。

タッチパネル

次に、タッチパネルの動作確認へ移ります。
タッチパネルも画面と同様に、Createでインスタンスを作り、コールバック関数で現在の状態をLVGLへ伝えることで機能します。詳細は下記をご覧下さい。

こちらのページ にLVGLのサンプルコードがいっぱいありますので、このうち Create a slider and write its value on a label を試しました。

使ったコントロールはSliderとLabelです。ほぼサンプル通りにcreateでインスタンスを作成し、sliderのコールバック関数を用意すると、LVGLのWebサイトと同様の動作が冒頭画像のようにタッチスクリーンディスプレイでも出来るようになります。

main.cpp
#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/multicore.h"
#include "pico/critical_section.h"
#include "lvgl.h"
#include "LocalTouchLcd.h"

#define	LDEF_LCD_WIDTH				480
#define	LDEF_LCD_HEIGHT				320
#define LDEF_LED_DELAY_MS			500
#define LDEF_SLIDER_WIDTH			300
#define LDEF_LABEL1_OFFSET_Y		(-20)

static void my_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_buf);
static void my_touchpad_read(lv_indev_t *indev, lv_indev_data_t *data);
static uint32_t my_get_millis(void);
static void slider_event_cb(lv_event_t * e);
static void Core1Main(void);

static semaphore_t sem;
static CLocalLcd *LLP;
static CLocalTouch *LTP;
static lv_obj_t * label1;

int main()
{
    stdio_init_all();
	LLP = new CLocalLcd;
	(LLP->Init)();
	LTP = new CLocalTouch;
	(LTP->Init)();
	sem_init(&sem, 1, 1);
    multicore_launch_core1(Core1Main);

    //-------------------------------- LVGL
	lv_init();
    lv_tick_set_cb(my_get_millis);
	
    //-------------------------------- display
    static uint8_t buf[2 * LDEF_LCD_WIDTH * LDEF_LCD_HEIGHT / 8];
	lv_display_t *display = lv_display_create(LDEF_LCD_WIDTH, LDEF_LCD_HEIGHT);
    lv_display_set_color_format(display, LV_COLOR_FORMAT_RGB565_SWAPPED);
    lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0xa0a0a0), LV_PART_MAIN);
	lv_display_set_buffers(display, buf, NULL, sizeof(buf), LV_DISPLAY_RENDER_MODE_PARTIAL);
	lv_display_set_flush_cb(display, my_flush_cb);

    //-------------------------------- touch panel
	lv_indev_t *indev = lv_indev_create();
	lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
	lv_indev_set_read_cb(indev, my_touchpad_read);
	
    //-------------------------------- slider
    lv_obj_t *slider = lv_slider_create(lv_screen_active());
    lv_obj_set_width(slider, LDEF_SLIDER_WIDTH);
    lv_obj_center(slider);
    lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);

    //-------------------------------- label
    label1 = lv_label_create(lv_screen_active());
    lv_obj_set_style_text_font(label1, &lv_font_montserrat_36, LV_PART_MAIN);
	lv_obj_set_style_text_color(label1, lv_color_make(0x00, 0x40, 0x00), LV_PART_MAIN);
    lv_label_set_text(label1, "0");
    lv_obj_align_to(label1, slider, LV_ALIGN_OUT_TOP_MID, 0, LDEF_LABEL1_OFFSET_Y);

	//--------------------------------
    while(1) {
        lv_timer_handler();
		sleep_ms(5);
    }

    delete LTP;
    delete LLP;
	return(0);
}

//-------------------------------- display callback
static void my_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_buf)
{
	int nPix = ((area->x2)-(area->x1)+1) * ((area->y2)-(area->y1)+1);
	(LLP->DrawLvgl)((area->x1), (area->y1), (area->x2), (area->y2), px_buf, (nPix*2));
    //--------
    lv_display_flush_ready(disp);
}

//-------------------------------- touchpanel callback
static void my_touchpad_read(lv_indev_t *indev, lv_indev_data_t *data) {
	int nRet, nPosX, nPosY;
	nRet = (LTP->GetTouchXy)(&nPosX, &nPosY);
	if(nRet==0) {
		(data->point.x) = nPosX;
		(data->point.y) = nPosY;
		(data->state) = LV_INDEV_STATE_PRESSED;
	}
	else {
		(data->state) = LV_INDEV_STATE_RELEASED;
	}
}

//-------------------------------- slider callback
static void slider_event_cb(lv_event_t * e)
{
    lv_obj_t * slider = lv_event_get_target_obj(e);
	//--------
    lv_label_set_text_fmt(label1, "%" LV_PRId32, lv_slider_get_value(slider));
    lv_obj_align_to(label1, slider, LV_ALIGN_OUT_TOP_MID, 0, LDEF_LABEL1_OFFSET_Y);
}

//-------------------------------- tick callback
static uint32_t my_get_millis(void)
{
    critical_section_t crit_sec;
    critical_section_enter_blocking(&crit_sec);
    uint32_t ms = to_ms_since_boot(get_absolute_time());
    critical_section_exit(&crit_sec);
    return(ms);
}

//-------------------------------- LED blinking
static void Core1Main(void)
{
    gpio_init(PICO_DEFAULT_LED_PIN);
    gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);

	while(1) {
		gpio_put(PICO_DEFAULT_LED_PIN, 1);
		sleep_ms(LDEF_LED_DELAY_MS);
		gpio_put(PICO_DEFAULT_LED_PIN, 0);
		sleep_ms(LDEF_LED_DELAY_MS);
	}
}
10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?