Tag: Jaloezie

Automatische Jaloezie Aansturing

Automatische Jaloezie Aansturing

DIY Automatische Jaloezie Aansturing met ESP32, Steppermotor en 3D‑Geprinte Behuizing

Wil je je houten jaloezieën automatiseren zonder dure commerciële systemen?
In dit project bouwen we een volledig lokaal werkende jaloezie‑controller met:

  • een ESP32
  • een 28BYJ‑48 steppermotor
  • een ULN2003 driver
  • micro‑switches
  • een 3D‑geprinte behuizing
  • ESPHome + Home Assistant

Hieronder vind je alle onderdelen, de montage, foto’s van het project, schema’s en de volledige ESPHome‑YAML.


Benodigde onderdelen

Mechanisch

Elektronica


Fotoreportage van het project

Foto 1 – Tandwielmechanisme
Close‑up van het interne tandwiel van het jaloeziemechanisme. Dit is het deel waar de motor op aangrijpt.

Foto 2 – Steppermotor + tandwieloverbrenging
De 28BYJ‑48 motor gekoppeld aan het grote tandwiel van de jaloezie.

Foto 3 – Motor in montageframe
De motor zit stevig geklemd in de 3D‑geprinte houder.

Foto 4 – ULN2003 driverboard
Het driverboard dat de steppermotor aanstuurt.

Foto 5 – ESP32 module
De compacte ESP32 D1 mini die in de behuizing past.

Foto 6 – ESP32 bedrading
De bedrading naar de ULN2003 driver.

Foto 7 – Eindschakelaars
De micro‑switches voor handmatige bediening.

Foto 8 – Complete montage
Alle onderdelen gemonteerd in de 3D‑geprinte behuizing.


Elektrisch schema

[ESP32 D1 Mini]
 ├─ 5V  ───────────────→  [ULN2003] VCC
 ├─ GND ───────────────→  [ULN2003] GND
 ├─ GPIO22 ────────────→  [ULN2003] IN1
 ├─ GPIO21 ────────────→  [ULN2003] IN2
 ├─ GPIO17 ────────────→  [ULN2003] IN3
 └─ GPIO16 ────────────→  [ULN2003] IN4

[ULN2003]
 └─ Motor connector → 28BYJ‑48 Steppermotor

[ESP32 D1 Mini]
 ├─ GPIO26 ───────────→  Micro‑switch CW (NO)
 └─ GPIO18 ───────────→  Micro‑switch CCW (NO)

Micro‑switches:
 ├─ COM → GND
 └─ NO  → GPIO (26 of 18)

Mechanisch schema

[3D-geprinte behuizing]
 ├─ Kamer 1: Steppermotor (28BYJ‑48)
 │     └─ Motoras grijpt in het tandwiel van het jaloeziemechanisme
 │
 ├─ Kamer 2: ULN2003 driverboard
 │     └─ Motorstekker direct aangesloten
 │
 ├─ Kamer 3: ESP32 D1 Mini
 │     └─ JST-connector naar driverboard
 │
 └─ Zijkant: Micro-switch CW & CCW
       ├─ Roller raakt de handmatige bedieningshendel
       └─ Functie: handmatige bediening (links/rechts)

Overzichtsschema

[ESP32 D1 Mini]
        │
        ▼
[ULN2003 Driverboard]
        │
        ▼
[28BYJ‑48 Steppermotor]
        │
        ▼
[Jaloezie tandwielmechanisme]

Handmatige bediening:
[Micro-switch CW] ←─┐
[Micro-switch CCW] ←┘

Montage – stap voor stap

1. Print de behuizing

Alle onderdelen passen met support printen. PLA of PETG werkt prima.

2. Monteer de steppermotor

Schuif de motor in de houder en zorg dat het tandwiel goed grijpt.

3. Plaats de ULN2003 driver

Klik het board in de sleuf en verbind de motorstekker.

4. Monteer de ESP32

Verbind IN1–IN4 met de driver en sluit 5V + GND aan.

5. Monteer de micro‑switches

Deze worden gebruikt voor handmatige CW/CCW bediening.

6. Sluit alles aan

ESP32 → ULN2003 → motor → micro‑switches.

7. Upload de ESPHome firmware

Gebruik de YAML hieronder.

8. Automatische kalibratie

Bij elke reboot:

  • motor draait naar open‑positie
  • positie wordt op 0 gezet
  • motor draait naar half‑positie
  • positie wordt opnieuw op 0 gezet

ESPHome YAML (algemene versie)

# ============================================================
# JALOEZIE 
# Inclusief:
# - Absolute kalibratie bij opstart
# - 10s stabilisatietijd
# - Half-target instelbaar in Home Assistant (persistent)
# - Realtime positie & percentage
# - Software eindstops
# - Handmatige bediening (vasthouden = draaien)
# - Versie 20260220.1
# ============================================================
substitutions:
  name: stepper_blind
  blindname: "blind"
  friendly_name: "jaloezie"
  stepperid: ${name}

  calib_open_target: "36000"
  calib_half_target: "-18000"

  min_position: "-14000"
  max_position: "14000"

esphome:
  name: ${name}
  friendly_name: "${friendly_name}"

  on_boot:
    priority: -10
    then:
      - delay: 10s

      - lambda: |-
          if (id(calib_half_target_global) == 0) {
            id(calib_half_target_global) = ${calib_half_target};
          }

      - stepper.set_target:
          id: $stepperid
          target: ${calib_open_target}

      - wait_until:
          condition:
            lambda: 'return id($stepperid).current_position == ${calib_open_target};'

      - stepper.report_position:
          id: $stepperid
          position: 0
      - stepper.set_target:
          id: $stepperid
          target: 0

      - stepper.set_target:
          id: $stepperid
          target: !lambda return id(calib_half_target_global);

      - wait_until:
          condition:
            lambda: 'return id($stepperid).current_position == id(calib_half_target_global);'

      - stepper.report_position:
          id: $stepperid
          position: 0
      - stepper.set_target:
          id: $stepperid
          target: 0

esp32:
  board: esp32dev
  framework:
    type: esp-idf

globals:
  - id: calib_half_target_global
    type: int
    restore_value: true

stepper:
  - platform: uln2003
    id: $stepperid
    pin_a: GPIO22
    pin_b: GPIO21
    pin_c: GPIO17
    pin_d: GPIO16
    max_speed: 500 steps/s
    sleep_when_done: true


cover:
  - platform: template
    name: $blindname
    id: ${blindname}
    has_position: true
    device_class: blind

    open_action:
      - stepper.set_target:
          id: $stepperid
          target: ${max_position}

    close_action:
      - stepper.set_target:
          id: $stepperid
          target: ${min_position}

    stop_action:
      - stepper.set_target:
          id: $stepperid
          target: !lambda return id($stepperid).current_position;

    # SET POSITION action verkeerd om
#    position_action:
#      - lambda: |-
#          float target = (1.0 - pos) * (float(${max_position}) - float(${min_position})) + float(${min_position});
#          id($stepperid).set_target((int)target);

    position_action:
      - lambda: |-
          // percentage van HA → stepper positie (nu omgedraaid)
          float target = pos * (float(${max_position}) - float(${min_position})) + float(${min_position});
          id($stepperid).set_target((int)target);


    # Cover slider in HA → 0–1.0
    lambda: |-
      float percent = id(position_percent).state;
      return percent / 100.0;


sensor:
  - platform: template
    name: "$blindname Position"
    id: position
    accuracy_decimals: 0
    update_interval: 200ms
    lambda: |-
      return (int) id($stepperid).current_position;
    filters:
      - delta: 10

  - platform: template
    name: "$blindname Percentage"
    id: position_percent
    unit_of_measurement: "%"
    accuracy_decimals: 0
    update_interval: 200ms
    lambda: |-
      float pos = id($stepperid).current_position;
      return (int)((1.0 - ((pos - ${min_position}) / (float(${max_position}) - float(${min_position}))))) * 100.0;
    filters:
      - delta: 1.0

number:
  - platform: template
    name: "${blindname} Calib Half Target"
    id: calib_half_target_number
    min_value: -50000
    max_value: 50000
    step: 100
    restore_value: true
    on_value:
      then:
        - lambda: |-
            id(calib_half_target_global) = (int)x;

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

logger:
ota:
api:

Conclusie

Met deze 3D‑geprinte behuizing, goedkope componenten en ESPHome heb je een
professionele jaloezie‑automatisering die volledig lokaal werkt en perfect integreert met Home Assistant.

Is er iets niet duidelijk, laat het gerust weten.

Loading