How shockwav3/multifunctionalknob works
1. This repository has two distinct layers: the firmware for an ESP32-C3 peripheral, and a large set of AI/workflow/documentation assets around that firmware. For an architecture diagram of the product itself, the important runtime boundary is the firmware under src/, include/, lib/, plus the PlatformIO build config.
2. The device is a Bluetooth HID rotary controller named “KnobKoKy.” Its core responsibility is to translate physical inputs from a rotary encoder and button into either HID actions or menu-driven configuration changes, while showing state on a small OLED display and persisting settings in NVS.
3. src/main.cpp is the composition root. It wires together configuration, event dispatchers/handlers, encoder mode management, menu control, display output, BLE HID services, macro behavior, and power management. This is the main place where subsystems are connected into one event-driven runtime.
4. Hardware input is split across custom drivers in lib/: ButtonDriver and EncoderDriver. These feed the application through the event layer in src/Event/, which is organized into dispatchers and handlers for button, encoder, menu, and app-level events. This is the main asynchronous boundary in the system.
5. The event pipeline is the central data flow: physical input -> driver -> event type -> dispatcher -> handler -> subsystem action. Shared event contracts live in include/Type/ and include/Enum/, which keeps the subsystems loosely coupled and makes the control flow explicit for diagramming.
6. Encoder behavior is abstracted as a mode system under src/EncoderMode/. There are separate handlers for scroll, volume, and zoom, plus a manager/selector layer that decides which behavior is active. This is the primary behavioral switch for the rotary knob.
7. The menu subsystem under src/Menu/ is the user-facing configuration boundary. It has a controller, tree/model objects, and action classes such as wheel mode selection, wheel direction selection, button behavior, display power, Bluetooth pair/disconnect, and status/about screens. Menu actions are the bridge from UI navigation to system state changes.
8. Bluetooth HID is encapsulated under src/BLE/. The BLE callback handler and keyboard service provide the external device interface that turns internal input events into wireless keyboard/mouse-like behavior. In diagram terms, this is the outbound hardware/service boundary to the host computer.
9. Display output is abstracted under src/Display/. A common DisplayInterface is implemented by both OLEDDisplay and SerialDisplay, and a DisplayTask processes DisplayRequest objects. This makes the display a separate consumer of application state rather than something the rest of the system writes to directly.
10. Configuration and persistence live under src/Config/, with ConfigManager and FactoryReset handling runtime settings and recovery. The include/Config/ headers define the device constants, pin mapping, and feature limits, while NVS persistence is the storage boundary for user settings like wheel direction, behavior, and other menu-driven options.
11. System behavior beyond input/output is handled by src/System/PowerManager.cpp, which supports inactivity-based sleep and wake behavior. This subsystem interacts with the event flow because user input resets timers and can wake the device, making power state part of the same control loop rather than a separate concern.
12. src/Macro/ adds another behavioral layer for programmable button actions, letting the device do more than simple HID passthrough. This subsystem is important because it expands the button from a single input into a configurable action trigger.
13. The build/runtime environment is PlatformIO for Arduino on ESP32-C3, with NimBLE used for the Bluetooth stack in the preferred build environment. The hardware target is the ESP32-C3 Super Mini with a rotary encoder and SSD1306 OLED on I2C; boards/nologo_esp32c3_super_mini.json and platformio.ini define the board/build boundary.
14. The extensive _bmad-output/, .claude/, .gemini/, .opencode/, .roo/, and _bmad/ trees are not part of firmware execution. They are documentation, planning, and AI-agent orchestration assets that describe the product, track epics/stories, and generate diagrams/specs; useful for understanding the project lifecycle, but separate from the runtime architecture.
Main entry points: main.cpp Main · Handler Handlers · Action Menu actions · Menu Menu system
Components 20
Firmware runtime
ESP32-C3 device code that runs KnobKoKy.
- Main · Wires the device runtime together and starts the event-driven loop.
src/main.cpp - Dispatchers · Routes button, encoder, menu, and app events to their handlers.
src/Event/Dispatcher - Handlers · Converts dispatched events into subsystem actions and state changes.
src/Event/Handler - Input drivers · Reads the rotary encoder and button from GPIO hardware.
lib - Event types · Shared event and status contracts used across subsystems.
include/Type - Enums · Core mode, direction, power, and error enums shared by the runtime.
include/Enum - Encoder modes · Selects rotary behavior such as scroll, volume, and zoom.
src/EncoderMode - Mode manager · Tracks the active encoder behavior and switches between modes.
src/EncoderMode/Manager - Mode handlers · Implements the concrete rotary behaviors for scroll, volume, and zoom.
src/EncoderMode/Handler - Menu system · Navigates device settings and invokes configuration actions.
src/Menu - Menu controller · Controls menu navigation state and selection flow.
src/Menu/Controller - Menu actions · Applies wheel, button, Bluetooth, display, and info actions from the menu.
src/Menu/Action - BLE HID · Exports device actions to the host computer over Bluetooth HID.
src/BLE - Display system · Builds and serves OLED or serial display output as requests.
src/Display - Display task · Consumes display requests and updates the active display implementation.
src/Display/Task - Config system · Loads, stores, and resets runtime settings backed by NVS.
src/Config - Power manager · Handles inactivity-based sleep and wake behavior.
src/System/PowerManager.cpp - Macro manager · Expands button input into configurable macro behaviors.
src/Macro/Manager - PlatformIO build · Defines the ESP32-C3 Arduino build environment and board target.
platformio.ini
Docs and agents
Planning, documentation, and AI workflow assets separate from runtime.
- Docs assets · Project planning, agent workflows, and generated documentation that support development but are outside firmware execution.
_bmad-output
Connections 29
- Input drivers → Dispatchers: input events · Physical button and encoder changes become application events.
- Dispatchers → Handlers: route · Dispatchers forward typed events to their handlers.
- Handlers → Encoder modes: select mode · Handlers choose or update rotary behavior.
- Handlers → Menu system: open menu · Events drive menu navigation and selection.
- Handlers → BLE HID: hid output · Input events can be translated into host-facing HID actions.
- Handlers → Display system: update ui · Handlers enqueue display state changes and requests.
- Handlers → Config system: persist settings · Menu and app events update stored configuration.
- Handlers → Power manager: reset timer · User activity affects idle and sleep control.
- Handlers → Macro manager: trigger macro · Button actions can invoke programmable macro behavior.
- Encoder modes → Mode manager: coordinate · The manager tracks and switches the active encoder behavior.
- Mode manager → Mode handlers: delegate · Active mode is executed by a concrete handler.
- Menu system → Menu controller: navigate · The controller manages the current menu state.
- Menu system → Menu actions: invoke actions · Menu selections map to concrete device actions.
- Menu actions → Config system: change config · Actions update runtime settings and NVS-backed values.
- Menu actions → BLE HID: pair/disconnect · Menu actions manage Bluetooth host connection state.
- Menu actions → Display system: screen modes · Actions can switch display content such as status or about screens.
- Display system → Display task: render requests · Display implementations are driven through request processing.
- Config system → PlatformIO build: device limits · Build and board configuration constrain runtime settings and hardware mappings.
- Main → Dispatchers: compose · Main wires dispatchers into the application runtime.
- Main → Handlers: compose · Main wires handlers into the application runtime.
- Main → Encoder modes: compose · Main initializes the encoder mode subsystem.
- Main → Menu system: compose · Main initializes menu navigation and actions.
- Main → BLE HID: compose · Main sets up Bluetooth HID services and callbacks.
- Main → Display system: compose · Main selects and starts the display pipeline.
- Main → Config system: compose · Main loads configuration and recovery behavior.
- Main → Power manager: compose · Main connects sleep and wake control into the loop.
- Main → Macro manager: compose · Main includes macro behavior in the runtime wiring.
- Main → Input drivers: init hardware · Main initializes the physical input drivers.
- Docs assets → Main: separate from runtime · Documentation and agent assets describe the project but do not participate in device execution.