From 1c593aff9b3e8b5d464149edfc714075e062af9c Mon Sep 17 00:00:00 2001 From: Myrddin Dundragon Date: Fri, 18 Jul 2025 12:14:01 -0400 Subject: [PATCH] Initial pass on the design documentation. The design doc and software design doc. The UML images are generated with plantUML from the *.puml files. --- docs/design.md | 76 +++++++++++++ docs/sdd.md | 243 +++++++++++++++++++++++++++++++++++++++++ docs/uml/switcher.png | Bin 0 -> 36092 bytes docs/uml/switcher.puml | 35 ++++++ docs/uml/tasks.png | Bin 0 -> 15663 bytes docs/uml/tasks.puml | 13 +++ 6 files changed, 367 insertions(+) create mode 100644 docs/design.md create mode 100644 docs/sdd.md create mode 100644 docs/uml/switcher.png create mode 100644 docs/uml/switcher.puml create mode 100644 docs/uml/tasks.png create mode 100644 docs/uml/tasks.puml diff --git a/docs/design.md b/docs/design.md new file mode 100644 index 0000000..f518056 --- /dev/null +++ b/docs/design.md @@ -0,0 +1,76 @@ +# Design Document: MicroBadge + +## Overview + +**MicroBadge** is an interactive embedded application built for the BBC +micro:bit v2. It is written in **Rust** using the **Embassy** async embedded +runtime. The project functions as a **conference name badge** that acts as a +professional and technical icebreaker at events. + +The application framework includes: +* A **menu system** for switching between apps. +* A **name scroller** for displaying your name or custom message. +* A **Snake game** for fun and interactivity. +* A **NFC business card** app for sharing contact info. **Still in progress** + +## Goals + +* Provide a custom and memorable name badge experience. +* Showcase embedded Rust development using async and no-std. +* Enable fun interactions and sharing via NFC. +* Serve as a technical portfolio piece for conferences, meetings, and + interviews. + +## Architecture + +### 1. Core Framework + +* Built on **Embassy** for asynchronous concurrency. +* Uses hardware abstraction layers (HALs) for GPIO, timers, display, and + buttons. +* Implements a lightweight app-switcher system with a menu UI. + +### 2. Applications + +#### Name Scroller +* Scrolls a name or message across the LED matrix. +* Configurable for speed and repeat mode. +* Useful for identifying the wearer at a glance. + +#### Snake Game +* Classic Snake game rendered on the 5x5 LED display. +* Uses `Button A` and `Button B` for turning. +* Includes food spawning, score tracking, and difficulty selection. +* Uses PWM for different intensity led lights. + +#### NFC Business Card (WIP) +* Leverages the onboard NFC peripheral. +* Intends to share vCard/contact data over NFC. +* Targeted at mobile phones for quick transfer of contact info + +## User Interaction + +* Navigation is handled via micro:bit's `Button A`, `Button B`, and long-press `Start` gesture +* LED matrix provides visual feedback for game states and menu navigation +* Apps are selected from a simple menu UI +* Snake game is tuned to a slower speed (~4Hz) for usability + +## Development Environment + +* Written entirely in **Rust**, `#![no_std]` +* Uses **Embassy** for async device access and task scheduling +* Debugging output via `defmt` +* Built and flashed using `probe-rs` and `cargo-embed` + +## Future Improvements + +* Finalize NFC vCard transmission +* Add configuration storage via flash memory +* Create a desktop companion app for editing settings +* Support BLE for data sync or configuration + +## Summary + +MicroBadge combines a fun hardware platform with modern Rust development. +It serves not only as a name badge but also as a way to demonstrate embedded +skills, share contact info, and invite technical discussion at events. diff --git a/docs/sdd.md b/docs/sdd.md new file mode 100644 index 0000000..e7d124c --- /dev/null +++ b/docs/sdd.md @@ -0,0 +1,243 @@ +# MicroBadge Software Design Document + +## 1. Introduction + +### 1.1 Purpose + +MicroBadge is a software application suite for the BBC micro:bit v2, designed +as a digital conference badge. It serves both functional and social purposes; +displaying the user’s name, hosting small interactive demos, and offering +contact sharing via NFC. + +This project serves as a conversation starter and technical showcase during +events like conferences, meetings, and interviews. + +### 1.2 Scope + +This document focuses exclusively on the software implementation of MicroBadge. +It covers the architecture, data structures, behavior, and design choices used +to implement the badge’s app-switching system and core applications using Rust +and the `embassy` async runtime. + +### 1.3 Audience + +This document is intended for: +* Reviewers evaluating its design. +* Recruiters or interviewers reviewing technical work. +* Anyone trying to learn how to write Rust on an embedded platform. + +## 2. System Overview + +MicroBadge is an embedded application for the micro:bit v2. It uses the +Embassy async runtime to manage multiple cooperative tasks without a +traditional RTOS. The system is modular and consists of an app switcher, +an LED display task, button listeners, and multiple interactive apps. + +### 2.1 Runtime and Concurrency + +MicroBadge uses Embassy's async executor. It runs the following tasks: + +* `display_task` -- Consumes frame buffers and drives the LED matrix. +* `button_listener` -- One per button (A, B, Start). Waits for input and + debounces it before sending an event. +* `app_task` -- Runs the currently selected app. Allows apps to yield and + re-enter on each loop. + +All communication is channel-based using `embassy_sync::channel::Channel`. + +[Task UML][./uml/tasks.png] + +### 2.2 App Switcher + +The `Switcher` manages app selection and transition. It displays a menu and +uses the A, B, and Start buttons to navigate between apps. + +Each app implements a shared `App` trait with an async `run()` method. +Apps are isolated and run cooperatively, returning control when done. + +Current apps: + +* *Menu*. The top-level app that allows selecting from installed apps. +* *Badge*. Scrolls a string (e.g. your name) across the LED matrix. +* *Snake*. A basic snake game with food, direction control, and score. +* *NFC Card* (in development). Will present contact info via NFC. + +[Switcher UML][./uml/switcher.png] + +### 2.3 Input System + +Each button is handled by a separate `button_listener` task. When a button +is pressed, it sends a `Button` enum into a shared channel. + +Apps listen for button input using the receiver end of the channel. + +* A and B buttons are mapped to actions like turn left and right. +* Start is used to confirm or start an app. It is mapped to the capacitive touch sensor logo. +* A debounce delay of 100 ms is used for stability. + +### 2.4 Rendering System + +The rendering system uses a frame buffer that is written by the active app +and read by the `display_task`. + +Apps write into this buffer using a `Renderer` abstraction. Drawing is done +in an offscreen buffer that is later pushed to the display. + +* The screen is a 5x5 LED grid. +* Per-frame updates allow for animations and dynamic content. +* LED brightness levels are supported. + +### 2.5 Code Organization + +The system is split into modules for clarity and reuse: + +* `app`. Defines the `App` trait and shared app interface. +* `display`. Low-level display driver and LED control. +* `renderer`. Provides drawing primitives for apps. +* `channel`. Shared async channels for button and frame messages. +* `switcher`. App selection logic and switching behavior. +* `snake`, `menu`, `badge`. App implementations. +* `microbit`. Definitions for button identifiers and device pins. + +Each module is self-contained and uses only the shared channels and traits +for interaction. + +## 3. Application Features + +### 3.1 Name Scroller + +* Scrolls a configured name across the LED display. +* Uses an async timer to advance frames. +* Simple input handling: Any Button returns to the menu. + +### 3.2 Snake Game + +* 5x5 LED grid snake game using a wrapped grid (`WrappedU8<0, 4>`). +* Buttons A and B turn the snake left/right. +* Food spawns randomly in empty grid cells. +* On collision with self, enters game-over state and displays score. + +### 3.3 NFC Business Card (WIP) + +* Intended to broadcast a vCard or custom URI over NFC. +* Plan to use the BLE softdevice on the chip. +* Currently under development. + +## 4. System Architecture + +This system uses Embassy's async runtime to coordinate application execution, +hardware input, and rendering on the micro:bit v2 board. It is divided into +distinct tasks: input listeners, a display task, and an app task. + +The overall architecture is message-passing oriented. Input events and screen +updates are communicated over embassy channels. + +Application logic is encapsulated in independent modules conforming to a shared +`App` trait. The Switcher manages the active app and transitions between them. + +### 4.1 Components + +* `main.rs`: Entry point. Spawns system tasks using Embassy. +* `Display`: Renders 5x5 LED frames from a channel receiver using PWM. +* `ButtonListener`: Listens for button presses and sends events via channel. +* `Switcher`: Manages app lifecycle and transitions. +* `App`: Trait for any runnable application module. +* `menu`, `badge`, `snake`, `nfc`: App implementations. + +## 5. Data Structures and State + +### 5.1 Position, Direction, and Snake Body + +The board is a fixed 5×5 grid. Positions are stored using a custom `Position` +struct, which holds a `ClampedU8` for both `x` and `y` axes, ensuring values +remain within bounds. + +* `Position`: Represents a coordinate on the board with safe bounds. +* `Direction`: Enum for movement direction: Up, Down, Left, Right. +* `Snake`: Maintains a list of `Position` elements representing the snake's + body. The first item is always the head. + +Snake direction is updated via input, and movement wraps to stay within the +board. + +### 5.2 Message-Passing and Input State + +User input is handled asynchronously via Embassy channels. + +* Button presses are detected using `button_listener` tasks. +* Events are sent to the `ButtonChannel`. +* Applications read input non-blockingly using `try_receive()`. + +This decouples physical input handling from application logic and allows clean, +testable state transitions. + +## 6. Component Interactions + +### 6.1 How Components Interact Over Time + +At runtime, three core tasks are running: + +* `display_task`: Receives rendered frames and presents them on the display. +* `button_listener`: Spawns three tasks, one per button (A, B, Start). +* `app_task`: Owns the app switcher and runs the current app. + +All interactions are asynchronous and use message-passing over embassy channels. + +### 6.2 Flow of Control + +1. User presses a button. +2. The button task sends a message to the channel. +3. The app reads the button event from the channel. +4. The app updates internal state (e.g., direction or selection). +5. The app prepares a frame and sends it to the frame channel. +6. The display task renders the frame. + +This loop repeats, giving a responsive, concurrent embedded UI. + +## 7. Development Environment + +### 7.1 Rust + Embassy + +This project uses Rust with the `embassy` async runtime. It provides +interrupt-driven, non-blocking execution suitable for low-power embedded +devices. + +### 7.2 Tools + +* `probe-rs`: For flashing and debugging firmware. +* `defmt`: Lightweight logging for embedded targets. +* `panic-probe`: Panic handler integrated with defmt output. +* `cargo-embed`: For development workflow and flashing. + +Development was done on Linux using vim and CLI tooling. + +## 8. Design Decisions + +### 8.1 Why Embassy + +Embassy was chosen for its async-first architecture, which maps well to +reactive, event-driven embedded applications like games and UI. It allows +multiple concurrent tasks without needing an RTOS or blocking code. + +### 8.2 Fixed Board Size + +The micro:bit's 5×5 LED matrix is inherently fixed. Game logic and rendering +are simplified by using a constant-size grid, avoiding the need for dynamic +allocation or scaling logic. + +### 8.3 Data Wrapping and Clamping + +Out-of-bounds positions are prevented using custom `ClampedU8` types. These +provide safe arithmetic that prevents overflow and keeps all positions within +0–4 inclusive. This reduces bugs and runtime checks in critical loops. + +## 9. Future Work + +### 9.1 NFC Business Card App + +An in-progress app will emulate a contact card via NFC. The goal is to allow +devices to scan the badge and receive contact information, a URL, or a vCard. + +### 9.3 UI Polish + + diff --git a/docs/uml/switcher.png b/docs/uml/switcher.png new file mode 100644 index 0000000000000000000000000000000000000000..cb3c91158d6accf9e3f8d5402f516ab0c4bb3f3b GIT binary patch literal 36092 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 [AppID] +[Switcher] --> [App] : use + +package "Menu" { + [App] <-- [Menu] +} + +package "Badge" { + [App] <-- [Badge] +} + +package "Snake" { + [App] <-- [Game] +} + +package "NFC" { + [App] <-- [NFC] +} + + +package "Channel" { + [ButtonReceiver] <-u- [Menu] : use + [ButtonReceiver] <-u- [Badge] : use + [ButtonReceiver] <-u- [Game] : use + [ButtonReceiver] <-u- [NFC] : use + [FrameSender] <-u- [Menu] : use + [FrameSender] <-u- [Badge] : use + [FrameSender] <-u- [Game] : use + [FrameSender] <-u- [NFC] : use +} + +@enduml diff --git a/docs/uml/tasks.png b/docs/uml/tasks.png new file mode 100644 index 0000000000000000000000000000000000000000..fd82564a0e40bc5fc42eee281e526cc06c297b6a GIT binary patch literal 15663 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 W>;(mqdlGQqPeDdS`kSP2;Qs*WQv`GX literal 0 HcmV?d00001 diff --git a/docs/uml/tasks.puml b/docs/uml/tasks.puml new file mode 100644 index 0000000..4d10481 --- /dev/null +++ b/docs/uml/tasks.puml @@ -0,0 +1,13 @@ +@startuml +skinparam componentStyle rectangle +[Tasks] --> [Switcher] +[Tasks] --> [Display] + +package "Button Listeners" { + [Tasks] --> [A Button Listener] + [Tasks] --> [B Button Listener] + [Tasks] --> [Start Button Listener] +} + +@enduml +