Skip to the content
PCBKitNew board
2 layers45 × 55 mmGarageVentilation v1, the printed circuit board in 3D

GarageVentilation v1

Joozd/GarageVentilation

GarageVentilation is a small DIY project that decides when ventilating a garage will actually help remove moisture.

Size
45 × 55 mm
Copper layers
2
Thickness
1.6 mm
Parts
5
Nets
22
Pads
34
Tracks, vias
33, 0
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
4 Nov 2026
Updated
4 Nov 2026

Overview

GarageVentilation v1 is an open-source printed circuit board by Joozd, from the Joozd/GarageVentilation repository on GitHub. It is a 2-layer board of 45 × 55 mm with 5 parts on 22 nets, routed with 33 tracks and 0 vias.

It is built around the IRLZ34N. Its parts include 2 connectors, 1 resistor, 1 IC and 1 transistor. It belongs with the ESP32 and RISC-V boards of this library.

Main components

1

README

README.md

GarageVentilation

Battery-powered, humidity-aware garage ventilation using an ESP32-C5, Bluetooth sensors and a 5 V fan.

GarageVentilation is a small DIY project that decides when ventilating a garage will actually help remove moisture. Instead of switching a fan on whenever the relative humidity is high, it compares the absolute humidity of the air inside and outside. The fan should run only when the garage is humid enough and the outside air contains sufficiently less water vapor.

The project combines an ESP32-C5, two existing Bluetooth sensors, a MOSFET-switched fan, and a rechargeable battery. It is being developed with PlatformIO and includes a custom PCB designed in KiCad.

Status: work in progress. BLE measurement decoding, ventilation decision logic, fan switching and sleep behavior are being developed and tested. This is a prototype, not a finished commercial device.

How it works

text
    SwitchBot (inside) ── BLE ──┐
                               │
                               ▼
                         ESP32-C5
                               ▲
                               │
    RuuviTag (outside) ── BLE ─┘
                               │
                     Compare humidity
                               │
                   Ventilation worthwhile?
                         /           \
                       yes            no
                        │              │
                   MOSFET → fan     Deep sleep
                        │
                    Light sleep
                        │
                  Measure again
  1. Scan Bluetooth advertisements from the indoor SwitchBot and outdoor RuuviTag.
  2. Decode temperature and relative humidity from both sensors.
  3. Calculate absolute humidity in g/m³.
  4. Start the fan if the indoor relative humidity is high enough and the indoor air contains sufficiently more moisture than the outside air.
  5. Use different start/continue thresholds (hysteresis) to avoid rapidly switching the fan on and off.
  6. Sleep between measurements to conserve battery power.

If a measurement cannot be obtained, the controller takes a conservative approach instead of assuming ventilation is useful. While ventilating, the current firmware allows one missed measurement cycle before stopping the fan.

Why absolute humidity?

Relative humidity alone is misleading when temperatures differ. Cold outside air can have a high relative humidity while containing less water vapor than warmer garage air. Once that outside air warms up in the garage, its relative humidity falls.

Comparing absolute humidity gives a better indication of whether exchanging the air will remove moisture. It does not guarantee that every surface will become drier immediately: surface temperature, condensation, airflow and moisture sources still matter.

Current control thresholds

These are experimental firmware settings, not universal recommendations:

ConditionStart ventilatingContinue ventilating
Minimum indoor relative humidity66%64%
Minimum indoor–outdoor absolute-humidity difference2.0 g/m³1.5 g/m³

Both conditions must be satisfied. The lower continuation thresholds provide hysteresis.

Hardware

ComponentPurpose
Seeed Studio XIAO ESP32-C5Microcontroller and BLE receiver
SwitchBot temperature/humidity sensorIndoor measurement via BLE advertisements
RuuviTagOutdoor temperature/humidity measurement via BLE RAWv2
5 V Noctua fanExhaust air from the garage
Logic-level N-channel MOSFETSwitch the fan from an ESP32 GPIO
Seeed LiPo Rider PlusRechargeable battery power and 5 V boost output
Single-cell Li-ion battery packPortable power source
Custom KiCad PCBMount and connect the electronics

Fan wiring (simplified)

text
5 V boost output ───────── Fan +
                           Fan − ─── MOSFET drain
ESP32 GPIO (D2) ────────── MOSFET gate
Ground ─────────────────── MOSFET source

The ESP32 and fan power supply must share a common ground. A suitable gate resistor and gate pull-down are part of the MOSFET control circuit. The fan is switched on the low side; it is not powered directly by an ESP32 GPIO.

The ESP32 is powered from the boost converter's 5 V output. Consult the XIAO ESP32-C5 and LiPo Rider Plus documentation before reproducing the power connections, particularly when combining external power and USB.

Battery safety: Use a protected battery pack and a charging/power board appropriate for its chemistry. Check polarity, current limits and mechanical protection before operating unattended.

Firmware architecture

The code is organized so that measurement collection, humidity decisions, hardware switching and sleep management have separate responsibilities.

text
main.cpp
  ├── MeasurementsScanner
  │     ├── BleScanner (NimBLE + FreeRTOS queue)
  │     ├── AdvertisementClassifier
  │     ├── RuuviDecoder
  │     └── SwitchbotDecoder
  ├── VentilationController
  ├── Fan
  └── sleep utilities
  • MeasurementsScanner gathers and decodes the two sensor measurements. It returns either a complete pair or no measurement.
  • BleScanner handles passive BLE scanning. Incoming advertisements are copied into a bounded FreeRTOS queue and processed by the main application task. Bluetooth is initialized at the start of each scan and deinitialized afterward, so it does not remain active during light sleep.
  • VentilationController decides whether ventilation is worthwhile using measurement data and configurable thresholds; it does not manipulate hardware.
  • Fan owns the output GPIO and controls the MOSFET, including GPIO hold so the output stays high during light sleep.
  • Sleep utilities put the controller into light sleep while ventilating or deep sleep when ventilation is not needed.

Deep sleep restarts the program on wake-up. Light sleep resumes execution where the program left off.

Building and flashing

The firmware uses C++, the Arduino framework, PlatformIO and NimBLE-Arduino.

  1. Install Visual Studio Code and the PlatformIO IDE extension.
  2. Open this repository as a folder in VS Code.
  3. Connect the XIAO ESP32-C5 over USB.
  4. In PlatformIO, select the seeed-xiao-esp32-c5 environment and build/upload the firmware.
  5. Open the serial monitor at 115200 baud for diagnostic output.

The project's platformio.ini defines the board, framework and library dependencies. Use the configuration committed with the code rather than copying settings from an older version of this README.

Power-saving approach

The prototype aims for a low average current draw rather than continuously operating the radio and fan:

  • Fan off: stop scanning, shut down Bluetooth and enter deep sleep until the next measurement cycle.
  • Fan on: keep the MOSFET gate asserted, shut down Bluetooth and use light sleep between measurement cycles.
  • After waking: initialize Bluetooth again for the next scan.

A fan duty cycle around 10% is an initial design target, not a measured long-term result. Actual battery life depends on fan runtime, battery capacity, boost-converter losses, measurement frequency and standby current. No runtime guarantee is made yet.

PCB and mechanical design

A custom PCB is designed in KiCad. The intent is to keep the electronics easy to assemble and allow the battery to sit in a separate, mechanically secured holder. The LiPo Rider Plus charging connection should remain accessible.

The repository can contain the PCB sources alongside the firmware, for example:

text
GarageVentilation/
├── src/
├── include/
├── lib/
├── hardware/
│   └── pcb/
│       ├── *.kicad_pro
│       ├── *.kicad_sch
│       └── *.kicad_pcb
├── platformio.ini
└── README.md

This layout is illustrative; the actual folder structure may evolve.

Project status / next steps

  • Decode RuuviTag BLE RAWv2 measurements
  • Decode SwitchBot temperature/humidity advertisements
  • Compare inside/outside absolute humidity
  • Drive the fan through a MOSFET
  • Test GPIO hold across light sleep
  • Design an initial PCB in KiCad
  • Verify reliable repeated BLE scans across sleep cycles
  • Validate long-term power consumption and battery runtime
  • Finish mechanical mounting and battery holder
  • Test control thresholds against real garage conditions
  • Document the finished wiring and add build photos

A note on scope

This is a purpose-built garage ventilator, not a general home automation platform. The design deliberately favors a small, readable firmware structure and a simple hardware interface over unnecessary abstraction.


Built as a practical electronics, embedded C++ and humidity-control learning project.

Parts

5
QtyValueFootprintReferences
11MResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P7.62mm_HorizontalR1
1Fan pin headerConnector:FanPinHeader_1x03_P2.54mm_VerticalJ2
1IRLZ34NPackage_TO_SOT_THT:TO-220-3_VerticalQ1
1Lipo_Rider_PlusGarageVentilation:LiPo_Rider_PlusJ1
1XIAO-ESP32-C5-DIPGarageVentilation:XIAO-ESP32-C5-DIP_mountU1

Questions

How big is the GarageVentilation v1 PCB?

It measures 45 × 55 mm and has 2 copper layers, 1.6 mm thick.

What parts does the GarageVentilation v1 use?

5 parts, built around the IRLZ34N. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the GarageVentilation v1 KiCad files?

From the Joozd/GarageVentilation repository on GitHub, at the commit this page was made from: the board is hardware/GarageVentilation_v1.kicad_pcb and its schematic hardware/GarageVentilation_v1.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the GarageVentilation v1 design in my own project?

Its repository states no licence, so its author keeps all rights: ask Joozd before reusing the design.

Similar boards

  • 2 layers100 × 50 mmEspled, the printed circuit board in 3D

    Espled

    Yottabits/espled

    THE one and only esp8266 LED Controller

    52 parts6
  • 2 layers224.8 × 60.3 mmDeurnode nieuw, the printed circuit board in 3D

    Deurnode nieuw

    Hans-Beerman/Deurnode_ESP32-PoE

    KiCad design Deurnode for the MakerSpace Leiden, based on the Olimex ESP32-PoE

    38 parts4Apache-2.0
  • 2 layers111.3 × 68.1 mmMKS relay v4, the printed circuit board in 3D

    MKS relay v4

    3D-Printing-for-Microfluidics/3D_printer_control

    2nd generation 3D printer control software

    67 parts3GPL-3.0
  • 2 layersWatch cleaner pcb, the printed circuit board in 3D

    Watch cleaner pcb

    DavidJ-Saving-Time/watch-cleaner

    So this is a very rough draft of code designed to run on an esp32 to control a watch cleaning machine see this YouTube video https://youtu.be/Opr75n8DbYY I'll be adding to this and making it easier for people to use.

    16 parts3MIT
  • 2 layers31.8 × 114.8 mm3DWelderPCB, the printed circuit board in 3D

    3DWelderPCB

    destroyer796/3DWelder

    An overbuilt 3D pen that will use a chc pro hotend and custom dc extruder powered by a power tool battery

    17 parts3MIT
  • 2 layers83.8 × 50.8 mmShunt charge controller, the printed circuit board in 3D

    Shunt charge controller

    grillbaer/solar-power-supply

    Solar power harvesting for micro controller projects with li-Ion battery and highly efficient charge controller

    16 parts3MIT
  • 2 layers80 × 45 mmWifiOiler01, the printed circuit board in 3D

    WifiOiler01

    volw/wifiOiler

    Automatic, distance depending chain oiler for motorbikes with track recording (GPS).

    15 parts3GPL-3.0
  • 2 layers80 × 20 mmSpider dropper, the printed circuit board in 3D

    Spider dropper

    aidtopia/spider_dropper

    Mechanism to "drop" a spider (or other lightweight prop) for Halloween fun

    10 parts2