Files
fan4life/README.md
dtoro 079f2bcc9a docs: update README for PWM/MOSFET + level table, add secrets.h.example
Rewrite README to describe the 5-level temperature-driven PWM fan
control (replacing the old relay on/off description), and add a
secrets.h.example template so new clones have a reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 01:18:37 +02:00

145 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ESP32-C3 Fan Controller
An automatic server fan controller built on the ESP32-C3. Drives a 5 V fan over PWM through an IRLZ44N MOSFET, auto-selects fan speed from a temperature table with hysteresis, shows live status on an OLED, and publishes sensor/fan state to Home Assistant over MQTT.
## Features
- **Temperature-driven PWM fan control** — 5 discrete speed levels, selected automatically from the current temperature
- **Hysteresis** — 1 °C drop-down margin prevents level flapping
- **DHT22 sensor** — reads temperature and humidity every 3 s
- **SSD1306 OLED** — displays live temp, humidity, fan state, and level
- **MQTT publishing** — streams sensor and fan data for Home Assistant
- **WiFi** — connects on boot, auto-reconnects WiFi and MQTT if they drop
## Hardware
| Component | Details |
|---|---|
| Microcontroller | ESP32-C3 |
| Sensor | DHT22 (temperature + humidity) |
| Driver | IRLZ44N N-channel MOSFET (logic-level) |
| Fan | 2-wire 5 V fan |
| Display | SSD1306 128×64 OLED (I²C) |
## Wiring
| ESP32-C3 Pin | Connected To |
|---|---|
| `GPIO2` | DHT22 DATA (+ 4.7 kΩ pullup to 3V3) |
| `GPIO3` | MOSFET gate (via ~150 Ω) + 100 kΩ gate→GND pulldown |
| `GPIO5` (SDA) | OLED SDA |
| `GPIO6` (SCL) | OLED SCL |
| `3V3` | DHT22 VCC, OLED VCC |
| `GND` | DHT22 GND, OLED GND, MOSFET source, fan |
Fan wiring:
- Fan **+** → USB 5 V
- Fan **** → MOSFET **drain**
- MOSFET **source** → GND
- MOSFET **gate**`GPIO3`
## Configuration
Copy `main/secrets.h.example` to `main/secrets.h` and fill in your values:
```cpp
#define WIFI_SSID "your_wifi_ssid"
#define WIFI_PASS "your_wifi_password"
#define MQTT_HOST "192.168.1.X"
#define MQTT_PORT 1883
#define MQTT_USER "mqtt_user"
#define MQTT_PASS "mqtt_password"
#define MQTT_CLIENT "esp32c3_fan"
```
`secrets.h` is gitignored.
### Fan Level Table
Fan speed is selected from a table of (temperature threshold → PWM duty) in `main/main.ino`:
| Level | Temp ≥ | PWM duty (0255) |
|-------|--------|------------------|
| 0 (off) | — | 0 |
| 1 | 28 °C | 230 |
| 2 | 30 °C | 236 |
| 3 | 32 °C | 242 |
| 4 | 34 °C | 249 |
| 5 | 36 °C | 255 |
`TEMP_HYST` (default `1.0 °C`) controls the drop-down margin: the fan only drops a level once temperature falls this much below that level's threshold. Below level 1's threshold minus hysteresis, the fan turns off.
Tune `LEVELS[]` and `TEMP_HYST` in `main/main.ino` to match your thermal setup.
## MQTT Topics
All topics are publish-only (the firmware does not accept remote commands).
| Topic | Payload | Notes |
|---|---|---|
| `esp32c3_fan/temperature` | `23.5` | °C, every loop |
| `esp32c3_fan/humidity` | `41` | %, every loop |
| `esp32c3_fan/fan/state` | `ON` / `OFF` | retained |
| `esp32c3_fan/fan/speed` | `0`..`5` | current level, retained |
## Home Assistant Setup
Add to `configuration.yaml`:
```yaml
mqtt:
sensor:
- name: "Room Temperature"
unique_id: "esp32c3_temperature"
state_topic: "esp32c3_fan/temperature"
unit_of_measurement: "°C"
device_class: temperature
- name: "Room Humidity"
unique_id: "esp32c3_humidity"
state_topic: "esp32c3_fan/humidity"
unit_of_measurement: "%"
device_class: humidity
- name: "Server Fan Level"
unique_id: "esp32c3_fan_level"
state_topic: "esp32c3_fan/fan/speed"
binary_sensor:
- name: "Server Fan"
unique_id: "esp32c3_fan"
state_topic: "esp32c3_fan/fan/state"
payload_on: "ON"
payload_off: "OFF"
device_class: running
```
Restart HA after saving. Requires the **Mosquitto broker** add-on installed and running.
## Dependencies
Install via Arduino IDE Library Manager:
- [U8g2](https://github.com/olikraus/u8g2) — OLED display
- [DHT sensor library](https://github.com/adafruit/DHT-sensor-library) — DHT22
- [PubSubClient](https://github.com/knolleary/pubsubclient) — MQTT client
- WiFi (built-in with ESP32 board package)
## Project Structure
```
fan4life/
├── main/
│ ├── main.ino # Main sketch
│ ├── secrets.h # WiFi & MQTT credentials (gitignored)
│ └── secrets.h.example # Credentials template
├── cad/ # Mechanical / enclosure files
├── .gitignore
└── README.md
```
## License
MIT