1 · Genesis
My final project for the JVC course is a smart mug heater, designed to keep your coffee or tea at the perfect temperature. It features a PID control system, mug detection heuristics, and a simple OLED UI for user interaction.
The project was inspired by my love for coffee and the desire to create a practical solution that enhances the daily coffee experience. The goal was to build a functional prototype that could be refined further with more time.
Due to time constraints, I had to pivot from my original design, which used an LR7843 MOSFET and high-frequency PWM PID control, to a simpler 2N2222 transistor driving a relay. This change was necessary after the original MOSFET and OLED display were damaged during testing.
2 · Hardware & Electronics
Mechanical Design
I started with downloading and modelling the CAD files of my electrical components. I was highly inspired by the Prusa Cup Heater project, which uses a similar Prusa XL heater tile. I designed a simple enclosure in Fusion 360, held together with M3 screws. The enclosure was originally designed to be made out of plywood, but due to time constraints, I 3D printed the enclosure instead. The inner part of the enclosure has a sandwich design, with a heat shield made out of aluminum tape, that protects a pocket for cable management and then there is another layer with holes for wires and mounting points for the electronic components. The enclosure has a plexiglass window on the bottom, which allows the user to appreciate the electronics inside, which are displayed in an elegant fashion with cables hidden in the other layer.
Electronics
The first prototype leaned on an LR7843 MOSFET and a high‑frequency PWM PID. My board layout was, diplomatically, "optimistic". On the sixth re‑solder, both the MOSFET and the OLED display got cooked. With the deadline marching closer and needing to focus on studying for state exams, I pivoted to a simpler 2N2222 transistor that drives a 5V relay. As seen in the code and schematic, a ten‑second time‑proportional output (TPO) window replaced the PWM: the relay now clicks only a handful of times each minute, which is both gentle on the contacts and strangely satisfying to the ear.
Note: I'm running out of time to perfect this project as I need to focus on studying for my state exams. At this point, I've implemented a functional version but there are several improvements I would make with more time.
Components
- ESP8266 NodeMCU
- Prusa XL heater tile (24V)
- NTC 100k thermistor in 20k divider (integrated in the heater tile)
- Rotary encoder (CLK, DT, SW)
- SSD1306 OLED display (I2C) - replacement for the fried one
- 2N2222 transistor driving a 5V relay
ESP8266 NodeMCU Pinout Table
This table summarizes the function of each GPIO used in the project and what it's connected to:
| Label | GPIO | Function | Used For | Notes |
|---|---|---|---|---|
| D0 | GPIO16 | Input | Encoder SW | Does not support interrupts |
| D1 | GPIO5 | I2C SCL | OLED Display | |
| D2 | GPIO4 | I2C SDA | OLED Display | |
| D5 | GPIO14 | Input | ENC SW | - |
| D6 | GPIO12 | Input | ENC CLK | - |
| D7 | GPIO13 | Input | ENC DT | - |
| D8 | GPIO15 | Output | Relay control | Must be LOW at boot |
| A0 | A0 (ADC0) | Analog In | NTC Thermistor | Max 3.3V Input |
Photo showcase - assembly
These photos document the assembly process of the smart mug heater, including the components, the fried MOSFET and OLED, and their replacements with the 2N2222 transistor and relay solution.
3 · Software & UI
Firmware arrived in four sprints. First came the Steinhart‑Hart thermistor driver with a tiny median filter to tame ADC noise. Next, the rotary encoder: an interrupt‑driven Gray decoder on the encoder pins with software debounce, giving me a crisp twist‑to‑set experience.
The OLED display shows the current temperature, target temperature, and heating status. The implementation uses a simple UI layout with current temperature in large font and target temperature below it.
The ESP's Wi‑Fi connects to get the current time via NTP and can fetch weather data, though in the current implementation this is more of a placeholder due to time constraints.
The sketch is written in C++ (Arduino-style) and uses a simple but effective Time Proportional Output (TPO) logic for the relay control instead of continuous PWM, which would be inappropriate for a mechanical relay.
Video Showcase
Main features
- Temperature control with TPO for mechanical relay safety
- Rotary encoder interface for temperature adjustment
- Current and target temperature display
- Wi-Fi connectivity for time synchronization
- Simple, intuitive UI with clear visual feedback
Sample code (TPO logic from actual implementation)
// TPO heating control - only active when heating is enabled
static unsigned long tpoStart = 0;
if (heatingEnabled) {
float error = targetTemp - curTemp;
float duty = constrain(error * 0.25, 0.4, 1); // Simple proportional control
// 10-second TPO cycle
unsigned long currentMillis = millis();
unsigned long cycleTime = (currentMillis - tpoStart) % 10000;
relayOn = cycleTime < (duty * 10000);
digitalWrite(RELAY_PIN, relayOn);
} else {
// Make sure relay is off when heating disabled
relayOn = false;
digitalWrite(RELAY_PIN, LOW);
}
5 · Integration & Features
On power‑up, the heater attempts to join Wi‑Fi, syncs time via NTP, and initializes the display. Turning the encoder dial adjusts the target temperature between 30°C and 95°C in 0.5°C increments. A click of the encoder button toggles between edit mode and heating mode.
When heating is enabled, the system uses a simple proportional control algorithm with a 10-second TPO cycle. The heating duty cycle is determined by the difference between target and current temperatures, with constraints to prevent excessive cycling.
Due to time constraints and the need to study for state exams, some planned features like mug detection heuristics and weather-based prompts remain partially implemented, but the core functionality is working reliably.
- Current Implementation: Basic temperature control with encoder interface
- Display: Current temperature, target temperature, and heating status
- Safety: Auto-shutoff when not in heating mode
6 · Bill of Materials
| Item | Qty | Cost € | Notes |
|---|---|---|---|
| ESP8266 NodeMCU v1 | 1 | 3.50 | Brains + Wi‑Fi |
| Prusa XL heater tile | 1 | 20 | Prusa store |
| 2N2222 transistor | 1 | 0.20 | Driving the relay |
| 5V relay | 1 | 0.80 | Power switching |
| SSD1306 OLED 0.96″ | 2 | 8.40 | I²C 0×3C (1 replacement) |
| Rotary encoder KY‑040 | 1 | 0.60 | User dial |
| USB‑C PD trigger & buck | 1 | 6.00 | 20 V → 5 V |
| NTC 100k thermistor | 1 | 0† | With glass bead |
| 20k pull-up resistor | 1 | 0.10 | For thermistor divider |
| Capacitor (100nF) | 1 | 0.10 | Power smoothing |
| 3D printed enclosure | — | 2.00 | PLA material |
7 · Reflections & Conclusion
This project taught me valuable lessons about electronic design. The fried MOSFET and OLED display showed me that high‑current switching requires proper circuit design and thermal management. The pivot to a 2N2222 transistor driving a relay was ultimately a more robust solution for this prototype.
The interrupt-driven encoder handling provides a responsive user interface, and the TPO approach for relay control is an elegant solution that extends relay life while providing adequate temperature regulation.
Due to time constraints and the need to focus on state exams, I couldn't implement all the planned features or refine the design as much as I would have liked. With more time, I would improve the temperature control algorithm, add more robust error handling, and implement the planned mug detection feature.
Despite these limitations, the project demonstrates the core skills taught during the semester: embedded programming, sensor integration, UI design, and basic control systems. It's a functional mug heater that serves its purpose while leaving room for future improvements.