libraries/Matter/examples/MatterFan/README.md
This example demonstrates how to create a Matter-compatible fan device using an ESP32 SoC microcontroller.
The application showcases Matter commissioning, device control via smart home ecosystems, manual control using a physical button, and analog input for speed control.
| SoC | Wi-Fi | Thread | BLE Commissioning | PWM Pin | Status |
|---|---|---|---|---|---|
| ESP32 | ✅ | ❌ | ❌ | Required | Fully supported |
| ESP32-S2 | ✅ | ❌ | ❌ | Required | Fully supported |
| ESP32-S3 | ✅ | ❌ | ✅ | Required | Fully supported |
| ESP32-C3 | ✅ | ❌ | ✅ | Required | Fully supported |
| ESP32-C5 | ❌ | ✅ | ✅ | Required | Supported (Thread only) |
| ESP32-C6 | ✅ | ❌ | ✅ | Required | Fully supported |
| ESP32-H2 | ❌ | ✅ | ✅ | Required | Supported (Thread only) |
RGB_BUILTIN if defined, otherwise pin 2 (for controlling fan speed)BOOT_PIN by defaultMatterWi-Fi (only for ESP32 and ESP32-S2)Before uploading the sketch, configure the following:
Wi-Fi credentials (if not using BLE commissioning - mandatory for ESP32 | ESP32-S2):
const char *ssid = "your-ssid"; // Change to your Wi-Fi SSID
const char *password = "your-password"; // Change to your Wi-Fi password
DC Motor PWM pin configuration (if not using built-in RGB LED):
const uint8_t dcMotorPin = 2; // Set your PWM pin here
Analog input pin configuration (optional): By default, analog pin A0 is used for speed control. You can change this if needed.
const uint8_t analogPin = A0; // Set your analog pin here
Button pin configuration (optional):
By default, the BOOT button (GPIO 0) is used for the Fan On/Off manual control and factory reset. You can change this to a different pin if needed.
const uint8_t buttonPin = BOOT_PIN; // Set your button pin here
MatterFan.ino sketch in the Arduino IDE.Once the sketch is running, open the Serial Monitor at a baud rate of 115200. The Wi-Fi connection messages will be displayed only for ESP32 and ESP32-S2. Other targets will use Matter CHIPoBLE to automatically setup the IP Network. You should see output similar to the following, which provides the necessary information for commissioning:
Connecting to your-wifi-ssid
.......
Wi-Fi connected
IP address: 192.168.1.100
Matter Node is not commissioned yet.
Initiate the device discovery in your Matter environment.
Commission it to your Matter hub with the manual pairing code or QR code
Manual pairing code: 34970112332
QR code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A6FCJ142C00KA0648G00
Matter Node not commissioned yet. Waiting for commissioning.
Matter Node not commissioned yet. Waiting for commissioning.
...
Matter Node is commissioned and connected to the network. Ready for use.
Fan State: Mode OFF | 0% speed.
User button released. Setting the Fan ON.
Fan State: Mode ON | 50% speed.
Fan set to SMART mode -- speed percentage will go to 50%
Fan State: Mode SMART | 50% speed.
The user button (BOOT button by default) provides manual control:
The analog input pin (A0) allows manual speed adjustment:
Use a Matter-compatible hub (like an Apple HomePod, Google Nest Hub, or Amazon Echo) to commission the device.
The MatterFan example consists of the following main components:
setup(): Initializes hardware (button, analog input, PWM output), configures Wi-Fi (if needed), sets up the Matter Fan endpoint with initial state (OFF, 0% speed), and registers callbacks for state changes.loop(): Checks the Matter commissioning state, handles button input for toggling the fan and factory reset, reads analog input to adjust fan speed, and allows the Matter stack to process events.onChangeSpeedPercent(): Handles speed percentage changes (0% to 100%). Automatically turns fan on/off based on speed.onChangeMode(): Handles fan mode changes (OFF, ON, SMART, HIGH). Automatically sets speed to 50% when switching from OFF to another mode.onChange(): Generic callback that controls the DC motor via PWM and reports the current state.fanDCMotorDrive(): Drives the DC motor (or simulates it with RGB LED brightness) based on fan state and speed.Arduino IDE Menu -> Tools -> Erase All Flash Before Sketch Upload: "Enabled" or directly with esptool.py --port <PORT> erase_flashThis example is licensed under the Apache License, Version 2.0.