From 48cf4020c31189a781abdcd1d19b907373ed6000 Mon Sep 17 00:00:00 2001 From: Koichi Ito Date: Thu, 3 Sep 2026 09:55:45 +0900 Subject: [PATCH] =?UTF-8?q?NeoPixcel=20=E3=83=A2=E3=82=B8=E3=83=A5?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- firmware/NeoPixelController.cpp | 63 +++++++++++++++++++++++++++++++++ firmware/NeoPixelController.h | 20 +++++++++++ firmware/firmware.ino | 62 +++----------------------------- 3 files changed, 88 insertions(+), 57 deletions(-) create mode 100644 firmware/NeoPixelController.cpp create mode 100644 firmware/NeoPixelController.h diff --git a/firmware/NeoPixelController.cpp b/firmware/NeoPixelController.cpp new file mode 100644 index 0000000..b67c73a --- /dev/null +++ b/firmware/NeoPixelController.cpp @@ -0,0 +1,63 @@ +#include "NeoPixelController.h" + +#include + +namespace { +constexpr uint8_t kPin = 18; +constexpr uint16_t kCount = 1; +constexpr uint32_t kColors[] = { + 0xFF0000, 0xFF8000, 0xFFFF00, 0x00FF00, + 0x0000FF, 0x4B0082, 0x8F00FF +}; +constexpr uint8_t kColorCount = sizeof(kColors) / sizeof(kColors[0]); + +Adafruit_NeoPixel pixels(kCount, kPin, NEO_GRB + NEO_KHZ800); +} + +void NeoPixelController::begin() { + pixels.begin(); + pixels.setBrightness(255); + pixels.setPixelColor(0, kColors[kStoppedColorIndex]); + pixels.show(); +} + +void NeoPixelController::setPlaying(bool playing) { + isPlaying_ = playing; + + if (isPlaying_) { + transitionStart_ = millis(); + lastUpdate_ = transitionStart_; + return; + } + + colorIndex_ = kStoppedColorIndex; + pixels.setPixelColor(0, kColors[colorIndex_]); + pixels.show(); +} + +void NeoPixelController::update() { + if (!isPlaying_ || millis() - lastUpdate_ < kUpdateIntervalMs) { + return; + } + + unsigned long now = millis(); + lastUpdate_ = now; + unsigned long transitionElapsed = now - transitionStart_; + if (transitionElapsed >= kTransitionMs) { + colorIndex_ = (colorIndex_ + transitionElapsed / kTransitionMs) % kColorCount; + transitionStart_ = now; + transitionElapsed = 0; + } + + uint8_t nextColorIndex = (colorIndex_ + 1) % kColorCount; + uint32_t currentColor = kColors[colorIndex_]; + uint32_t nextColor = kColors[nextColorIndex]; + uint8_t red = ((currentColor >> 16) * (kTransitionMs - transitionElapsed) + + (nextColor >> 16) * transitionElapsed) / kTransitionMs; + uint8_t green = (((currentColor >> 8) & 0xFF) * (kTransitionMs - transitionElapsed) + + ((nextColor >> 8) & 0xFF) * transitionElapsed) / kTransitionMs; + uint8_t blue = ((currentColor & 0xFF) * (kTransitionMs - transitionElapsed) + + (nextColor & 0xFF) * transitionElapsed) / kTransitionMs; + pixels.setPixelColor(0, red, green, blue); + pixels.show(); +} \ No newline at end of file diff --git a/firmware/NeoPixelController.h b/firmware/NeoPixelController.h new file mode 100644 index 0000000..d9004f4 --- /dev/null +++ b/firmware/NeoPixelController.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +class NeoPixelController { +public: + void begin(); + void setPlaying(bool playing); + void update(); + +private: + static constexpr uint8_t kStoppedColorIndex = 3; + static constexpr unsigned long kUpdateIntervalMs = 30; + static constexpr unsigned long kTransitionMs = 3000; + + bool isPlaying_ = false; + uint8_t colorIndex_ = 0; + unsigned long lastUpdate_ = 0; + unsigned long transitionStart_ = 0; +}; \ No newline at end of file diff --git a/firmware/firmware.ino b/firmware/firmware.ino index ffbb598..d7f224f 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -1,28 +1,13 @@ #include "BluetoothA2DPSink.h" #include #include -#include - -// WS2812B設定 -constexpr uint8_t WS2812B_PIN = 18; -constexpr uint16_t WS2812B_COUNT = 1; -Adafruit_NeoPixel ws2812b(WS2812B_COUNT, WS2812B_PIN, NEO_GRB + NEO_KHZ800); -const uint32_t ws2812bColors[] = { - 0xFF0000, 0xFF8000, 0xFFFF00, 0x00FF00, - 0x0000FF, 0x4B0082, 0x8F00FF -}; -constexpr uint8_t WS2812B_COLOR_COUNT = sizeof(ws2812bColors) / sizeof(ws2812bColors[0]); -constexpr unsigned long WS2812B_INTERVAL_MS = 30; -constexpr unsigned long WS2812B_TRANSITION_MS = 3000; -bool isPlaying = false; -uint8_t ws2812bColorIndex = 0; -unsigned long lastWs2812bUpdate = 0; -unsigned long ws2812bTransitionStart = 0; +#include "NeoPixelController.h" // I2C接続のOLED設定 (SSD1306 128x64) U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); BluetoothA2DPSink a2dp_sink; +NeoPixelController neoPixelController; // 表示用変数 String currentTitle = "未接続"; @@ -92,28 +77,13 @@ void volume_changed_callback(int volume) { } void audio_state_changed_callback(esp_a2d_audio_state_t state, void *) { - isPlaying = (state == ESP_A2D_AUDIO_STATE_STARTED); - - if (isPlaying) { - ws2812bTransitionStart = millis(); - lastWs2812bUpdate = ws2812bTransitionStart; - } - - if (!isPlaying) { - ws2812bColorIndex = 3; - ws2812b.setPixelColor(0, ws2812bColors[ws2812bColorIndex]); - ws2812b.show(); - } + neoPixelController.setPlaying(state == ESP_A2D_AUDIO_STATE_STARTED); } void setup() { Serial.begin(115200); - // WS2812Bを緑で点灯 - ws2812b.begin(); - ws2812b.setBrightness(255); - ws2812b.setPixelColor(0, ws2812bColors[3]); - ws2812b.show(); + neoPixelController.begin(); // SDAをGPIO 19、SCLをGPIO 32 に設定 // (配線に合わせて Wire.begin(SDA_PIN, SCL_PIN) の順で指定します) @@ -151,27 +121,5 @@ void setup() { } void loop() { - if (isPlaying && millis() - lastWs2812bUpdate >= WS2812B_INTERVAL_MS) { - unsigned long now = millis(); - lastWs2812bUpdate = now; - unsigned long transitionElapsed = now - ws2812bTransitionStart; - if (transitionElapsed >= WS2812B_TRANSITION_MS) { - ws2812bColorIndex = (ws2812bColorIndex + transitionElapsed / WS2812B_TRANSITION_MS) - % WS2812B_COLOR_COUNT; - ws2812bTransitionStart = now; - transitionElapsed = 0; - } - uint8_t nextColorIndex = (ws2812bColorIndex + 1) % WS2812B_COLOR_COUNT; - uint32_t currentColor = ws2812bColors[ws2812bColorIndex]; - uint32_t nextColor = ws2812bColors[nextColorIndex]; - uint8_t red = ((currentColor >> 16) * (WS2812B_TRANSITION_MS - transitionElapsed) - + (nextColor >> 16) * transitionElapsed) / WS2812B_TRANSITION_MS; - uint8_t green = (((currentColor >> 8) & 0xFF) * (WS2812B_TRANSITION_MS - transitionElapsed) - + ((nextColor >> 8) & 0xFF) * transitionElapsed) / WS2812B_TRANSITION_MS; - uint8_t blue = ((currentColor & 0xFF) * (WS2812B_TRANSITION_MS - transitionElapsed) - + (nextColor & 0xFF) * transitionElapsed) / WS2812B_TRANSITION_MS; - ws2812b.setPixelColor(0, red, green, blue); - ws2812b.show(); - - } + neoPixelController.update(); } \ No newline at end of file