118 lines
6.6 KiB
Markdown
118 lines
6.6 KiB
Markdown
# micro-tuner
|
|
An instrument tuner assistant, built to be run on the Microbit V2. Portable and Practical!
|
|
## Background
|
|
Selecting a project for this course was itself small challenge and lead to a slightly later start then I would have otherwise planned.
|
|
### Alternatives
|
|
Since I thought a lot about it, I may as well mention what the alternatives may have been
|
|
* Reverse engineering, or augmenting the firmware of my [DEFCON30 badge](./defcon.jpg)
|
|
* Adding sound output capabilities to my recent [BSides badge](./bsides.jpg), possibly with my [piezoelectric buzzer](./buzzer.jpg) (discussed briefy in the notebook)
|
|
* An undetermined project, perhaps reverse engineering or adding to a small [FM receiver](./fm-tuner.jpg) board I have, but know little about (Chip MEGA328P)
|
|
* Sound oriented project involving other small devices I own like arduinos, raspberry pi's, and my newly aquired adafruit featherboard RP2040. Notably, the new Pi 5 no longer has a 3.5mm audio port, and it would be interesting to try to build a DAC in code with GPIO output, to not need an external USB DAC.
|
|
* Understanding/Experimenting with sound tricks like [Dolby Pro Logic](https://en.wikipedia.org/wiki/Dolby_Pro_Logic)
|
|
* Buying an SDR and exploring the various ways sounds is encoded and transmitted in practical radio applications. Learning the law, and getting an amateur radio license
|
|
|
|
I hope to work on many of these some day soon, but feel free to share these with any future students looking for ideas
|
|
|
|
### Decision
|
|
I chose to create an instrument tuner device with my microbit-v2 from the previous embedded rust course. Compared to the other ideas, this project is both tangible and flexible. It can be broken into different levels of goals and there are different layers of abstraction I can choose from with this approach.
|
|
|
|
## Goals
|
|
### Primary Goals (MVP)
|
|
* The microbit shall be able to play any reference note (tone mode). The reference note will be displayed on the LED matrix, and the touch button shall play the note when touched. The A and B buttons will allow the choosing of different reference notes.
|
|
* In an alternative mode (listen mode), the microbit shall be able to identify the note heard by the microphone. Likewise, this note should also be displayed
|
|
* Portable / can run on a battery (this should just work)
|
|
|
|
### Stretch Goals
|
|
* In the listen mode, if the note heard is close to a reference note, some feedback should be given (up or down arrow, etc.)
|
|
* Building on the above point to set a "target" note and provide appropriate feedback
|
|
* Avoid to some extent, sound abstraction the microbit package provides and build/interpret my own frequencies
|
|
|
|
|
|
### Fun ideas (Stretch ++)
|
|
* Interfacing with the dragontail and breadboard to do some cool stuff:
|
|
* Using the analog dial resistor to assist with chaning notes
|
|
* Using an external LED for more interesting feedback
|
|
* Printing some data to an external display
|
|
* Interfacing some pins to a USB adapter -> MIDI adapter -> My MIDI keyboard, to instantly choose a reference note
|
|
* Parallel implemention in rust, and comparing the performance
|
|
|
|
|
|
## Source Code Overview
|
|
Although I already have experience interfacing with the various capabilities of this device with rust, I initially decided to go with python for this project. I want to compare the experience of both, and also have the ability to take advantage of more abstractions if I choose to. However, after making significant progress building tone mode in `micropy`, I came to find that micropy (and the microbit package) do not generally allow API access to the raw data samples of the microphone pins. They only seem to expose 256 values of sound intensity. This makes rust appear much more feasible for listen mode, and the scope of this project has changed to now implement only tone mode in python, and listen mode in rust.
|
|
|
|
It should also be possible to flash a python application with some compiled rust, using a package like `PyO3`. If I have time, I will look into that.
|
|
|
|
|
|
### Python
|
|
#### [`main.py`](main.py)
|
|
This application (tone mode) works relatively well. Ultimetly, I decided to rely on microbits `music.play()` function which takes a note name as a parameter. In this regard much of the sound theory efforts are abstracted away, and there was more focus on the music and computers. The application works as follow
|
|
|
|
* On start, note A4 / Midi key 69 is selected.
|
|
* Pressing A selects the next note down; Pressing B selects the next note up
|
|
* The selected note and octave will wrap around on both ends (0 and 128)
|
|
* The root note (letter portion) is always rendered using all pixels except the last column
|
|
* If a flat note is selected, the bottom pixel of the last column is dimly lit.
|
|
* The current octave is expressed in a little-endian binary fashion with 4 pixels, top-down in the last column (not to conflict with the flat flag)
|
|
* Pressing A and B together was intended to switch to and from listen mode (not implemented as explained above)
|
|
### Rust
|
|
#### [`src/main.rs`](./src/main.rs)
|
|
|
|
Much of the code for this feature has beeen written, but some critical pieces remain. Some repositories were consulted, including
|
|
|
|
* [`mb2-template`](https://github.com/pdx-cs-rust-embedded/mb2-template): Configurations and common packages
|
|
* [`microbit-spectrum`](https://github.com/BartMassey/microbit-spectrum/blob/main/src/main.rs): This seems to be one of the only code examples of grabbing raw audio samples with the microbit microphone in rust
|
|
|
|
|
|
|
|
|
|
## Building/ Running - Python
|
|
It seems that many python microbit developers use a highly abstracted web-based IDE. I attempted to avoid that. These methods are tested only on my local debian-based linux machine, so your results may vary
|
|
### Dependencies
|
|
```bash
|
|
pip install microbit-3
|
|
pip install uflash
|
|
```
|
|
### IDE support
|
|
The microbit package does not seem to include the necessary stubs/tooltips for graceful IDE development. I found the [micro:bit Python](https://marketplace.visualstudio.com/items?itemName=MAKinteract.micro-bit-python) VS Code extension helpful. Follow its instructions
|
|
|
|
### Flashing
|
|
```bash
|
|
uflash main.py # Optional paramter for device port like /dev/ttyACM0 if not found automatically
|
|
```
|
|
|
|
### Serial (for console output)
|
|
```bash
|
|
screen /dev/ttyACM0 115200 # You may have a different port
|
|
```
|
|
|
|
## Building/ Running - Rust
|
|
|
|
### Dependencies
|
|
|
|
```bash
|
|
rustup target add thumbv7em-none-eabihf
|
|
rustup component add llvm-tools
|
|
cargo install cargo-binutils
|
|
cargo install probe-run
|
|
cargo install cargo-embed
|
|
```
|
|
|
|
### Flashing
|
|
```bash
|
|
cargo embed --release
|
|
```
|
|
|
|
## Testing
|
|
More time should be allocated to write tests, as well as perform user acceptence testing
|
|
|
|
## Demo
|
|
|
|
### Tone Mode
|
|
|
|
[tone-demo.mkv](./tone-demo.mkv)
|
|
|
|
### Listen Mode
|
|
|
|
Not Yet Ready
|
|
|
|
###### Author: David Westgate |