Skip to main content
Nastrotek
IoT SolutionsIoT SolutionsNew

A camera-free desk clock that indicates sleep quality

Notes for an ESP32 bedside clock that uses CO2, temperature, light, and bed presence to explain why a night felt off, without putting a camera in the bedroom.

Share

LinkedInFacebookX
A hand reviewing a sleep environment score on a camera-free DIY bedside clock in the morning

As you build it, I would treat every score as a prompt for reflection rather than a medical conclusion.

Some mornings I wake up tired and cannot tell why: the room was stuffy, the air conditioner ran a little warm, light leaked through the curtains, or I simply went to bed too late. I want a bedside clock that records a few of those clues so the next morning I can see what to fix first.

The boundary for me is a camera in the bedroom. This project does not try to watch anyone sleep. It combines simple room and bed signals, then shows a reference indicator in the morning. It does not measure REM, claim to identify deep sleep, or diagnose sleep apnea.

What can the clock honestly know?

SignalReasonable observation
CO2, temperature, humidityWhether the room became stuffy, warm, or humid relative to its normal baseline
LightWhether the room was dark at bedtime and when morning light arrived
Sound levelHow many periods rose noticeably above the room's normal noise floor
Under-bed FSRBedtime, bed exits, and total time in bed
Seven-day historyWhether bedtime and wake time stayed consistent

An FSR cannot tell whether I am awake or asleep. A noise spike cannot prove that it woke me. The display should therefore say “Sleep conditions” or “Last night indicator,” not claim “3 hours 20 minutes of deep sleep.”

An ESP32-S3, e-paper display, SCD41, light sensor, MEMS microphone, encoder, and 3D-printed clock enclosure on a workbench.

Version one should measure a few clear signals: CO2, temperature, humidity, light, sound level, and bed occupancy.

Hardware for version one

  • ESP32-S3, preferably with PSRAM for a larger interface.
  • SH1107 128 x 128 OLED or a 2.9-inch e-paper display. OLED is easier for a continuous clock; e-paper is gentler but not suited to per-second updates.
  • SCD40/SCD41 for CO2, temperature, and humidity.
  • BH1750 for room illuminance.
  • I2S MEMS microphone or analog sound-level board, used only for local noise calculation.
  • Pushable rotary encoder for score details and alarm settings.
  • A separate ESP32 node with one or two FSR strips under a bed slat.
  • A printed enclosure with sensor vents, keeping ESP32 heat away from the SCD41 airflow.

For the smallest build, leave out the microphone and bed sensor. The clock can still review bedroom conditions and lights-out consistency. That score contains less information, but it is easier to trust than an overambitious algorithm.

A score that can explain itself

I would start with a deliberately simple formula:

40 points: CO2, temperature, humidity, darkness, and noise
35 points: total time with the bed occupied
15 points: extended bed-exit events
10 points: seven-day bedtime consistency

The thresholds should not be universal. Record roughly one week, mark the nights that felt reasonably good, and use those as a personal baseline. An air-conditioned room, an open-window room, and a bedroom shared by two people will produce very different CO2 and temperature curves.

The score must also include a reason. 72 - room became stuffy after 02:10 is more useful than an unexplained orange ring.

ESPHome room-sensor outline

The basic sensor configuration stays short:

i2c:
  sda: GPIO8
  scl: GPIO9

sensor:
  - platform: scd4x
    measurement_mode: low_power_periodic
    co2:
      name: "Bedroom CO2"
    temperature:
      name: "Bedroom Temperature"
    humidity:
      name: "Bedroom Humidity"

  - platform: bh1750
    name: "Bedroom Illuminance"
    update_interval: 60s

Home Assistant can calculate the final value because it needs overnight history. The clock only receives sleep_condition_score and one short reason. If Home Assistant is offline, time and alarms should continue locally; the morning screen can simply say that there was not enough data.

A camera-free sleep indicator clock on a nightstand with an extremely dim display while someone sleeps.

At night, keep only a very dim clock or turn the display off; the indicator score can wait until morning.

Privacy is more than removing a camera

For the microphone, firmware should calculate RMS/dB over a short window and discard the audio samples. It should never save a file, stream sound, or expose a playback API. A physical switch that cuts microphone power makes this behavior visible and verifiable.

Data can stay on the local network through ESPHome and Home Assistant. The clock face should show only the summary score, especially when it sits somewhere other people can easily see it.

My first MVP

  1. Use SOAS for the clock, retaining its encoder and night display behavior.
  2. Add an SCD41 and BH1750, then record seven nights before deciding thresholds.
  3. Build a one-side FSR node with delayed_on and delayed_off so turning over does not create false events.
  4. Start with only time in bed, average CO2, and minutes with excessive light.
  5. Each morning, press a simple “fine/not fine” button to tune the personal baseline.

The thing I want to test is not a perfect sleep score. I only need it to say something honest: CO2 stayed high after 02:10, morning light arrived earlier than usual, or time in bed was shorter than last week. If that helps me change one small habit tonight, the clock has earned its spot.

References

Share

LinkedInFacebookX

Keep exploring

Read next

Related articles

View more in IoT Solutions

Nastrotek uses cookies for analytics and ad personalization to help us understand how the site is used. You can accept or decline non-essential cookies.