1 / 5
Simple yet Effective and Invisible Smart Tilt Control for 50mm Wooden Blinds/ Shades (Hornbach/Soluna) with Servo — zdjęcie 1
1 / 5

Simple yet Effective and Invisible Smart Tilt Control for 50mm Wooden Blinds/ Shades (Hornbach/Soluna) with Servo

Zamów wydruk tego modelu

Obliczymy ostateczną cenę na podstawie wybranego pliku. Sprawdzisz ją i zaakceptujesz przed płatnością.

Zapisane na tym urządzeniu.

Servo & ESP32C3 Mount for Soluna 50mm Wooden Blinds / Shades sold by Hornbach – Simple Smart Tilt Control

Ocena
0 / 5
Polubienia
34
Pobrania
46
Wydruki
0
Wyświetlenia
702
Oceny
0

Aktualizacja u źródła:

Informacje o modelu

Źródło
Printables
Licencja
Creative Commons — Attribution — Noncommercial

Upgrade your (Hornbach) Soluna 50mm wooden blinds with this simple and effective servo mount for automated tilt control. Unlike setups that require stepper motors and controllers, this design leverages a widely available mini hobby servo (SG90/MG90S) servo, making it easy to control the open and closed positions. The servo can be directly connected to the ESP and controlled with (for example) ESPHome & Home Assistant. 

Possibly works for other brands as well, as long as the frame size is 35x55mm and the shaft position matches.

Features:

  • Tilt control

  • Compatible with MG90S or SG90 servos 

  • Integrated slot for an ESP32-C3, enabling wireless automation.

  • No stepper motor, no stepper controller—just a simple, effective servo solution.

  • Quick installation: No drilling or permanent modifications required. Simply remove the snap-fit pan/tilt mechanism.

  • Compact and discreet design, ensuring a clean look.

  • Precise control using the servo’s internal potentiometer—set open/closed positions with ease.

Limitations:

  • 180-degree rotation limits tilt range a little. However, it is sufficient to open and close the blinds, which was enough for my needs. 

    • I have made a version with transmission (gears) to increase tilt range - however the negative effect on torque did not result in a usable version yet

    • Potentially the servo can be modified to allow continuous rotation, however you would loose the precise position control

Print Recommendations:

  • Material: PETG or ABS for durability and UV/heat resistance.

  • Layer Height: 0.2mm for precision.

  • Infill: 20% or higher for strength.

  • Supports: May be needed for overhangs.

 

ESPHome code

globals:
  - id: shade_1_position
    type: float
    restore_value: true
    initial_value: '0.5'  # Midpoint

Output configuration for servo

output:

  • platform: ledc id: pwm_output pin: GPIO3 frequency: 50 Hz

Servo configuration

servo:

  • id: my_servo output: pwm_output min_level: 2.5% #2.5% max_level: 12.5% #12.5% auto_detach_time: 2s # Reduces power draw after movement transition_length: 2s

Sliders for controlling the servos in the web UI

number:

  • platform: template name: "Servo 1 Position" id: servo_position_1 min_value: -100 max_value: 100 step: 10 optimistic: true mode: slider restore_value: true set_action: then: - lambda: |- auto level = x / 100.0; id(my_servo).write(level); id(shade_1_position) = (level + 1.0) / 2.0; // Convert -1.0–1.0 to 0.0–1.0

cover:

  • platform: template name: "Shade" id: shade_1 open_action:
    • number.set: id: servo_position_1 value: 100 close_action:
    • number.set: id: servo_position_1 value: -100 stop_action:
    • number.set: id: servo_position_1 value: 0 position_action:
    • lambda: |- auto value = (pos - 0.5) * 200.0; // Map cover position (0.0-1.0) to servo position (-100 to 100) id(servo_position_1).publish_state(value); // This triggers the actual servo move ESP_LOGE("shade_1", "Servo position set via position_action: %.2f", value);
    • lambda: |- id(shade_1_position) = pos; // Track actual cover position (0.0–1.0) ESP_LOGE("shade_1", "Cover position set via position_action: %.2f", pos);
    • number.set: # This explicitly updates the servo position when cover position changes in Home Assistant id: servo_position_1 value: !lambda "return (pos - 0.5) * 200.0;" # Lambda to calculate the value as a float optimistic: true assumed_state: true has_position: true

Tagi