What device did you purchase specifically? Most Dev boards these Days have on-board serial USB connections but you mention a 3.3 volt programmer setting. Not typical on my experience.
i bought this model:
ESP8266 Módulo de relé inalåmbrico de 1/2/4/8/16 canales AC/DC ESP ESP-12F Placa de desarrollo WIFI - AliExpress 502
and use a FTDI programer that have a jumper to set 5v or 3.3v.
ESP-12F_Relay_X4 | ESPHome Devices If youâve connected 5V to it you may have already killed it.
Thatâs a really old board. Personally, Iâd stick with buying ESP32 boards in 2026.
A lot of the ESPs are sorta 5v tolerant. Keep your fingers crossed.
Are you sure that esp32dev is the right board type in your yaml?
If in doubt, post your yaml code (forum </> formatting please)
Works fine. If i quit the jumper, it starts correcto and generate the wifi.
Not start the process of first program.
The yaml now is not importante because not pass the âconectingâ
I would say the yaml is very important, as your âconnectingâ will rely on what you have there.
the yaml is basically the same as first post, with some litle changes in not core sections.
I would encourage you to start with the YAML in the link I last posted. This is basic YAML for the board. Once the board is working, add in the sprinkler config.
solved, the problem is not the yaml. because as i said the problem is in the first steep, previously to the preparing instalation.
In my case with my board:
- connected ONLY the programer in 5V setup
- jumper into io0 and gnd
- push the reset button and keep it
- connect the programer to the PC
- push install en esphome and select the programer.
- timeout
- push retry, push only one time the reset button in the board. ONLY ONE TIME. NOT keeping pushed.
- and no, conected, preparing to install, and installed
maybe this is not the correct procedure, but IN MY CASE, worked.
and now I will play ![]()
Hi Jack , is your code available, i would really like to see your menu with the rotary ,to have control on the panelâŠ
Thanks
Sure,
name: irrigation-control
friendly_name: Irrigation control
esp32:
board: esp32-s3-devkitc-1
flash_size: 8MB
framework:
type: esp-idf
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "key"
ota:
- platform: esphome
password: "password"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Irrigation-Control"
password: "rDfXc4gU5ro7"
captive_portal:
i2c:
sda: GPIO8
scl: GPIO9
frequency: 400kHz
# --- Display and Menu Configuration ---
font:
- file: "fonts/arial.ttf"
id: my_font
size: 16
display:
- platform: ssd1306_i2c
id: oled_display
model: "SSD1306 128x64"
address: 0x3C
pages:
- id: page1
lambda: |-
if (id(backyard_sprinklers).active_valve().has_value()) {
// the controller is running, get the active valve into running_valve and print it
auto running_valve = id(backyard_sprinklers).active_valve().value() + 1;
it.print(0, 0, id(my_font), "Cycle Active");
it.printf(0, 16, id(my_font), "Zone %u", running_valve);
it.printf(0, 32, id(my_font), "Remaining: %u", id(backyard_sprinklers).time_remaining_active_valve().value());
} else {
// the controller is NOT running
it.print(0, 0, id(my_font), "");
}
# The display_menu component, set to rotary mode
graphical_display_menu:
id: sprnklr_menu
display: oled_display
font: my_font
active: false
mode: rotary
items:
- type: command
text: 'Exit Menu'
on_value:
then:
- display_menu.hide: sprnklr_menu
- type: switch
immediate_edit: true
text: 'Full Cycle'
switch: sprinkler_ctrlr_main_switch
on_enter:
then:
- switch.toggle: sprinkler_ctrlr_main_switch
- type: switch
immediate_edit: true
text: 'Rain Delay'
switch: raindelay_24h_enabled
on_enter:
then:
- logger.log: "Selected Rain Delay"
- switch.toggle: raindelay_24h_enabled
- type: switch
immediate_edit: True
text: 'Zone 1'
switch: zone_1_aux
on_enter:
then:
- switch.toggle: zone_1_aux
- type: switch
immediate_edit: True
text: 'Zone 2'
switch: zone_2_aux
on_enter:
then:
- switch.toggle: zone_2_aux
- type: switch
immediate_edit: True
text: 'Zone 3'
switch: zone_3_aux
on_enter:
then:
- switch.toggle: zone_3_aux
- type: switch
immediate_edit: True
text: 'Zone 4'
switch: zone_4_aux
on_enter:
then:
- switch.toggle: zone_4_aux
# --- Rotary Encoder and Button Integration ---
# Integrate the rotary encoder sensor
sensor:
- platform: rotary_encoder
id: my_encoder
name: "Rotary Encoder"
pin_a: GPIO4
pin_b: GPIO5
# Send actions to the display_menu component
on_clockwise:
- display_menu.up: sprnklr_menu
on_anticlockwise:
- display_menu.down: sprnklr_menu
- platform: uptime
name: Uptime
entity_category: "diagnostic"
# Integrate the button on the rotary encoder
binary_sensor:
- platform: gpio
id: rotary_button
pin:
number: GPIO10
mode: INPUT
name: "Rotary Encoder Button"
filters:
- delayed_on: 10ms
- delayed_off: 10ms
on_press:
- if:
condition:
display_menu.is_active: sprnklr_menu
then:
- display_menu.enter: sprnklr_menu
else:
- display_menu.show: sprnklr_menu
- platform: status
name: "Status"
- platform: gpio
name: "Boot Button"
pin:
number: 0
ignore_strapping_warning: true
mode:
input: true
inverted: true
disabled_by_default: true
on_press:
then:
- button.press: restart_button
sprinkler:
- id: backyard_sprinklers
main_switch:
name: "Sprinklers Main"
id: sprinkler_ctrlr_main_switch
auto_advance_switch: "Auto Advance"
valves:
- valve_switch: "Backyard Zone 1"
enable_switch: "Enable_Backyard Zone 1"
run_duration_number:
id: zone_1_run_duration
name: "Zone 1 Run Duration"
icon: "mdi:timer-outline"
initial_value: 1
unit_of_measurement: min
valve_switch_id: relay1
- valve_switch: "Backyard Zone 2"
enable_switch: "Enable Backyard Zone 2"
run_duration_number:
id: zone_2_run_duration
name: "Zone 2 Run Duration"
icon: "mdi:timer-outline"
initial_value: 1
unit_of_measurement: min
valve_switch_id: relay2
- valve_switch: "Backyard Zone 3"
enable_switch: "Enable Backyard Zone 3"
run_duration_number:
id: zone_3_run_duration
name: "Zone 3 Run Duration"
icon: "mdi:timer-outline"
initial_value: 1
unit_of_measurement: min
valve_switch_id: relay3
- valve_switch: "Backyard Zone 4"
enable_switch: "Enable Backyard Zone 4"
run_duration_number:
id: zone_4_run_duration
name: "Zone 4 Run Duration"
icon: "mdi:timer-outline"
initial_value: 1
unit_of_measurement: min
valve_switch_id: relay4
switch:
- platform: gpio
pin: GPIO1
id: relay1
restore_mode: ALWAYS_OFF
- platform: gpio
pin: GPIO2
id: relay2
restore_mode: ALWAYS_OFF
- platform: gpio
pin: GPIO41
id: relay3
restore_mode: ALWAYS_OFF
- platform: gpio
pin: GPIO42
id: relay4
restore_mode: ALWAYS_OFF
# day of week toggle switches
- platform: template
id: dow_sunday
name: Sunday
icon: "mdi:calendar-range"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
- platform: template
id: dow_monday
name: Monday
icon: "mdi:calendar-range"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
- platform: template
id: dow_tuesday
name: Tuesday
icon: "mdi:calendar-range"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
- platform: template
id: dow_wednesday
name: Wednesday
icon: "mdi:calendar-range"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
- platform: template
id: dow_thursday
name: Thursday
icon: "mdi:calendar-range"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
- platform: template
id: dow_friday
name: Friday
icon: "mdi:calendar-range"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
- platform: template
id: dow_saturday
name: Saturday
icon: "mdi:calendar-range"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
# scheduled time enable switches
- platform: template
id: schedule1_enabled
name: Enable Schedule 1
icon: "mdi:clock-outline"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
- platform: template
id: schedule2_enabled
name: Enable Schedule 2
icon: "mdi:clock-outline"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
- platform: template
id: schedule3_enabled
name: Enable Schedule 3
icon: "mdi:clock-outline"
entity_category: config
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
# rain delay switches (can be cancelled, auto-resetting)
- platform: template
id: raindelay_24h_enabled
name: Enable 24h Rain Delay
icon: "mdi:weather-cloudy-clock"
restore_mode: RESTORE_DEFAULT_OFF
optimistic: true
turn_on_action:
then:
- delay:
hours: 24
- switch.turn_off: raindelay_24h_enabled
- platform: template
id: raindelay_48h_enabled
name: Enable 48h Rain Delay
icon: "mdi:weather-cloudy-clock"
restore_mode: RESTORE_DEFAULT_OFF
optimistic: true
turn_on_action:
then:
- delay:
hours: 48
- switch.turn_off: raindelay_48h_enabled
- platform: template
id: main_switch
optimistic: true
name: "Sprinkler Main"
on_turn_off:
- switch.turn_off: sprinkler_ctrlr_main_switch
on_turn_on:
- switch.turn_on: sprinkler_ctrlr_main_switch
- platform: template
id: zone_1_aux
optimistic: True
name: "Zone 1 Aux"
on_turn_off:
then:
- sprinkler.shutdown:
id: backyard_sprinklers
on_turn_on:
then:
- sprinkler.start_single_valve:
id: backyard_sprinklers
valve_number: 0
- platform: template
id: zone_2_aux
optimistic: True
name: "Zone 2 Aux"
on_turn_off:
then:
- sprinkler.shutdown:
id: backyard_sprinklers
on_turn_on:
then:
- sprinkler.start_single_valve:
id: backyard_sprinklers
valve_number: 1
- platform: template
id: zone_3_aux
optimistic: True
name: "Zone 3 Aux"
on_turn_off:
then:
- sprinkler.shutdown:
id: backyard_sprinklers
on_turn_on:
then:
- sprinkler.start_single_valve:
id: backyard_sprinklers
valve_number: 2
- platform: template
id: zone_4_aux
optimistic: True
name: "Zone 4 Aux"
on_turn_off:
then:
- sprinkler.shutdown:
id: backyard_sprinklers
on_turn_on:
then:
- sprinkler.start_single_valve:
id: backyard_sprinklers
valve_number: 3
datetime:
- platform: template
name: Schedule 1 Start Time
entity_category: config
id: sched_s1t
type: time
optimistic: true
restore_value: true
- platform: template
name: Schedule 2 Start Time
entity_category: config
id: sched_s2t
type: time
optimistic: true
restore_value: true
- platform: template
name: Schedule 3 Start Time
entity_category: config
id: sched_s3t
type: time
optimistic: true
restore_value: true
time:
- platform: homeassistant
id: ha_time
on_time:
# Every 1 minute
- seconds: 0
minutes: /1
then:
- script.execute: script1
on_time_sync:
then:
- logger.log: "Synchronized system clock"
script:
# check what day of the week it is currently, and if we have the schedule enabled today
- id: script1
then:
lambda: |-
int dow = id(ha_time).now().day_of_week;
if ((dow == 1 && id(dow_sunday).state == true)
|| (dow == 2 && id(dow_monday).state == true)
|| (dow == 3 && id(dow_tuesday).state == true)
|| (dow == 4 && id(dow_wednesday).state == true)
|| (dow == 5 && id(dow_thursday).state == true)
|| (dow == 6 && id(dow_friday).state == true)
|| (dow == 7 && id(dow_saturday).state == true)) {
id(script2).execute();
}
# if current time is equal to any of the scheduled start times, start the sprinkler cycle
- id: script2
then:
lambda: |-
int hour = id(ha_time).now().hour;
int minute = id(ha_time).now().minute;
if ((hour == id(sched_s1t).hour && minute == id(sched_s1t).minute && id(schedule1_enabled).state == true && id(raindelay_24h_enabled).state == false && id(raindelay_48h_enabled).state == false)
|| (hour == id(sched_s2t).hour && minute == id(sched_s2t).minute && id(schedule2_enabled).state == true && id(raindelay_24h_enabled).state == false && id(raindelay_48h_enabled).state == false)
|| (hour == id(sched_s3t).hour && minute == id(sched_s3t).minute && id(schedule3_enabled).state == true && id(raindelay_24h_enabled).state == false && id(raindelay_48h_enabled).state == false)) {
id(script3).execute();
}
# start the sprinkler cycle
- id: script3
then:
- sprinkler.start_full_cycle: backyard_sprinklers
- lambda: ESP_LOGI("main", "Sprinkler cycle has begun!");
button:
- platform: restart
name: "Restart"
id: restart_button
entity_category: config
- platform: factory_reset
name: "Factory Reset"
id: reset
entity_category: config
- platform: safe_mode
name: "Safe Mode"
internal: false
entity_category: config
Wow that looks really cool!
Any help on an exact working config? I have built it with the same board, but my relays are not firing.
Hello,
I plan on following the OP. since i am located in NL, i am not sure if i can find the same PCB of the relay board. can you give me measurements for the PCB so I can check? that way I can use the included 3D model to print a case.
Sorry for the stupid question but what is the benefit of that board? The way I understand how to do this for people who need 24VAC is how @roc1479 did it by using a 24VAC power supply and jumping the relays with that voltage. And then stepping it down and converting to some suitable voltage for the board itself (e.g. 5VDC), that should work the same on the original 8-relay board, no?
Even if this 4-relay board can be operated with mains voltage, I don't see a benefit here for controlling the valves? A transformer still is needed from mains -> 24VAC.


