Time & Room Temperature Display for mounting on Center Microphone Stand, Temperature and CO2 levels are derived from either the Room Controller or remote ENS160+AHT21 Devices
|
|
1 lună în urmă | |
|---|---|---|
| documents | 2 luni în urmă | |
| include | 1 lună în urmă | |
| lib | 1 lună în urmă | |
| src | 1 lună în urmă | |
| .gitignore | 2 luni în urmă | |
| CLAUDE.md | 1 lună în urmă | |
| README.md | 1 lună în urmă | |
| platformio.ini | 2 luni în urmă |
A simple, clean desktop temperature and clock display built around the WaveShare ESP32-S3-RLCD-4.2.
The display is designed to make the information readable from a distance, with the current time occupying the upper half of the screen and indoor/outdoor temperatures displayed prominently across the lower half.
The display uses the full 300 × 400 pixel resolution of the 4.2-inch reflective LCD.
Top 60%
Date displayed as:
A small battery indicator sits in the top right corner. It can be turned off in the setup page.
Bottom 40%
WaveShare ESP32-S3-RLCD-4.2
The board provides:
The onboard SHTC3 provides the indoor temperature measurement. The PCF85063 provides hardware real-time clock functionality.
The 4.2-inch panel is fully reflective and has no backlight or frontlight. It is read by room light alone, which means it needs no power to hold an image but also cannot be read in the dark. Both facts shape the power saving below.
Battery voltage is measured through the onboard divider on ADC1 channel 3 (GPIO4). The divider sits downstream of the charger, so the firmware reports cell voltage but cannot distinguish "charging" from "fully charged".
A BH1750 module on the expansion header lets the display detect an unlit room and sleep. It is optional — without it the same decision is made from the clock using configurable quiet hours.
| BH1750 | Board |
|---|---|
| VCC | 3V3 |
| GND | GND |
| SDA | GPIO 13 |
| SCL | GPIO 14 |
| ADDR | leave unconnected |
It shares the existing I²C bus with the RTC and the SHTC3, so no GPIO is consumed. Both possible addresses (0x23 and 0x5C) are probed at boot, and the setup page reports whether the sensor was found along with the current lux reading.
See the official hardware documentation:
WaveShare ESP32-S3-RLCD-4.2 Documentation
The outdoor temperature will be supplied separately from the display.
The preferred architecture is:
Outdoor Sensor
│
│ Wi-Fi
▼
ESP32-S3-RLCD-4.2
│
├── Indoor Temperature
├── Outdoor Temperature
├── Date
└── Time
The outdoor sensor can be another ESP32-based device, a network temperature sensor, MQTT source, HTTP API, or another compatible data source.
The display should continue showing the last known outdoor temperature if the outdoor sensor temporarily becomes unavailable.
The project is intended to run on the ESP32-S3 using the Arduino framework.
Recommended:
WaveShare officially supports both Arduino IDE and ESP-IDF for this board.
┌─────────────────────┐
│ ESP32-S3 │
│ │
│ Main Application │
└──────────┬──────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ RTC │ │ SHTC3 │ │ Wi-Fi │
│ PCF85063 │ │ Indoor │ │ │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
│ │ │
│ │ Outdoor Temp
│ │ │
└────────────────┼────────────────┘
│
▼
┌──────────────────┐
│ Display Engine │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 300 × 400 RLCD │
└──────────────────┘
The UI should remain intentionally simple.
There should be no unnecessary menus, icons, animations, or small text.
The primary purpose of the display is to provide information that can be read quickly from across a room.
The time should be the largest element on the display.
Example:
11:08
The seconds should not normally be displayed.
The display should update once per minute.
24-hour and 12-hour formats are both selectable in the setup page; 24 hour is the default.
The date is positioned directly underneath the time.
Example:
MONDAY 24 AUGUST
The arrangement is configurable — see Time and date format.
The indoor temperature comes from the onboard SHTC3 sensor.
Example:
INDOOR
21.5°C
The outdoor temperature is received over the network.
Example:
OUTDOOR
14.8°C
| Data | Source | Update Rate |
|---|---|---|
| Time | PCF85063 RTC | 1 minute |
| Date | PCF85063 RTC | 1 day |
| Indoor temperature | SHTC3 | 30–60 seconds |
| Outdoor temperature | Network | 30–60 seconds |
| Display | RLCD | As required |
The display should avoid unnecessary full-screen refreshes.
On startup, with no Wi-Fi configured, the display raises its own access point and shows the setup screen instead of the clock. See Configuration.
Otherwise, on startup:
During normal operation:
If Wi-Fi is unavailable:
Losing Wi-Fi does not return the display to setup mode. A working clock on screen matters more than an opportunity to reconfigure, so the setup access point appears only when no network is stored or when KEY is held at power-up.
The ESP32-S3 should synchronise the RTC from an NTP server when network connectivity is available.
Recommended configuration:
NTP Server:
pool.ntp.org
Time Zone:
Australia/Hobart
Format:
24 hour
The NTP server and timezone are both set in the setup page; the values above are the defaults.
The RTC then maintains the time locally when Wi-Fi is unavailable. It stores UTC, so a daylight saving change needs no intervention.
Temperatures should be displayed with one decimal place.
Examples:
21.5°C
19.0°C
7.8°C
-2.3°C
The degree symbol should be displayed as:
°C
The display continues operating from the local RTC.
OUTDOOR
--.-°C
or, if a previous value is available:
OUTDOOR
14.8°C
The previous value should preferably remain visible rather than replacing it immediately with an error value.
If the SHTC3 cannot provide a valid indoor temperature:
INDOOR
--.-°C
If the RTC has lost its valid time:
--:--
The system should attempt to correct the time as soon as network connectivity becomes available.
A suggested project structure:
/
├── README.md
├── platformio.ini
│
├── src/
│ ├── main.cpp
│ ├── display.cpp
│ ├── display.h
│ ├── rtc.cpp
│ ├── rtc.h
│ ├── temperature.cpp
│ ├── temperature.h
│ ├── network.cpp
│ ├── network.h
│ ├── outdoor.cpp
│ ├── outdoor.h
│ ├── settings.cpp
│ ├── settings.h
│ ├── portal.cpp
│ ├── portal.h
│ ├── battery.cpp
│ ├── battery.h
│ ├── ambient.cpp
│ ├── ambient.h
│ ├── power.cpp
│ └── power.h
│
├── include/
│ ├── config.h
│ └── i2c_bus.h
│
└── lib/
└── ST7305_U8g2/
settings holds the runtime configuration in flash; portal serves the setup
web page. Fonts are compiled in from the U8g2 library, so no font files are
shipped.
All user-specific settings are entered on the display itself through a setup web page. Nothing needs to be edited or recompiled, and no credentials are stored in the repository.
On a phone or laptop, join:
Network: TempDisplay-Setup
Password: temp1234
The setup page should open by itself. If it does not, browse to
http://192.168.4.1.
Choose your Wi-Fi network from the list and enter its password.
Enter the outdoor temperature source URL and, for a JSON response, the field holding the value.
Check the timezone, then press Save and restart.
The display reboots, joins your network, sets its clock from NTP and begins showing data.
Once the display is on your network the same page is available at
http://temp-display.local or at the display's IP address. This is the place
to change the outdoor source without touching the Wi-Fi settings.
To return to the setup access point — after moving house, or changing the Wi-Fi password — hold the KEY button while powering the display on. Erase all settings on the page does the same thing.
| Setting | Notes |
|---|---|
| Wi-Fi network and password | Chosen from a scan, or typed in for a hidden network |
| Outdoor source URL | An HTTP address returning the outdoor temperature |
| JSON field | The field holding the value, e.g. temperature or main.temp. Blank if the response is a bare number |
| Time format | 24 hour (14:05) or 12 hour (2:05 PM) |
| Battery indicator | Whether to show the corner icon |
| Panel low-power mode | Lowers the screen's internal refresh rate |
| Sleep when dark | Whether to rest in an unlit room |
| Darkness threshold | In lux, with the live reading shown beside it |
| Quiet hours | Used only when no light sensor is fitted |
| Date format | Picked from a list, or given as a strftime pattern |
| Capitals | Whether the date line is upper case |
| Timezone | Picked from a list, or given as a POSIX TZ string |
| NTP server | Defaults to pool.ntp.org |
The time is shown either as 24 hour or as 12 hour with an AM/PM suffix. In
12-hour mode the leading zero is dropped, midnight is 12:00 AM and noon is
12:00 PM.
The date line is chosen from a list of common arrangements, or given directly
as a strftime(3) pattern:
| Pattern | Result |
|---|---|
%A %e %B |
MONDAY 24 AUGUST |
%A %e %B %Y |
MONDAY 24 AUGUST 2026 |
%B %e, %Y |
AUGUST 24, 2026 |
%a %e %b %Y |
MON 24 AUG 2026 |
%d/%m/%Y |
24/08/2026 |
%Y-%m-%d |
2026-08-24 |
The useful fields are %A day, %a short day, %B month, %b short month,
%e date, %d date padded to two digits, %Y year and %y short year.
The setup page shows a live preview of both lines, rendered by the display itself using the same code that draws the panel, so what the preview shows is what appears on screen. A long date is automatically set in a smaller size rather than being allowed to run off the edge.
Settings are held in the ESP32's own flash and survive both power loss and a firmware update.
Either form is accepted:
14.8
{ "temperature": 14.8 }
The setup page has a Test this source button that fetches the URL and reports the temperature it read, so a wrong address or field name can be corrected before saving.
The display is designed to run from the 18650 cell for as long as possible.
Because the panel is reflective, an unlit room is the cheapest possible time to stop working — the image already on screen stays there with no power at all.
Pressing KEY wakes the display at once.
The threshold is set in lux and has hysteresis, so a room hovering near the boundary cannot chatter the display in and out of sleep. With no light sensor fitted, the quiet hours are used instead — 23:00 to 06:00 by default.
Sleeping is suppressed for a minute after anyone uses the settings page, so the Wi-Fi is never dropped mid-configuration, and never happens at all while the setup access point is up.
The top right corner shows a four-bar battery icon, derived from a lithium-ion discharge curve rather than a straight voltage scale. It is deliberately coarse — it only has to answer "should I be thinking about charging" — and quantising it to quarters also means normal voltage noise causes no screen refresh. Below 25% the icon shows as an empty outline.
The setup page shows the exact voltage and percentage.
Potential future additions:
Screen brightness control is not possible on this board: the panel is reflective with no backlight to adjust.
The project should follow these principles:
The WaveShare board is particularly suited to this application because the RLCD provides a reflective display without a conventional backlight, while the board already includes the RTC and indoor temperature/humidity sensor required by the application.
Official documentation:
This project is released under the terms specified by the repository owner.