Compare commits

..

4 Commits

Author SHA1 Message Date
c1bd7d653a Adjusted the Design Document.
The Design Document is now the Product Design Document (PRD).
It was rewritten to be a bit more in line with just describing the why
and what of the product, not the how. It might not be perfect, but it is
good enough.

The README was adjusted to document that we are using the weasyprint
pdf-engine for pandoc. I had started with just using the LaTex engine,
but when you get to heading level 4, the heading is classified as a
paragraph and not a proper heading.

Also, all generated documents (*.pdf) were removed from the repository.
2025-07-27 12:04:20 -04:00
84ff23655c Adjusted the project structure in the README 2025-07-18 12:28:51 -04:00
aabcfc6a9a Added the generated design docs.
Also explained how to generate them in the README.md file.
2025-07-18 12:25:52 -04:00
1c593aff9b Initial pass on the design documentation.
The design doc and software design doc.
The UML images are generated with plantUML from the *.puml files.
2025-07-18 12:14:01 -04:00
7 changed files with 586 additions and 0 deletions

View File

@ -64,6 +64,9 @@ arithmetic via bounded, clamped, and wrapped integer types.
```text
src/
├── main.rs Entry point of the application.
├── menu/ The Menu Applicaiton.
├── badge/ The Badge Application.
├── snake/ The Snake Application.
```
## Getting Started
@ -93,8 +96,36 @@ To build and flash the program to your Microbit just run:
cargo embed
```
## Documentation
To generate all the documentation you will need to have pandoc and weasyprint
installed.
### Design Doc
The [Design Doc][./docs/design.pdf] is generated with pandoc from the markdown
file.
```bash
pandoc ./docs/design.md --pdf-engine=weasyprint -o ./docs/design.pdf
```
### Software Design Doc
The [Software Design Doc][./docs/sdd.pdf] is generated with pandoc from the markdown
file.
```bash
pandoc ./docs/sdd.md --pdf-engine=weasyprint -o ./docs/sdd.pdf
```
### UML
[UML][./docs/uml/] is generated using Plant UML on the \*.puml files.
```bash
plantuml ./docs/uml/*.puml
```
---
## Copyright & License

264
docs/prd.md Normal file
View File

@ -0,0 +1,264 @@
# MicroBadge
## Product Design Document
**Version:** 1.0
**Date:** July 11, 2025
**Author(s):** CyberMages, LLC (Jason Smith)
**Stakeholders:** Self, Potential Conference Attendees, Hobbyists
---
1. [Introduction](#introduction)
- [Purpose of this Document](#purpose-of-this-document)
- [Product Overview](#product-overview)
- [Target Audience](#target-audience)
- [Scope](#scope)
2. [Business Case & Goals](#business-case-goals)
- [Problem Statement](#problem-statement)
- [Business Objectives](#business-objectives)
- [Key Performance Indicators (KPIs)](#key-performance-indicators-kpis)
3. [User Stories / Use Cases / Features](#user-stories-use-cases-features)
- [User Personas](#user-personas)
- [Core Features](#core-features)
* [Menu System](#menu-system)
* [Name Scroller](#name-scroller)
* [NFC Business Card](#nfc-business-card)
* [Snake Game](#snake-game)
- [Out-of-Scope Features](#out-of-scope-features)
4. [User Experience (UX) & User Interface (UI)](#user-experience-ux-user-interface-ui)
- [User Flows](#user-flows)
- [Wireframes / Mockups](#wireframes-mockups)
- [Interaction Design](#interaction-design)
- [Accessibility Considerations](#accessibility-considerations)
- [Brand & Style Guidelines](#brand-style-guidelines)
5. [Technical Considerations (High-Level)](#technical-considerations-high-level)
- [System Integrations](#system-integrations)
- [Performance Requirements](#performance-requirements)
- [Security Considerations](#security-considerations)
- [Data Privacy](#data-privacy)
6. [Release Plan & Roadmap](#release-plan-roadmap)
- [Phased Rollout Strategy](#phased-rollout-strategy)
- [Future Considerations / Roadmap](#future-considerations-roadmap)
7. [Success Metrics & Analytics](#success-metrics-analytics)
- [Key Metrics to Track](#key-metrics-to-track)
- [Analytics Tools](#analytics-tools)
8. [Open Questions and Assumptions](#open-questions-and-assumptions)
- [Open Questions](#open-questions)
- [Assumptions](#assumptions)
9. [Appendices](#appendices)
- [Glossary](#glossary)
- [References](#references)
---
## Introduction
### Purpose of this Document
This document defines the **product vision**, **features**, and **user
experience** for MicroBadge, an interactive name badge application, to guide
its development and align on its purpose.
### Product Overview
**MicroBadge** is an interactive embedded application built for the BBC
micro:bit v2, functioning as a **conference name badge**. It provides a
**professional and technical icebreaker** at events through various
interactive apps.
### Target Audience
* Professionals attending conferences and networking events.
* Individuals looking for unique icebreakers and conversation starters.
* Developers interested in embedded Rust and interactive hardware.
* Anyone seeking a personalized, memorable name badge experience.
### Scope
This document covers the **initial release** of MicroBadge, including its
core menu system, name scroller, Snake game, and the NFC business card
functionality.
## Business Case & Goals
### Problem Statement
* Traditional name badges are often static and unengaging, failing
to facilitate professional or technical icebreaking effectively.
* Networking often lacks memorable, interactive elements.
* Sharing contact information can be cumbersome.
### Business Objectives
* Provide a **custom and memorable name badge experience**.
* Enable **fun interactions** and **easy sharing of contact info via NFC**.
* Serve as a **technical portfolio piece** for conferences, meetings,
and interviews.
* **Showcase embedded Rust development** using async and no-std.
### Key Performance Indicators (KPIs)
* Number of positive comments received about the badge.
* Frequency of badge-initiated conversations.
* Successful NFC contact transfers (post-completion).
* Completion rate of the Snake game by others.
---
## User Stories / Use Cases / Features
### User Personas
* **Conference Attendee Alex:** Wants to easily display their name,
engage in lighthearted interactions, and quickly share contact
details without fumbling for cards.
* **Tech Enthusiast Tara:** Appreciates the technical sophistication
and wants to use the badge as a conversation starter about embedded
Rust.
### Core Features
#### Menu System
**Description:** Allows the user to switch between different
applications on the micro:bit.
**User Stories:** As a user, I want to easily navigate between different
badge functionalities so I can quickly access the app
I need.
**Acceptance Criteria:**
* Menu is visible on the LED matrix.
* Navigation via physical buttons is intuitive and responsive.
* Selecting an app loads it promptly.
**Priority:** Must Have
#### Name Scroller
**Description:** Scrolls a user-defined name or custom message
across the 5x5 LED matrix.
**User Stories:** As a conference attendee, I want my name to scroll across
the badge so others can easily identify me from a distance.
**Acceptance Criteria:**
* Name scrolls smoothly and is legible.
* Scrolling text supports English ASCII characters only.
* Speed and repeat mode are configurable (future state).
**Priority:** Must Have
#### NFC Business Card
**Description:** Leverages the onboard NFC peripheral to share vCard/contact
data with mobile phones.
**User Stories:** As a user, I want to quickly share my contact information
by tapping my badge on a phone, saving time and effort.
**Acceptance Criteria:**
* Badge emits vCard data via NFC upon activation.
* Mobile phones can successfully read and import the data.
**Priority:** Must Have
#### Snake Game
**Description:** A classic Snake game playable on the 5x5 LED display,
designed for fun and interactivity.
**User Stories:** As a user, I want a simple, engaging game on my badge to
break the ice or pass time.
**Acceptance Criteria:**
* Game renders correctly on the 5x5 LED matrix.
* Controls (Button A, Button B for turning) are responsive.
* Game includes food, score tracking, and game over conditions.
* Game speed is tuned for usability.
**Priority:** Should Have
### Out-of-Scope Features
* Configuration storage via flash memory.
* Desktop companion app for editing settings.
* BLE for data sync or configuration.
## User Experience (UX) & User Interface (UI)
### User Flows
* **Power On:** Device boots, then goes directly to the main menu.
* **App Selection:** From main menu, user presses Button A to cycle
through apps, Button B to select.
* **App Interaction:** User interacts with the active app (e.g.,
scrolling name, playing Snake).
* **Return to Menu:** Pressing the **Reset button** on the back of
the device returns to the main menu.
### Wireframes / Mockups
The primary UI is the **5x5 LED matrix**. Visuals are abstract patterns or
simple character representations. (No detailed wireframes beyond conceptual
understanding of 5x5 limits).
### Interaction Design
* `Button A`: Navigation (e.g., move down in menu, turn left in Snake).
* `Button B`: Selection (e.g., select app, turn right in Snake).
* `Start Button` (capacitive touch logo): Its function varies by app:
- In the **Menu**, it selects the currently highlighted application.
- In the **Name Scroller**, pressing any button (A, B, or Start)
will return to the main menu.
- In the **Snake game**, the Start button is used for selections
within the game (e.g., choosing difficulty).
* LED matrix provides immediate **visual feedback** for selections, game
states, and menu navigation.
### Accessibility Considerations
Limited by the 5x5 LED matrix. Focus is on **clear, distinct visual
patterns** where possible.
### Brand & Style Guidelines
Adheres to the physical aesthetic of the BBC micro:bit v2, with simple,
functional LED display patterns.
## Technical Considerations (High-Level)
### System Integrations
* Onboard NFC peripheral (for NFC Business Card app).
* GPIO for button input.
* LED matrix display control.
### Performance Requirements
* Menu navigation must be responsive.
* Snake game refresh rate tuned for smooth play.
### Security Considerations
NFC data transfer should minimize privacy risks (e.g., only share public
contact info). No sensitive data stored.
### Data Privacy
VCard data intended for public sharing only. No personal data collected or
stored by the application itself.
## Release Plan & Roadmap
### Phased Rollout Strategy
Initial single release. No phased rollout planned for this version.
### Future Considerations / Roadmap
* Finalize NFC vCard transmission.
* Add configuration storage via flash memory for user preferences.
* Create a desktop companion app for easier settings editing.
* Support BLE for data synchronization or advanced configuration.
## Success Metrics & Analytics
### Key Metrics to Track
As listed in section 4.3 (e.g., qualitative feedback, observations of
interaction, NFC transfer success rate).
### Analytics Tools
Primarily anecdotal observation and direct user feedback due to the
embedded, standalone nature of the device.
## Open Questions and Assumptions
### Open Questions
* Exact vCard data format for NFC compatibility across devices.
* Optimal user experience for NFC activation on the micro:bit.
### Assumptions
* Users will be familiar with basic micro:bit interactions.
* The 5x5 LED matrix provides sufficient visual fidelity for intended
applications.
* NFC peripheral provides reliable data transfer.
## Appendices
### Glossary
**Embassy:** An asynchronous embedded runtime for Rust.
**HALs:** Hardware Abstraction Layers, providing a consistent API for
hardware peripherals.
**micro:bit v2:** A small, programmable computer designed for
education and hobbyists.
**NFC:** Near Field Communication, a set of communication protocols.
**PWM:** Pulse-width modulation, used for controlling LED intensity.
**vCard:** An electronic business card file format.
### References

243
docs/sdd.md Normal file
View File

@ -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 users 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 badges 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
04 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

BIN
docs/uml/switcher.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

35
docs/uml/switcher.puml Normal file
View File

@ -0,0 +1,35 @@
@startuml
interface App
[Switcher] --> [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

BIN
docs/uml/tasks.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

13
docs/uml/tasks.puml Normal file
View File

@ -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