Skip to main content
Version: FILS English

Smart Station

An ambient-aware music controller built on Raspberry Pi Pico W using embedded Rust.

info

Author: Daria Gladkykh
GitHub Project Link: Smart Station on GitHub

Description

Smart Station is an IoT music controller that adjusts playback based on ambient light, includes alarm features.

Motivation

This project was chosen to explore embedded Rust for IoT applications, combining sensor-driven automation with an interactive user interface to create a practical, engaging device.

Architecture

The Smart Station consists of the following main components:

  • Sensor Processing:
    Handles input from the light sensor (LDR) to detect ambient brightness and trigger actions.
  • User Interface:
    Integrates an OLED screen configured as an Equalizer display for visual feedback. It also includes a joystick and buttons for music playback control.
  • Playback Control:
    Coordinates music playback from a connected PC, integrating sensor data and user inputs for volume and track control.
  • Visual Feedback:
    Drives an RGB LED to indicate system status and provides music-synced visuals on the OLED Equalizer screen.
  • Time Management:
    Uses LEDs to display time in binary format, utilizing an RTC module for accurate timekeeping.
    Additionally, includes a buzzer for periodic alarms (e.g., every 45 minutes) to remind users to take breaks.

Connections:

  • The Sensor Processing component feeds brightness data to the Playback Control.
  • The User Interface sends user commands (play, pause, etc.) to the Playback Control and queries the Time Management for clock/alarm data.
  • The Playback Control updates the Visual Feedback component to reflect playback status.
  • The Time Management component triggers the Playback Control for scheduled alarms.

System Architecture

Log

Week 5 - 11 May

What was already done:

  • Set up Raspberry Pi Pico W with Rust toolchain.
  • Configured GPIO for light sensor and RGB LED.
  • Initial testing of LDR sensor for ambient light detection.

Week 12 - 18 May

Initially, I planned to use the OLED screen as a standalone control station for the Smart Station. However, I encountered persistent issues with the screen's firmware—specifically, it continuously mirrored all output. Due to these limitations, I decided to repurpose the OLED solely as a visual equalizer display.

To achieve this, I used pre-processed audio data (converted into frequency slices using Rust) and mapped it to graphical bars on the OLED screen. I utilized the minifb crate for initial testing and the SSD1306 driver for actual rendering on the screen.

I now plan to incorporate binary clocks (using LEDs), a buzzer for periodic reminders, and a joystick with buttons to reintroduce the interactivity that the screen was initially intended to provide.

The equalizer has been tested with one audio track and is currently displaying frequency bands accurately. I aim to expand this to support around five compositions, broadening the use case of my Smart Station prototype and enhancing the user experience.

Week 19 - 25 May

What I have done:

  • Changed the display configuration with .command(Command::MemoryAccessControl, &[0x64]) to fix the mirroring issue.

  • Finalized playback interaction logic using joystick and buttons.

  • Added buzzer functionality with RTC-based scheduling (e.g., every 60 minutes as a reminder).

  • Implemented binary clock using LEDs.

  • Optimized OLED equalizer display and added the digital and numerical translation for the binary clocks from board.

  • Integrated and tested joystick/button controls for volume and track navigation.

  • Completed the website's simple logic and stored all MP3 files there.

  • Unified all separate tasks into a single main.rs file, managing asynchronous work in Rust.

  • Created the final look of the Smart Station prototype, ready for real-life testing.

Hardware

The Smart Station uses a Raspberry Pi Pico W, OLED , light sensor, RGB LED, and RTC module for a responsive music control system.

Sample of how everything is connected

Schematics

KiCAD schematics

Bill of Materials

DeviceQuantityPrice (RON)
Raspberry Pi Pico W3120
TFT SPI Display ST7789V170
Light sensor (LDR)110
Kit with LEDs, buttons, etc.160
RGB LED15
Jumper wires (various sets)140
Breadboards335
Total340 RON

Software

LibraryDescriptionUsage
embedded-halHardware abstraction layerInterfaces for GPIO, ADC, I2C, SPI
rp2040-halRP2040-specific HALLow-level Pico W peripheral access
ssd1306OLED display driverRenders UI on SSD1306 OLED
ds3231RTC module driverTimekeeping and alarm functionality
fugitTime-keeping utilityPrecise timing for RTC and alarms
embedded-graphics2D graphics libraryDraws UI elements on OLED
rppalRaspberry Pi Peripheral AccessGPIO and sensor communication
cortex-m-rtARM Cortex-M runtimeInterrupt handling and scheduling
embassy-lab-utilsCustom utility libraryProject-specific utilities
embassy-embedded-halEmbedded HAL for EmbassyAsync interfaces for peripherals
embassy-syncSynchronization primitivesAsync task coordination
embassy-executorAsync executor for EmbassyTask scheduling and execution
embassy-futuresFuture utilities for EmbassyAsync operation support
embassy-timeTime management for EmbassyPrecise timing for async tasks
embassy-rpRP2350-specific HALLow-level RP2350 peripheral access
embassy-usbUSB device supportUSB communication for playback
embassy-netNetwork stackNetwork connectivity for WiFi
embassy-net-wiznetWiznet network driverEthernet support for networking
embassy-usb-loggerUSB logging utilityDebugging over USB
logLogging facadeGeneral logging support
cyw43WiFi chip driverWiFi functionality for Pico W
cyw43-pioPIO-based WiFi driverLow-level WiFi communication
defmtEfficient logging for embeddedLightweight debug logging
defmt-rttRTT backend for defmtReal-time debug output
fixedFixed-point arithmeticPrecise calculations
fixed-macroMacros for fixed-pointSimplified fixed-point operations
serdeSerialization/deserializationData handling for configuration
serde-json-coreJSON serializationCompact JSON processing
panic-probePanic handler for probe-runError handling for debugging
display-interfaceDisplay interface abstractionGeneric display communication
display-interface-spiSPI display interfaceSPI-based display communication
mipidsiGeneric TFT display driverTFT display support
heaplessHeapless allocatorStatic memory allocation
embedded-hal-1Blocking embedded HALBlocking peripheral interfaces
embedded-hal-asyncAsync embedded HALAsync peripheral interfaces
embedded-hal-busBus sharing utilitiesSPI/I2C bus sharing
embedded-io-asyncAsync IO traitsAsync IO operations
static_cellStatic cell for runtime initSafe static initialization
embedded-storageNon-volatile storage traitsStorage access
randRandom number generatorsRandom number generation
embedded-sdmmcFAT filesystem for SD cardsSD card file access
byte-slice-castSafe byte slice castingType conversions
itoaInteger to string conversionString formatting
micromathLightweight math utilitiesMath operations
ili9341ILI9341 display driverTFT display rendering
  1. Rust Embedded Book - Guide for embedded Rust development.
  2. Raspberry Pi Pico W Documentation - Official Pico W reference.
  3. Embedded Graphics Documentation - Resource for UI rendering.
  4. Probe-rs - Tooling for flashing and debugging Rust firmware.
  5. Embassy-rs - Async runtime and drivers for embedded Rust.
  6. Defmt - Efficient logging framework for embedded systems.
  7. ILI9341-rs - Custom ILI9341 display driver.
  8. Serde - Serialization/deserialization framework.
  9. Rand - Random number generation library.
  10. Embedded HAL - Hardware abstraction layer for embedded systems.
  11. Embedded Storage - Non-volatile storage traits.