Control window blinds/curtains with voice commands using DC motor or stepper motor.
- ESP32 board
- DC motor or stepper motor
- Motor driver (L298N, L293D, or DRV8825 for stepper)
- External power supply (12V for most motors)
- Manual control buttons (optional)
ESP32 GPIO25 → IN1 (Motor direction)
ESP32 GPIO26 → IN2 (Motor direction)
ESP32 GPIO27 → ENA (Motor enable)
ESP32 GND → GND
L298N OUT1 → Motor +
L298N OUT2 → Motor -
L298N +12V → External 12V supply
L298N GND → Power supply GND + ESP32 GND (common ground)
Buttons:
ESP32 GPIO32 → UP button → GND
ESP32 GPIO33 → DOWN button → GND
ESP32 GPIO0 → STOP button (BOOT) → GND
- Variable position control 0-100% (0=closed, 100=open)
- Automatic motor control with position tracking
- Manual buttons (up/down/stop)
- Smooth movement to target position
- Position reporting to SinricPro
cd examples/blinds
idf.py build flash monitorEdit main/blinds_example.c - update WiFi and SinricPro credentials.
IMPORTANT: Calibrate travel time for your blinds:
#define FULL_TRAVEL_TIME_MS (10000) /* Adjust: Time from fully closed to fully open */To calibrate:
- Measure time for full open→close cycle
- Set FULL_TRAVEL_TIME_MS to this value
- Test accuracy, adjust if needed
- "Alexa, open the blinds"
- "Alexa, close the blinds"
- "Alexa, set blinds to 50 percent"
- "Alexa, open the blinds halfway"
- Pros: Simple, cheap
- Cons: No position feedback, relies on timing
- Use with: L298N, L293D
- This example uses timing-based position estimation
- Pros: Precise position control, no drift
- Cons: More expensive, noisier
- Use with: DRV8825, A4988
- Modify code to use step counting instead of timing
- Pros: Built-in position control
- Cons: Limited rotation (180° max)
- Use for: Small blinds, shutters
- See examples/lock for servo code
This example uses time-based estimation:
- Tracks motor runtime to estimate position
- Works well for consistent loads
- May drift over time (periodic recalibration recommended)
For better accuracy, add:
- Limit switches (detect fully open/closed)
- Rotary encoder (measure actual rotation)
- Current sensor (detect motor stall)
IMPORTANT: Motorized blinds can be dangerous.
- Obstruction Detection: Add current sensing to detect obstructions
- Limit Switches: Prevent over-travel
- Thermal Protection: Motor drivers can overheat
- Manual Override: Always provide manual operation method
- UP: Move to fully open (100%)
- DOWN: Move to fully closed (0%)
- STOP: Stop at current position
-
Motor Selection:
- Calculate blind weight
- Choose motor with 2-3x torque margin
- Consider gearing for heavy blinds
-
Mounting:
- Secure motor to wall/ceiling
- Ensure smooth pulley/cord system
- Test for binding or friction
-
Power Supply:
- Size for motor current + margin
- Use adequate gauge wire
- Common ground is essential
- Motor doesn't move: Check power supply, wiring polarity
- Wrong direction: Swap IN1/IN2 connections
- Position drift: Recalibrate FULL_TRAVEL_TIME_MS
- Erratic movement: Check common ground connection
- Motor stalls: Increase voltage or reduce load
Consider adding:
- Scheduling: Open at sunrise, close at sunset
- Light sensor: Automatic control based on sunlight
- Group control: Control multiple blinds together
- Privacy mode: Automatically close at night
This example can be adapted for:
- Curtains: Horizontal track systems
- Roller shades: Tube motor systems
- Venetian blinds: Tilt angle control
- Shutters: Open/close control
Add limit switches for accurate calibration:
#define LIMIT_OPEN_GPIO (34)
#define LIMIT_CLOSED_GPIO (35)
void check_limit_switches() {
if (!gpio_get_level(LIMIT_CLOSED_GPIO)) {
blinds_position = 0; /* Recalibrate at closed */
set_motor_direction(MOTOR_STOP);
}
if (!gpio_get_level(LIMIT_OPEN_GPIO)) {
blinds_position = 100; /* Recalibrate at open */
set_motor_direction(MOTOR_STOP);
}
}Typical DC motor blinds:
- Motor: 1-3A @ 12V during movement
- Idle: <50mA
- ESP32: ~150mA
Use appropriate power supply (recommend 12V 3A minimum).