ESP32-S3 room air monitor
An SCD40 sensor measures the room's CO2, temperature and humidity, and a 20x4 screen shows them. Three LEDs say when to open the window: green below 1000 ppm, yellow up to 1500, red above. Stale air makes you tired long before you notice it.
The program
Chip BASIC: every line is one instruction you can read and change. The compiler checks it at every release of the site.
REM Aria della stanza
REM @part aria = scd40
REM @part schermo = lcd2004
10 schermo(0) = "Aria della stanza"
20 schermo(1) = "CO2 ppm ", aria.CO2
30 schermo(2) = "Temp C ", aria.TEMP
40 schermo(3) = "Umid % ", aria.HUM
50 LED green, off : LED yellow, off : LED red, off
60 IF aria.CO2 < 1000 THEN LED green, on
70 IF aria.CO2 >= 1000 AND aria.CO2 < 1500 THEN LED yellow, on
80 IF aria.CO2 >= 1500 THEN LED red, on
90 WAIT 5s
100 GOTO 20What you should see: the screen shows CO2 in ppm, temperature and humidity, refreshed every 5 seconds; one LED at a time, green, yellow or red by the CO2. In the simulator move the CO2 slider above 1500 and the red LED lights.
▶ Open it in the IDEIn the simulator you see the logic run right away, with no hardware. The simulator does not check the wires: you check those on the board, and the IDE's wiring check walks you through it.
The parts
The compiler finds the parts in the program. Each has its own page with a test program to run before you build the whole thing.
- 3 × LED (with resistors: 220 Ω, or 470 Ω on the UNO R4)
- SCD40 CO2 sensorMeasures the air's CO2 in ppm: tells when the room needs airing.
- 20x4 I2C LCD screenA backlit character screen, four rows of 20: for a small terminal.
How to wire it to the ESP32-S3
- + red → ESP32-S3: GPIO4Through a 220 Ω resistor
- + yellow → ESP32-S3: GPIO2Through a 220 Ω resistor
- + green → ESP32-S3: GPIO1Through a 220 Ω resistor
- − → ESP32-S3: GNDCommon ground: this link is mandatory.
- LV1 → ESP32-S3: GPIO38The shifter carries the board's bus (3.3 V, LV side) to the screen's 5 V (HV side): 5 V never reaches the board's pins
- LV2 → ESP32-S3: GPIO39
- LV → ESP32-S3: 3V3
- GND → ESP32-S3: GNDCommon ground: this link is mandatory.
- HV → ESP32-S3: 5V
- schermo: SDA → I2C level shifter: HV1The screen goes only on the shifter's HV side (5 V), never on the board's pins
- schermo: SCL → I2C level shifter: HV2
- schermo: VCC → I2C level shifter: HV
- schermo: GND → I2C level shifter: GND
- SDA → ESP32-S3: GPIO38The sensor bus: every I2C module shares these two pins
- SCL → ESP32-S3: GPIO39
- VCC → ESP32-S3: 3V3
- GND → ESP32-S3: GNDCommon ground: this link is mandatory.
If it does not work
- The lights: the program runs but nothing happens
- The LED is the wrong way round, or the series resistor is missing. The long leg goes on the board pin's side, the short one towards GND, with the resistor in between (220 Ω, or 470 Ω on the UNO R4).
What you can change
The limits are lines 60 to 80: 1000 and 1500 ppm are common advice for a room. Ask the assistant to beep when it turns red, or to send the readings to the phone and see them over the day.
Which boards it works on
- ESP32-S3 Freenove: yes
- Nordic nRF54LM20 DK: no: one of its parts does not run on this board yet
- Arduino UNO R4 WiFi: yes