AirDimmer is an intuitive, mid-air gesture controller for smart home lighting. Using a VL53L1X Time-of-Flight sensor and an ESP32, it enables precision brightness control through simple hand movements—eliminating the need for physical switches or buttons.
AirDimmer transforms the space above it into a seamless dimming surface.
- Hand Detection: The high-precision ToF sensor detects your hand entering the active zone.
- Intuitive Dimming: Your hand's vertical position directly maps to light intensity. Raise to brighten, lower to dim.
- Visual Feedback: The integrated web-dashboard provides a real-time "mirror" of your actions, showing the exact distance and the resulting brightness change.
- Instant Response: The system automatically increases its polling frequency ("Fast Polling") as soon as you bring your hand near, providing a zero-lag experience.
- Safety Thresholds: Configure exact boundaries to ensure reliable detection.
- Invertible Control: Choose the direction of control:
- Standard: Closer = Brighter, Further = Dimmer.
- Inverted: Further = Brighter, Closer = Dimmer.
- Sensitivity Control: Adjust the response scaling (1x, 2x, or 3x divider).
- Persistent Calibration: Self-calibrates to the mounting surface on boot, ensuring reliable performance in different environments.
- MQTT-Native: Works out of the box with Home Assistant, Node-RED, and other MQTT brokers.
- Armed Safety: Explicit "Armed" toggle to enable/disable light control while keeping the sensor active for monitoring.
- Hostname Discovery: Reachable anywhere on your network at
http://airdimmer-(suffix).local.
- Configure your WiFi and MQTT credentials in
network_information.h. - Flash the device via USB or OTA.
- Navigate to
http://airdimmer-setup.localto begin calibration and setup.
AirDimmer is optimized for the VL53L1X Time-of-Flight (ToF) sensor. Development and testing were primarily conducted using the SparkFun Distance Sensor. While other VL53L1X-based modules (such as the Pololu VL53L1X) are likely compatible due to the common chipset, they have not been personally tested.
Connect the sensor to your board via the I2C interface.
The ESP32 is the preferred platform due to its robust WiFi performance and native MQTT support.
| ESP32 Pin | Sensor Pin | Description |
|---|---|---|
| 3V3 | VIN | Power Supply (3.3V) |
| GND | GND | Common Ground |
| GPIO 21 (SDA) | SDA | I2C Data Line |
| GPIO 22 (SCL) | SCL | I2C Clock Line |
It is also possible to use an ESP8266 (e.g., NodeMCU or Wemos D1 Mini) with the following typical pinout:
| ESP8266 Pin | Sensor Pin |
|---|---|
| 3V3 | VIN |
| GND | GND |
| D2 (SDA) | SDA |
| D1 (SCL) | SCL |
For 5V boards like the Arduino Uno, Leonardo, or Mega:
| Arduino Pin | Sensor Pin |
|---|---|
| 5V | VIN |
| GND | GND |
| SDA | SDA |
| SCL | SCL |
Important
To use MQTT and Web features, you must use a WiFi-enabled board like the ESP32 or ESP8266.
To control your lights, you can use the following Home Assistant automation. It listens for brightness changes and syncs the current light state back to AirDimmer.
trigger:
- platform: mqtt
topic: "AirDimmer/setup/brightness_change" # <--- Change 'setup' to your device suffix
action:
- service: light.turn_on
target:
entity_id: light.test_airdimmer # <--- Your light entity ID
data:
brightness_step_pct: "{{ trigger.payload | float }}"
- service: mqtt.publish
data:
topic: "AirDimmer/setup/receiver" # <--- Change 'setup' to your device suffix
payload: "{{ state_attr('light.test_airdimmer', 'brightness') }}"Important
light.test_airdimmer: Replace this with the entity ID of the light you want to control.- MQTT Topic: Ensure the
(suffix)(default issetup) in the topic matches the hostname suffix configured in your AirDimmer settings.
AirDimmer uses a structured MQTT hierarchy. The (suffix) defaults to setup until changed.
| Topic | Direction | Description |
|---|---|---|
AirDimmer/(suffix)/brightness_change |
Publish | Sends the relative change (e.g., -5.5, +12.0) to adjust light intensity. |
AirDimmer/(suffix)/distance |
Publish | Sends raw distance measurements (in cm) when enabled in settings. |
AirDimmer/(suffix)/receiver |
Subscribe | Listens for commands (threshold_calibration) or brightness sync (values 0-255). |
While designed for hands-free use, AirDimmer includes a Web Suite for setup:
- Responsive Control: Full setup via any phone or desktop browser.
- Themes: Light and sophisticated Dark Gray modes.
- Localization: Native English (UK) and Italian support.
- Microcontroller: ESP32
- Sensor: ST VL53L1X (Time-of-Flight)
- Connectivity: WiFi, MQTT, mDNS, ArduinoOTA
- Persistence: EEPROM (Store thresholds, sensitivity, and naming)
- Sensor not found: Check your I2C wiring (SDA/SCL). Ensure the sensor is powered (3.3V/VIN).
- MQTT Disconnected: Verify your credentials in
network_information.hand ensure your broker is reachable from the ESP32's IP. - No Dimming: Check if the device is "Armed" via the web dashboard.
This is a v1.0 experimental project. While functional, it is provided "as is" without warranty of any kind. Always maintain physical access to your light switches and use this project at your own risk.
Feel free to fork the repo and create a pull request if you have improvements. You can also open an issue for bugs or feature requests.
3D printed case designs (STL/CAD files) are particularly helpful to the project.
Distributed under the MIT License. See LICENSE for more information.
