Smart lock using DC motor with encoder

I created this smart lock for my door which is using 3D printed material to mount onto the door.
The idea is that a key is permanently inserted into the door and the motor is attached to it. Several components are required to achieve this:

  • ESP32s
  • DC Worm Motor with Encoder (Rated Torque: >8kg.cm)
  • L9110S Motor Driver
  • Power supply

This shows how the electronics are connected:

The model that attaches to the door and motor can be found here and this is a preview:

ESPHome was used for controlling the motor. It creates two buttons on Home Assistant which are to control the motor for Unlock and Lock. The motor stops automatically after 5 seconds, but it also stops when the key cannot turn any further.

esphome:
  name: smartlock
  platform: ESP32
  board: nodemcu-32s

wifi:
  ssid: mywifi
  password: mypassword

# Enable logging
logger:

# Enable OTA updates
ota:

# Enable Home Assistant API
api:

globals:
   - id: is_locked
     type: bool
     restore_value: yes
     initial_value: 'true'

binary_sensor:
  - platform: template
    name: "Is locked"
    lambda: "return id(is_locked);"

switch:
- platform: gpio
  pin: GPIO26  # Signal Out: Rotates the motor
  interlock: &interlock [turn_right, turn_left]
  name: Unlock
  id: turn_right
  on_turn_on:
  - script.execute: unlock_until_time
  on_turn_off:
  - globals.set:
      id: is_locked
      value: 'false'
- platform: gpio
  pin: GPIO27  # Signal Out: Rotates the motor
  interlock: *interlock
  name: Lock
  id: turn_left
  on_turn_on:
  - script.execute: lock_until_time
  on_turn_off:
  - globals.set:
      id: is_locked
      value: 'true'
  

sensor:
  - platform: rotary_encoder
    name: "Rotary Encoder"
    id: motor_encoder
    pin_a: GPIO15  # Signal In: The motor step
    pin_b: GPIO13  # Signal In: The motor rotation
    on_value:
      then:
        - script.execute: stop_at_the_end

script:
  - id: unlock_until_time
    mode: restart
    then:
      - delay: 5s  # Change this
      - switch.turn_off: turn_right
  - id: lock_until_time
    mode: restart
    then:
      - delay: 5s  # Change this
      - switch.turn_off: turn_left
  - id: stop_at_the_end
    mode: restart
    then:
      - delay: 200ms
      - switch.turn_off: turn_right
      - switch.turn_off: turn_left
3 Likes

Excellent project! Thanks for sharing. Do you have a picture or video of the final product?

I haven’t actually printed the model I posted on this thread, but I printed a previous version which was used on a smaller motor. This was not powerful enough to turn the key, only 5.6kg/cm.

The print was really good and stable, but a friend of mine helped me make a wooden one so instead of printing the one I posted, I used the wooden one.

This is how everything is connected:

This video shows how it works with Home assistant, though I am currently using a lock template to unlock and lock.

And this is the actual project:

2 Likes

This new version checks works with doors that use latch. It opens the door with the latch and after 5 seconds it gets restored. I am using an external device connected with a magnetic sensor which checks when the door closes. In that case it locks all the way.

esphome:
  name: smartlock
  platform: ESP32
  board: nodemcu-32s

wifi:
  ssid: mywifi
  password: mypassword

# Enable logging
logger:

# Enable OTA updates
ota:

# Enable Home Assistant API
api:

globals:
  - id: is_locked
    type: bool
    restore_value: yes
    initial_value: 'true'

binary_sensor:
  - platform: template
    name: "Is locked"
    lambda: "return id(is_locked);"
  - platform: gpio
    id: button_inside
    pin:
      number: GPIO23
      mode: INPUT_PULLUP
      inverted: True
    on_click:
      then:
        - switch.turn_on: unlock

switch:
- platform: gpio
  pin: GPIO26
  interlock: &interlock [unlock, lock]
  name: Unlock
  id: unlock
  on_turn_off:
  - globals.set:
      id: is_locked
      value: 'false'
- platform: gpio
  pin: GPIO27
  interlock: *interlock
  name: Lock
  id: lock
  on_turn_on:
  - script.execute: lock_until_time
  on_turn_off:
  - globals.set:
      id: is_locked
      value: 'true'

sensor:
  - platform: rotary_encoder
    id: motor_encoder
    pin_a: GPIO15
    pin_b: GPIO13
    on_value:
      then:
        - script.execute: stop_at_the_end

script:
  - id: lock_until_time
    mode: restart
    then:
      - delay: 3s
      - switch.turn_off: lock
  - id: stop_at_the_end
    mode: restart
    then:
      - delay: 200ms
      - if:
          condition:
            switch.is_on: unlock
          then:
            - script.execute: open_latch
      - switch.turn_off: lock
      - switch.turn_off: unlock
  - id: open_latch
    mode: restart
    then:
      - delay: 5s
      - switch.turn_on: lock
      - delay: 500ms
      - switch.turn_off: lock

Hola me ha encantado tu proyecto y es justo lo que estaba buscando creo que solo tengo una duda que voltaje tiene que ser el motor ya que me estoy haciendo una lista de los componentes para comprarlos.

Muchas gracias

hi, I don’t understand Spanish, but with google translate I got it.
The voltage of the motor and the RPM don’t matter, as long as it has the necessary torque to turn the key.
The more RPM you have, the faster the lock will be and lower the RPM.

Perdona no se hablar bien ingles

mi duda es sobre como alimento el motor ya que el esp32 creo que funciona con 5v?
si me puedes ayudar ya que tengo la impresora 3d y me gustaria mucho poder hacerlo gracias y perdona no poder hablar en ingles :pray: :sweat:

el L9110S es alimentado por el esp32? me podria decir cual es su motor y comprare el mismo ?gracias

I don’t think that you can find a motor with 5v that is powerful enough to turn the key. If you see the diagram, the red and purple wires are 9v-24v based on the requirements of your motor. The motor is powered through the L9110S driver which is controlled by ESP32.

1 Like

me podria decir cual es su motor y comprare el mismo? gracias

I bought this one:

I bought the 24V 60RPM, but anything with more than 8kg.cm will be fine.

If you are interested on another take on a Smart Lock, check out this new thread that I wrote:

Very very good project!!!
Where find I the firmware to upload on esp32s?

You need to install ESPHome and configure it using the YAML i’ve posted.

1 Like

Thanks a lot for your answer…
From your 3d project I don’t understand where you positioning the esp32s etc ect components. Is it possible to attach a real photo to understant the components location?

There is no place on the 3D print for the components because I don’t have it near the lock.
I’ve extended the cables around the door and I have them installed on a box on the wall.
I no longer use this lock so I can’t show you pictures. I am using another type of lock: Smart Lock with Gears

@bkbilly how does esp home check if the key cant turn further? Its not clear to me from the yaml code… building my own smart lock right now and found your post… thank you!

I haven’t implemented a stop action on my YAML.
I believe with the help of the rotary encoder, this could be possible.

Oh ok, so this feature is not included (as you have written) that it stops when the key cannot turn any further? Or do I get it wrong somehow? I try to archive the same at the moment…

I couldn’t remember exactly how it works because it’s almost 3 years that I last used this.
By investigating the configuration further, I figured it out.

The rotary_encoder triggers the script stop_at_the_end, but it waits for 200ms.
This is done on any change on the encoder value which restarts the script, so it won’t continue with turning of the rotation of the motor.
Once the encoder stops getting new values, the script will have the time (200 milliseconds) to continue and stop the movement of the motor.

Hope this makes this clear.