Servo motor wont work in ESPhome

Im trying to get a Servo motor to function and from what i can tell i did the code correct. can someone tell me where im going wrong?
its for a smart air vent cover
im using a ESP8266
heres the code on that:

esphome:
  name: smart-vent

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  services:
    - service: control_servo
      variables:
        level: float
      then:
        - servo.write:
            id: my_vent
            level: !lambda 'return level / 100.0;'

ota:
  password: "********************************"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Smart-Vent Fallback Hotspot"
    password: "*********************"

captive_portal:
 
   
servo:
  - id: my_vent
    output: pwm_output
        
    
output:
  - platform: esp8266_pwm
    id: pwm_output
    pin: D3
    frequency: 50 Hz

heres what i have in the configuration.yaml file:

input_number:
  servo_control:
    initial: 0
    min: -100
    max: 100
    step: 1
    mode: slider
    

and heres what i have in the automation.yaml file:

- id: smart-vent_servo
  alias: write servo value to esp
  trigger:
    platform: state
    entity_id: input_number.servo_control
  action:
    - service: esphome.smart-vent_control_servo
      data_template:
      level: '{{ trigger.to_state.state | int }}'

any help would be appreciated. im using a SG90 servo ( the basic hobby servo)
i can confirm its not the hardware as i test both usin arduino code and it worked fine.

thanks

1 Like

Maybe change this:

To this:

esphome:
  name: esp01s_doorbell
  platform: ESP8266
  board: d1_mini

I will share my working version for ESP32. I did it with feedback and brought out the servo position sensor, and also added the start and end positions. These positions are needed when we know exactly the starting and ending positions, by setting these values and using the switch we can already set the desired positions. The slider is needed to control the servo and find the desired position. Implemented memorize the last position of the servo. If the board is de-energized and the voltage is applied, the position will be restored

image

esphome:
  name: servo_smartbath

esp32:
  board: esp32dev
  framework:
    type: arduino

#Wi-Fi credentials for connecting the board to the home network
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: on

#If there is no connection with WiFi, then the access point will rise
  ap:
    ssid: !secret ap_esp_ssid
    password: !secret ap_esp_password

#Web server
web_server:
  port: 80

#Logging
logger:


#OTA и API
ota:
  password: "esphome"
api:
  password: "esphome"
  services:
   - service: control_servo
     variables:
       level: float
     then:
       - servo.write:
           id: servo_control
           level: !lambda 'return level / 100.0;'
       - sensor.template.publish:
           id: servo_sensor
           state: !lambda 'return (float)level;'

#Output Platform
output:
  - platform: ledc
    id: pwm_output
    pin: 13
    frequency: 50 Hz

#Configuration variables: Output (required, ID): ID of the output component to be used for this servo
servo:
  - id: servo_control
    output: pwm_output
    auto_detach_time: 0s
    transition_length: 5s

#Sensors
sensor:
#WiFi Signal Sensor
  - platform: wifi_signal
    name: gateway wifi signal
    update_interval: 30s
    unit_of_measurement: "dBa"
    accuracy_decimals: 0

#Servomotor position sensor
  - platform: template
    name: servo sensor position
    id: servo_sensor
    on_value:
      then:
        - script.execute: script_servo

#Switches
switch:
#Restart esp
  - platform: restart
    name: gateway restart

#Servo switch with start and end position
  - platform: template
    id: servo_control_switch
    name: servo start/end
    icon: mdi:bathtub
    restore_state: true
    turn_on_action:
      - sensor.template.publish:
          id: servo_sensor
          state: !lambda 'return id(servo_start).state;'
      - switch.template.publish:
         id: servo_control_switch
         state: true
      - servo.write:
         id: servo_control
         level: !lambda 'return (id(servo_start).state/100);'
    turn_off_action:
      - sensor.template.publish:
          id: servo_sensor
          state: !lambda 'return id(servo_stop).state;'
      - switch.template.publish:
         id: servo_control_switch
         state: false
      - servo.write:
         id: servo_control
         level: !lambda 'return (id(servo_stop).state/100);'


#Script servo script
script:
  - id: script_servo
    then:
      - if:
          condition:
            - lambda: 'return id(servo_sensor).state == id(servo_start).state;'
          then:
            - sensor.template.publish:
               id: servo_sensor
               state: !lambda 'return (id(servo_start).state/100);'
            - switch.turn_on: servo_control_switch
      - if:
          condition:
            and:
              - lambda: 'return id(servo_sensor).state == id(servo_stop).state;'
          then:
            - sensor.template.publish:
               id: servo_sensor
               state: !lambda 'return id(servo_stop).state;'
            - switch.turn_off: servo_control_switch

#Adding a slider to control the servo
number:
  - platform: template
    name: servo position
    min_value: -100
    max_value: 100
    update_interval: 5s 
    mode: slider #slider/box
    lambda: 'return id(servo_sensor).state;' 
    step: 1
    set_action:
      then:
        - servo.write:
           id: servo_control
           level: !lambda 'return x / 100.0;'
        - sensor.template.publish:
           id: servo_sensor
           state: !lambda 'return x;'

#Specify the initial position of the servo
  - platform: template
    name: servo start position
    id: servo_start
    min_value: -100
    max_value: 100
    mode: box #slider/box
    step: 1
    optimistic: true
    restore_value: true
 
#Specify the final position of the servo
  - platform: template
    name: servo end position
    id: servo_stop
    min_value: -100
    max_value: 100
    mode: box #slider/box
    step: 1
    optimistic: true
    restore_value: true


3 Likes

Just spent few hours trying to get SG90 working on ESP32. I was using a separate power supply for the 5V. Eventually worked it out that I had to tie the GND together of the external power supply to the GND of the ESP32.

taitum1234:

moostmartijn’s solution works, here’s why…

You can’t use hyphens ("-") in the service: name.
Underscores are ok.

So change “esphome.smart-vent_control_servo”
To “esphome.smart_vent_control_servo”

If you check the logs in HA, you’ll find this error if you use hyphens:

does not match format < domain>. <name> for dictionary value @ data[‘action’][0][‘service’]

Hello. Maybe try to use frendly name (that does not contain spaces). For example in your ESP YAML file:
" esphome:
name: “ESP1”
friendly_name: ESP1 " ← here
This is a name that Home Assistant use and so the name that should be in automations.yaml:
" action:

  • service: esphome.ESP1_control_servo " ← change the ESP1 if you have set diffrent friendly name earlier