M5 CapsuleでUSB Hostを試す
準備
M5 Capsuleの5Vin-GNDに5V電源を供給する
プログラム
以下の記事で利用したプログラムを流用して、「USBメモリを差すとLEDの色が赤から緑に変わるサンプルを作成
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_intr_alloc.h"
#include "usb/usb_host.h"
#define DAEMON_TASK_PRIORITY 2
#define CLASS_TASK_PRIORITY 3
#define INPUT_TASK_PRIORITY 4
#define CLIENT_NUM_EVENT_MSG 5
#define DELAY_DAEMON 500
#define DELAY_CLIENT 500
#define DELAY_INPUT 500
static const char *TAG_DAEMON = "DAEMON";
static const char *TAG_CLASS = "CLASS";
#define NUM_OF_LEDS 1
#define NEOPIXELS_PIN 21
Adafruit_NeoPixel pixels(NUM_OF_LEDS, NEOPIXELS_PIN, NEO_GRB + NEO_KHZ800);
typedef enum
{
DAEMON_READY = 1,
STOP_BUTTON_IS_PRESSED = 1 << 1
} app_event_t;
typedef struct
{
usb_host_client_handle_t client_hdl;
uint8_t dev_addr;
usb_device_handle_t dev_hdl;
} class_driver_t;
static void daemon_task(void *arg)
{
EventGroupHandle_t app_event = (EventGroupHandle_t)arg;
usb_host_config_t host_config = {
.skip_phy_setup = false,
.intr_flags = ESP_INTR_FLAG_LEVEL1,
};
usb_host_install(&host_config);
xEventGroupSetBits(app_event, DAEMON_READY);
bool no_clients = 0;
while (no_clients == 0)
{
uint32_t event_flags;
usb_host_lib_handle_events(DELAY_DAEMON, &event_flags);
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS)
{
no_clients = 1;
}
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE)
{
}
}
usb_host_uninstall();
vTaskDelete(NULL);
}
static void client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg)
{
class_driver_t *driver_obj = (class_driver_t *)arg;
switch (event_msg->event)
{
case USB_HOST_CLIENT_EVENT_NEW_DEV:
if (driver_obj->dev_addr == 0)
{
driver_obj->dev_addr = event_msg->new_dev.address;
usb_host_device_open(driver_obj->client_hdl, driver_obj->dev_addr, &driver_obj->dev_hdl);
usb_device_info_t dev_info;
usb_host_device_info(driver_obj->dev_hdl, &dev_info);
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
pixels.show();
}
break;
case USB_HOST_CLIENT_EVENT_DEV_GONE:
if (driver_obj->dev_hdl != NULL)
{
usb_host_device_close(driver_obj->client_hdl, driver_obj->dev_hdl);
}
break;
}
}
static void class_driver_task(void *arg)
{
EventGroupHandle_t app_event = (EventGroupHandle_t)arg;
EventBits_t event = xEventGroupWaitBits(app_event, DAEMON_READY, pdTRUE, pdFALSE, portMAX_DELAY);
class_driver_t driver_obj = {0};
usb_host_client_config_t client_config = {
.is_synchronous = false,
.max_num_event_msg = CLIENT_NUM_EVENT_MSG,
.async = {
.client_event_callback = client_event_cb,
.callback_arg = (void *)&driver_obj,
},
};
usb_host_client_register(&client_config, &driver_obj.client_hdl);
while (1) {
esp_err_t e = usb_host_client_handle_events(driver_obj.client_hdl, portMAX_DELAY);
}
if (driver_obj.dev_hdl != NULL)
{
usb_host_device_close(driver_obj.client_hdl, driver_obj.dev_hdl);
}
usb_host_client_deregister(driver_obj.client_hdl);
usb_host_device_free_all();
vTaskDelete(NULL);
}
void setup()
{
EventGroupHandle_t app_events = xEventGroupCreate();
uint32_t color = pixels.Color(255, 0, 0);
pixels.setPixelColor(0, color);
pixels.show();
xTaskCreatePinnedToCore(daemon_task,
"daemon",
4096,
(void *)app_events,
DAEMON_TASK_PRIORITY,
NULL,
0);
xTaskCreatePinnedToCore(class_driver_task,
"class_driver",
4096,
(void *)app_events,
CLASS_TASK_PRIORITY,
NULL,
0);
}
void loop()
{
delay(1000);
}
platformio.ini
[env:m5stack-stamps3]
platform = espressif32
board = m5stack-stamps3
framework = arduino
build_flags =
-D ARDUINO_USB_MODE=0
-D ARDUINO_USB_CDC_ON_BOOT=0
lib_deps = adafruit/Adafruit NeoPixel@^1.12.2
USBメモリを差してLEDの色が緑に変わることを確認!
USB MIDIデバイス
USB MIDIデバイスを使った場合でも無事に動作することが確認できた
環境
PlatformIO Core 6.1.15, Home 3.4.4
platform
espressif32
board:
m5stack-stamps3
framework:
arduino
Libs
adafruit/Adafruit NeoPixel@^1.12.2
USB Hostを使ってしまうと、シリアルでデバッグ出力ができない(する方法がみつけられていない)、他の通信手段(Bluetooth、WiFiなど)を使って、デバッグ出力する方法を模索する
この記事が気に入ったらサポートをしてみませんか?