11# DeskCal - Smart Desk Calendar
2+ A smart desk calendar that displays weather, news, local sensor data, and
23A smart desk calendar that displays weather, local sensor data, and Google
34Calendar events on a TFT screen, with animated LED ring alerts for upcoming
45meetings.
@@ -14,6 +15,25 @@ meetings.
1415
1516## Description
1617
18+ DeskCal is a smart desk calendar running on an STM32 Nucleo-U545RE-Q
19+ microcontroller. It receives real-time data from a laptop via USB-UART —
20+ including current time, weather conditions, Calendar events, and live
21+ news headlines — all serialized as JSON by a companion Python script.
22+
23+ A BME280 sensor measures local temperature, humidity, and atmospheric pressure.
24+ A 2.8" ILI9341 TFT touchscreen display renders five navigable screens: a
25+ summary overview, a full-screen clock with upcoming meetings, a local air
26+ quality dashboard, an outdoor weather page, and a live news feed. Navigation
27+ between screens is done via swipe gestures on the touchscreen.
28+
29+ A WS2812B RGB LED ring displays animated color patterns — configurable via a
30+ companion web application — with a dedicated alert mode when a meeting is
31+ approaching. A passive buzzer emits an audio alert before
32+ events start.
33+
34+ The system supports multiple visual themes, selectable in real time from the
35+ companion web app which communicates with the Python bridge over HTTP. The
36+ device is housed in a custom 3D-printed enclosure.
1737DeskCal is a smart desk calendar running on an STM32 Nucleo-U545RE-Q
1838microcontroller. It receives weather data and Google Calendar events from a
1939laptop via USB-UART, processed by a Python script. A BME280 sensor provides
@@ -46,6 +66,36 @@ include:
4666
4767![ System Architecture Diagram] ( ./images/project-pm-diagram.drawio.svg )
4868
69+ ** DeskCal Controller (Web App)** — a local web application running in the
70+ browser that allows the user to select visual themes, configure LED ring
71+ behavior, adjust brightness, and push quick meetings to the device. Communicates
72+ with the Python bridge over HTTP at localhost:5000.
73+
74+ ** Python Bridge Script** — runs on the laptop and acts as the central data
75+ aggregator. Fetches weather data from OpenWeatherMap, events from
76+ Calendar, and news headlines from an RSS feed. Receives theme and configuration
77+ changes from the web app and forwards everything to the STM32 as JSON packets
78+ over USB-UART. Sends time synchronization packets every second
79+ and full data updates every 60 seconds.
80+
81+ ** STM32 Nucleo-U545RE-Q** — main controller running embassy-rs. Contains a
82+ dedicated async UART task that receives and parses incoming JSON packets and
83+ dispatches them to the main loop via a channel.
84+
85+ ** Display Subsystem** — ILI9341 2.8" TFT touchscreen over SPI renders five
86+ screens: Summary (screen 0), Clock + Meetings (screen 1), Air Quality (screen
87+ 2), Weather (screen 3), and News (screen 4). Navigation between screens is
88+ performed via swipe gestures detected on the XPT2046 touchscreen
89+ controller. When a meeting is within 5 minutes, a full-screen alert overlay
90+ appears with a dismiss button.
91+
92+ ** Alert Subsystem** — WS2812B LED ring driven via one-wire protocol (using SPI
93+ peripheral for precise timing) displays eight configurable animation modes:
94+ Off, Dim, Solid, Breathe, Pulse, Fast, Strobe, and Chase. The ring switches
95+ to a dedicated alert animation mode when a meeting is approaching. A passive
96+ buzzer driven by PWM emits a tone. Both the
97+ normal ring color/animation and the alert color/animation are configurable in
98+ real time from the web app.
4999The system is organized around four main components:
50100
51101** Host Python Script** — runs on the laptop, fetches weather from OpenWeatherMap
@@ -72,6 +122,50 @@ snooze via GPIO interrupt.
72122Finalized project idea and had the theme approved by the lab coordinator.
73123
74124### Week 7
125+ Ordered all hardware components from Optimus Digital and eMAG. Started reading
126+ embassy-rs documentation and experimenting with basic GPIO and UART on the
127+ Nucleo board. Started enclosure design in Fusion 360.
128+
129+ ### Week 8 & 9
130+ Completed project documentation page. Set up embassy-rs project skeleton for
131+ STM32U545. Verified all components arrived and functional.
132+
133+ ### Week 11 - Hardware Milestone
134+ Connected and tested all hardware components: ILI9341 display via SPI,
135+ BME280 sensor via I2C, WS2812B LED ring via SPI, passive buzzer via PWM,
136+ XPT2046 touchscreen, potentiometer via ADC. Designed and 3D printed enclosure.
137+ Implemented basic firmware with display rendering, sensor reading, touch input,
138+ buzzer alerts and LED ring animations.
139+
140+ ![ Project Wired] ( ./images/wires_project.webp )
141+ ![ Fusion Enclosure Project] ( ./images/fusion_project.webp )
142+
143+ ## Hardware
144+
145+ The project uses an STM32 Nucleo-U545RE-Q as the main microcontroller, running
146+ at 160MHz via PLL configured in firmware.
147+
148+ A 2.8" ILI9341 TFT display with integrated XPT2046 touchscreen controller is
149+ connected via SPI1 (PA5=SCK, PA7=MOSI, PA6=MISO). The display uses a dedicated
150+ SPI chip select (PC9) and control pins for data/command (PC8) and reset (PC6).
151+ The touchscreen controller shares the SPI bus with a separate chip select (PB4)
152+ and an interrupt line (PC13) for touch detection.
153+
154+ A BME280 barometric sensor is connected via I2C1 (PB6=SCL, PB7=SDA) and
155+ provides local temperature, humidity, and atmospheric pressure readings.
156+
157+ A WS2812B 16-LED RGB ring is driven via one-wire protocol using the SPI2
158+ peripheral (PC3=MOSI, PB13=SCK) at 6.4MHz for precise signal timing. Each bit
159+ is encoded as a single SPI byte (0xC0 for logical 0, 0xF8 for logical 1).
160+
161+ A passive buzzer is driven via PWM on TIM1 channel 1 (PA8), producing
162+ configurable frequency tones for meeting alerts.
163+
164+ A 50kΩ potentiometer is connected to ADC1 (PA0) and read periodically. A
165+ tactile button with integrated blue LED provides user interaction via GPIO.
166+
167+ All components are interconnected via jumper wires on a mini breadboard and
168+ housed in a custom 3D-printed PLA enclosure designed in Fusion 360.
75169Ordered all hardware components from Optimus Digital and eMAG. Started reading
76170embassy-rs documentation and experimenting with basic GPIO and UART on the
77171Nucleo board. Started enclosure design in Fusion 360.
@@ -94,6 +188,7 @@ All components are housed in a custom 3D-printed PLA enclosure.
94188### Schematics
95189
96190* TODO: KiCad schematic to be added at Hardware Milestone (Week 11)
191+ ![ KiCad schematic] ( ./images/kikad-deskcal.webp )
97192
98193### Bill of Materials
99194
@@ -124,6 +219,15 @@ The format is
124219
125220## Software
126221
222+ | Library | Description | Usage |
223+ | ---------| -------------| -------|
224+ | [ embassy-stm32] ( https://github.com/embassy-rs/embassy ) | Async HAL for STM32 | Peripheral drivers: SPI, I2C, UART, ADC, PWM, GPIO |
225+ | [ embassy-executor] ( https://github.com/embassy-rs/embassy ) | Async task executor | Running concurrent tasks on the microcontroller |
226+ | [ embassy-sync] ( https://github.com/embassy-rs/embassy ) | Sync primitives | Mutex and Channel for inter-task state sharing |
227+ | [ embassy-embedded-hal] ( https://github.com/embassy-rs/embassy ) | Embedded HAL bridge | SpiDevice wrapper for shared SPI bus |
228+
229+ * TODO: the rest will be added as I develop the code
230+
127231* TODO: the rest will be added as I develop the code
128232
129233| Library | Description | Usage |
@@ -142,3 +246,4 @@ The format is
1422465 . [ Google Calendar API Python quickstart] ( https://developers.google.com/calendar/api/quickstart/python )
1432476 . [ OpenWeatherMap API] ( https://openweathermap.org/api )
1442487 . [ embedded-graphics examples] ( https://github.com/embedded-graphics/examples )
249+ 8 . [ KiCad EDA for schematics] ( https://www.kicad.org )
0 commit comments