Check the relays installed on your board.
Are they 5VDC or 12VDC items?
If they are 12VDC, that is your issue.
The manufacturer placed the wrong relays on the board.
I’m building a landscape lighting controller for my back yard using this four-relay board. The board came with the Nuvoton chip, so I used the longer UART codes with preambles. The relays are switching from OFF (Normally Open) to ON to pass 12VDC from the landscape lighting transformer to each of four zones. The relay board is powered from a 12VDC-to-5VDC buck convertor module. Wiring is easy, but running the low-voltage wires around the back yard in the summer heat is the most difficult part of this project.
Parts in use:
9x6x3 Extreme Broadband Heavy Duty Weatherproof Enclosure IPE963-LTC
Four-relay ESP8266 Smart Switch Module
12V-to-5V Miniature DC-DC Convertor Power Supply Module
2 x Four-position terminal strips
The larger four-position terminal strips allow attaching multiple low-voltage wires without problem. The plastic box has foam-insulated ports on the bottom for waterproof routing of the low-voltage wires into and out of the box.
Was going to say thank you for this thread, it helped me get up and running in about 20 mins after finding out my new ESP01 flashing USB stick didn’t require anything special and just flashed it straight from ESPHome.
Going to be using it for a garage door relay so needed the momentary press:
- platform: template
name: 'Relay 1 Toggle'
id: relay1tog
turn_on_action:
- uart.write: [0xA0, 0x01, 0x01, 0xA2]
turn_off_action:
- uart.write: [0xA0, 0x01, 0x00, 0xA1]
optimistic: true
on_turn_on:
- delay: 500ms
- switch.turn_off: relay1tog
And it works a treat. Many thanks.
esphome:
name: 4ch-relay
esp8266:
board: esp01_1m
# Enable Home Assistant API
api:
ota:
password: "*******************************"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "4Ch-Relay Fallback Hotspot"
password: "************"
captive_portal:
# Enable Web server.
#web_server:
# port: 80
time:
- platform: homeassistant
id: homeassistant_time
# Text sensors with general information.
text_sensor:
# Expose ESPHome version as sensor.
- platform: version
name: Relay ESPHome Version
# Expose WiFi information as sensors.
- platform: wifi_info
ip_address:
name: Relay IP
ssid:
name: Relay Connected SSID
bssid:
name: Relay Connected BSSID
mac_address:
name: Relay Mac Wifi Address
# Make uptime Human Readable
- platform: template
name: Uptime Human Readable
id: uptime_human
icon: mdi:clock-start
# Sensors with general information.
sensor:
# Uptime sensor.
- platform: uptime
name: Relay Uptime
id: uptime_sensor
update_interval: 60s
on_raw_value:
then:
- text_sensor.template.publish:
id: uptime_human
state: !lambda |-
int seconds = round(id(uptime_sensor).raw_state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return (
(days ? to_string(days) + "d " : "") +
(hours ? to_string(hours) + "h " : "") +
(minutes ? to_string(minutes) + "m " : "") +
(to_string(seconds) + "s")
).c_str();
# WiFi Signal sensor.
- platform: wifi_signal
name: Relay WiFi Signal
update_interval: 60s
- platform: adc
pin: VCC
name: "VCC Voltage"
# Enable logging
logger:
baud_rate: 0 #need this to free up UART pins
uart:
baud_rate: 115200 # speed to STC15L101EW
tx_pin: GPIO1
rx_pin: GPIO3
switch:
- platform: template
name: 'Relay 1'
id: relay1
turn_on_action:
- uart.write: [0xA0, 0x01, 0x01, 0xA2]
turn_off_action:
- uart.write: [0xA0, 0x01, 0x00, 0xA1]
optimistic: true
- platform: template
name: 'Relay 2'
id: relay2
turn_on_action:
- uart.write: [0xA0, 0x02, 0x01, 0xA3]
turn_off_action:
- uart.write: [0xA0, 0x02, 0x00, 0xA2]
optimistic: true
- platform: template
name: 'Relay 3'
id: relay3
turn_on_action:
- uart.write: [0xA0, 0x03, 0x01, 0xA4]
turn_off_action:
- uart.write: [0xA0, 0x03, 0x00, 0xA3]
optimistic: true
- platform: template
name: 'Relay 4'
id: relay4
turn_on_action:
- uart.write: [0xA0, 0x04, 0x01, 0xA5]
turn_off_action:
- uart.write: [0xA0, 0x04, 0x00, 0xA4]
optimistic: true
After amalgamating the posts and viewing the esphome docs, this is what I use.
Just wondering if the turn on and off actions could be done using the UART switch?
https://esphome.io/components/switch/uart.html?highlight=uart
Hi, did anyone of you manage to sort out if it’s possible to read the actual state of the relays?
Do the ESP receive anything cyclic on the RX pins or are there any register to read data from?
I needed to toggle two relays. (one on, one off). I tried a few combinations. This is what ultimately worked. Looks like you need a delay between commands.
turn_on_action:
- uart.write: [0xA0, 0x01, 0x01, 0xA2]
- delay: 10ms
- uart.write: [0xA0, 0x02, 0x00, 0xA2]
turn_off_action:
- uart.write: [0xA0, 0x02, 0x01, 0xA3]
- delay: 10ms
- uart.write: [0xA0, 0x01, 0x00, 0xA1]
It appears that “0xA0” is the sequence start, then the second byte is the Relay #, the third byte is either 0x00 or 0x01 for off/on respectively; and the last byte is the ‘sequence end’ which includes a checksum.
However, this didn’t work:
- uart.write: [0xA0, 0x01, 0x00, 0xA1, 0xA0, 0x02, 0x01, 0xA3]
- uart.write: [0xA0, 0x01, 0x01, 0xA2, 0xA0, 0x02, 0x00, 0xA2]
and neither did this:
- uart.write: [0xA0, 0x01, 0x00, 0x02, 0x01, 0xA4]
- uart.write: [0xA0, 0x01, 0x01, 0x02, 0x00, 0xA4]
Since this post helped me so much, I also want to show you what works for me. When I want to toggle the switches, this code works wonderfully:
switch:
- platform: template
name: 'Stufe 1'
id: relay1
turn_on_action:
- delay: 2000ms
- uart.write: [0xA0, 0x01, 0x01, 0xA2]
turn_off_action:
- uart.write: [0xA0, 0x01, 0x00, 0xA1]
optimistic: true
on_turn_on:
- delay: 10ms
- switch.turn_off: relay2
- delay: 10ms
- switch.turn_off: relay3
- delay: 10ms
- switch.turn_off: relay4
- platform: template
name: 'Stufe 2'
id: relay2
turn_on_action:
- delay: 2000ms
- uart.write: [0xA0, 0x02, 0x01, 0xA3]
turn_off_action:
- uart.write: [0xA0, 0x02, 0x00, 0xA2]
optimistic: true
on_turn_on:
- delay: 10ms
- switch.turn_off: relay1
- delay: 10ms
- switch.turn_off: relay3
- delay: 10ms
- switch.turn_off: relay4
- platform: template
name: 'Stufe 3'
id: relay3
turn_on_action:
- delay: 2000ms
- uart.write: [0xA0, 0x03, 0x01, 0xA4]
turn_off_action:
- uart.write: [0xA0, 0x03, 0x00, 0xA3]
optimistic: true
on_turn_on:
- delay: 10ms
- switch.turn_off: relay1
- delay: 10ms
- switch.turn_off: relay2
- delay: 10ms
- switch.turn_off: relay4
- platform: template
name: 'Stufe 4'
id: relay4
turn_on_action:
- delay: 2000ms
- uart.write: [0xA0, 0x04, 0x01, 0xA5]
turn_off_action:
- uart.write: [0xA0, 0x04, 0x00, 0xA4]
optimistic: true
on_turn_on:
- delay: 10ms
- switch.turn_off: relay1
- delay: 10ms
- switch.turn_off: relay2
- delay: 10ms
- switch.turn_off: relay3
Is there a reason you didn’t just include the turning off of the other relays as part of the turn_on_action
? I was curious if you had tested that and had reason for doing it the way you did. Also, 2 seconds (2000 ms) is a seemingly long wait time for an impatient person like myself and others so I may or others may try to click again with a delay like that. Was this also tested for a reason I have not yet come across? Thanks for feedback. I put my test code below at 300 ms as that seemed to be what people were using when configuring interlock:
settings, but unfortunately that isn’t available for template:
types, versus switch:
.
CODE SUGGESTIONS BELOW WORK, NOT EXTENSIVELY TESTED, SO I DON’T KNOW IF THERE ARE DRAWBACKS TO THIS. Seems to work well and things are more responsive that I wouldn’t click again. Tested clicking between relays quickly and didn’t seem to affect anything.
switch:
- platform: template
name: 'Relay 1'
id: relay1
turn_on_action:
- delay: 10ms
- switch.turn_off: relay2
- delay: 10ms
- switch.turn_off: relay3
- delay: 10ms
- switch.turn_off: relay4
- delay: 300ms
- uart.write: [0xA0, 0x01, 0x01, 0xA2]
turn_off_action:
- uart.write: [0xA0, 0x01, 0x00, 0xA1]
optimistic: true
- platform: template
name: 'Relay 2'
id: relay2
turn_on_action:
- delay: 10ms
- switch.turn_off: relay1
- delay: 10ms
- switch.turn_off: relay3
- delay: 10ms
- switch.turn_off: relay4
- delay: 300ms
- uart.write: [0xA0, 0x02, 0x01, 0xA3]
turn_off_action:
- uart.write: [0xA0, 0x02, 0x00, 0xA2]
optimistic: true
- platform: template
name: 'Relay 3'
id: relay3
turn_on_action:
- delay: 10ms
- switch.turn_off: relay1
- delay: 10ms
- switch.turn_off: relay2
- delay: 10ms
- switch.turn_off: relay4
- delay: 300ms
- uart.write: [0xA0, 0x03, 0x01, 0xA4]
turn_off_action:
- uart.write: [0xA0, 0x03, 0x00, 0xA3]
optimistic: true
- platform: template
name: 'Relay 4'
id: relay4
turn_on_action:
- delay: 10ms
- switch.turn_off: relay1
- delay: 10ms
- switch.turn_off: relay2
- delay: 10ms
- switch.turn_off: relay3
- delay: 300ms
- uart.write: [0xA0, 0x04, 0x01, 0xA5]
turn_off_action:
- uart.write: [0xA0, 0x04, 0x00, 0xA4]
optimistic: true
I anticipate any feedback from others experience or know how as to whether this is a good idea or if there are reasons not to do it this way.
THIS PAGE WAS SUPER HELPFUL FO ME AND I WANTED TO CONTRIBUTE TO OTHERS LOOKING FOR HELP. I couldn’t find complete examples but this page got me to where I needed to be so I am contributing my full example.
Here is my 4 channel relay configuration that I setup for use with a 3 speed pull chain fan conversion. The original fan was Off, Low, Medium, and High and cycled through the stages as you pulled the chain. I wanted control of selecting each individual speed, automations, power, etc. all while still keeping the pull chain functional for others to be able to operate it normally. Using the esp-01s and the attached 4 channel relay and some finagling allowed me to do this!
For transparency, I have decided not to use this and instead go with a D1Mini and a separate 4 channel relay (only need three) that has individual pins to turn on and off the relays and provide status of the relay state since each pin is individual. The configuration below does lose track of what speed the relay is on from the esphome device’s web interface when the browser page is refreshed. Not sure if Home Assistant does also, cause I didn’t check before deciding I needed more control. Might be alright there. Long story short, I couldn’t mess with not knowing what was on and what was off when I am switching three different 120VAC legs into a motor and only one can be on at a time. While I accomplished most things below, I just felt the need for more info and control. I certainly will use this in some form on a project that doesn’t have a big 'ol fan connected to it!
Anyway, I removed the original 3way (4-wire) pull chain and replaced it with a single on/off pull chain as I’ll configure the different speeds in code. I just need to know the state has changed to cycle things. I am using GOPI0 to determine if the state of the pull chain has changed. It doesn’t matter if it is On or Off really, just that it has changed. All well and good except I had a 50% chance of the chain being ON and therefore GPIO0 connected to GND at boot up and if GPIO0 was connected directly through to GND during boot the device goes to boot loader mode and doesn’t startup normal operations. To avoid this issue, I have relay4 to enable/disable the Pull chain. One leg of the pull chain is soldered to GPIO0 then to the NC of relay4 and out the NO (normally open) side of relay4 then soldered to the GND pin. Then in the code I turn relay4 on after boot automatically enabling the pull chain after the device is successfully booted. This ensures during boot that the GPIO0 and GND are not connected until after the program starts.
The turn on action for each of the speed relays first turns off the others prior to turning itself on. The functions like and interlock:
but since the template
platform doesn’t have that I had to manually do it. In the code below I threw in using the fan:
component which I started using on my new iteration. I commented out the old code I used that I had come up with that worked but not as nice. However, I didn’t rebuild this one on the esp to confirm function, but I believe I have added it in right based off my other working model.
substitutions:
#--- device config
device_name: "bar-fan"
device_disp: "Bar Fan"
packages:
common: !include common/base_config.yaml
wifi: !include common/base_wifi.yaml
esphome:
name: ${device_name}
comment: '${device_disp} controller'
on_boot:
priority: -10
then:
- switch.turn_on: relay4
esp8266:
board: esp01_1m
# Enable logging
logger:
baud_rate: 0 # need this to free up UART pins
uart:
baud_rate: 115200 # speed to STC15L101EW
tx_pin: GPIO1
rx_pin: GPIO3
# globals:
# id: speed
# type: int
# initial_value: "0" # Off: 0; Low: 1; Medium: 2; High: 3
# restore_value: no
#
# binary_sensor:
# - platform: gpio
# pin: GPIO0
# name: "${device_disp} Pull Chain"
# internal: true
# filters:
# - delayed_on_off: 300ms # was 100ms; thought matching delay time was better
# on_state:
# then:
# - lambda: |-
# id(speed) = id(speed) + 1;
# if(id(speed) > 3) {
# id(speed) = 0;
# }
# if(id(speed) == 0) {
# id(relay1).turn_off();
# id(relay2).turn_off();
# id(relay3).turn_off();
# }
# if(id(speed) == 1) {
# id(relay1).turn_on();
# }
# if(id(speed) == 2) {
# id(relay2).turn_on();
# }
# if(id(speed) == 3) {
# id(relay3).turn_on();
# }
binary_sensor:
- platform: gpio
name: "${device_disp} Pull Chain"
pin: GPIO0
internal: true
filters:
- delayed_on_off: 100ms
on_state:
then:
- fan.cycle_speed: fan1
button:
#--- Momentary Push Button for for testing "like pull chain"
- platform: template
name: "${device_disp} Button"
internal: true
on_press:
then:
- fan.cycle_speed: fan1
fan:
- platform: speed
output: fan_speed
id: fan1
name: "${device_disp}"
icon: mdi:fan
speed_count: 3
output:
- platform: template
type: float
id: fan_speed
write_action:
- lambda: |-
ESP_LOGD("fan", "Float value: %f", state);
if(state < 0.3) {
// Off
id(relay1).turn_off();
id(relay2).turn_off();
id(relay3).turn_off();
} else if (state >= 0.3 && state <= 0.39) {
// Low Speed
id(relay1).turn_on();
} else if (state >= 0.4 && state <= 0.69) {
// Medium Speed
id(relay2).turn_on();
} else if (state > 0.69) {
// High Speed
id(relay3).turn_on();
}
switch:
- platform: template
name: "${device_disp} Relay 1"
id: relay1
turn_on_action:
- delay: 10ms
- switch.turn_off: relay2
- delay: 10ms
- switch.turn_off: relay3
- delay: 300ms
- uart.write: [0xA0, 0x01, 0x01, 0xA2]
turn_off_action:
- uart.write: [0xA0, 0x01, 0x00, 0xA1]
optimistic: true
# on_turn_on:
# - globals.set:
# id: speed
# value: "1"
- platform: template
name: "${device_disp} Relay 2"
id: relay2
turn_on_action:
- delay: 10ms
- switch.turn_off: relay1
- delay: 10ms
- switch.turn_off: relay3
- delay: 300ms
- uart.write: [0xA0, 0x02, 0x01, 0xA3]
turn_off_action:
- uart.write: [0xA0, 0x02, 0x00, 0xA2]
optimistic: true
# on_turn_on:
# - globals.set:
# id: speed
# value: "2"
- platform: template
name: "${device_disp} Relay 3"
id: relay3
turn_on_action:
- delay: 10ms
- switch.turn_off: relay1
- delay: 10ms
- switch.turn_off: relay2
- delay: 300ms
- uart.write: [0xA0, 0x03, 0x01, 0xA4]
turn_off_action:
- uart.write: [0xA0, 0x03, 0x00, 0xA3]
optimistic: true
# on_turn_on:
# - globals.set:
# id: speed
# value: "3"
- platform: template
name: "${device_disp} Enable Pull Chain"
id: relay4
turn_on_action:
- uart.write: [0xA0, 0x04, 0x01, 0xA5]
turn_off_action:
- uart.write: [0xA0, 0x04, 0x00, 0xA4]
optimistic: true
Just wanting to post this here for anyone looking for the 8-channel relay board from LC Technology. It’s from the original PDF reference file, including a table showing all the GPIO channels assigned for each relay.
Relay 1 GPIO16
Relay 2 GPIO14
Relay 3 GPIO12
Relay 4 GPIO13
Relay 5 GPIO15
Relay 6 GPIO0
Relay 7 GPIO4
Relay 8 GPIO5
Hi, thanks for this thread,
i have the 2 channel relay board that comes with esp-01 and in addition to using the relays, i would like to add 2 sensors, Dallas (i2c per my understanding) and AM2301 (DHT), has anybody managed to connect additional peripherals to the board ?
thank you !
Thank you for this, I bought one of these off AliExpress, and I was able to erase, prepare, and flash ESPHome on it, update your Yaml code and wirelessly update it.
I have control of all four relays now through Home Assistant. I very much appreciate your efforts on this. Thank you!
You seem to have solved my problem, but how did you do it? I am stuck on adding the UART codes for the Nuvoton chip. Don’t seem to get the relays to function or click. Would you like to share the code for that part?
esphome:
name: back-yard-lights
platform: ESP8266
board: esp01_1m
#
# Disable UART logging
#
logger:
baud_rate: 0
level: debug
#
# Config UART for STC15L101EW serial commands
#
uart:
baud_rate: 115200
tx_pin: GPIO1
rx_pin: GPIO3
#
# Configure all four relays as switches
#
switch:
- platform: template
name: 'Relay 1'
id: zone1
optimistic: true
assumed_state: false
restore_mode: "RESTORE_DEFAULT_OFF"
turn_on_action:
- uart.write: [0x0D, 0x0A, 0x2B, 0x49, 0x50, 0x44, 0x2C, 0x30, 0x2C, 0x34, 0x3A, 0xA0, 0x01, 0x01, 0xA2]
turn_off_action:
- uart.write: [0x0D, 0x0A, 0x2B, 0x49, 0x50, 0x44, 0x2C, 0x30, 0x2C, 0x34, 0x3A, 0xA0, 0x01, 0x00, 0xA1]
- platform: template
name: 'Relay 2'
id: zone2
optimistic: true
assumed_state: false
restore_mode: "RESTORE_DEFAULT_OFF"
turn_on_action:
- uart.write: [0x0D, 0x0A, 0x2B, 0x49, 0x50, 0x44, 0x2C, 0x30, 0x2C, 0x34, 0x3A, 0xA0, 0x02, 0x01, 0xA3]
turn_off_action:
- uart.write: [0x0D, 0x0A, 0x2B, 0x49, 0x50, 0x44, 0x2C, 0x30, 0x2C, 0x34, 0x3A, 0xA0, 0x02, 0x00, 0xA2]
- platform: template
name: 'Relay 3'
id: zone3
optimistic: true
assumed_state: false
restore_mode: "RESTORE_DEFAULT_OFF"
turn_on_action:
- uart.write: [0x0D, 0x0A, 0x2B, 0x49, 0x50, 0x44, 0x2C, 0x30, 0x2C, 0x34, 0x3A, 0xA0, 0x03, 0x01, 0xA4]
turn_off_action:
- uart.write: [0x0D, 0x0A, 0x2B, 0x49, 0x50, 0x44, 0x2C, 0x30, 0x2C, 0x34, 0x3A, 0xA0, 0x03, 0x00, 0xA3]
- platform: template
name: 'Relay 4'
id: zone4
optimistic: true
assumed_state: false
restore_mode: "RESTORE_DEFAULT_OFF"
turn_on_action:
- uart.write: [0x0D, 0x0A, 0x2B, 0x49, 0x50, 0x44, 0x2C, 0x30, 0x2C, 0x34, 0x3A, 0xA0, 0x04, 0x01, 0xA5]
turn_off_action:
- uart.write: [0x0D, 0x0A, 0x2B, 0x49, 0x50, 0x44, 0x2C, 0x30, 0x2C, 0x34, 0x3A, 0xA0, 0x04, 0x00, 0xA4]
I can also say, you should check the four relays on your board. Be certain they are using either 3.3VDC or 5VDC coils. I once received a board that had 12VDC coils installed, and it would NEVER fire, simply because there was no 12VDC power supply anywhere on the board.
Thank you for answering so quickly and being so generous!!! Fantastic!!! It did not work for me though (or I have missed something else). The relay works fine with Tasmota and code from LC Technology 12V 4 Channel Relay Board (LC-ESP01-4R-12V) Configuration for Tasmota. I want to use esphome for everything and don’t seem to understand how to initiate the listening state between esp01 and the relaycard, how to translate the Tasmota command: SerialReceived#Data=41542B5253540D0A to yaml in esphome.
Can you share a close-up photograph/image of your board?
It may help identify some other difference, as in the power supply section, or the actual relays.
Also, what power supply are you using to power the board? Is it 5VDC, or 12VDC?
We are using 12V power supply for this one. We also have a couple of 4 ch relays with 5V power, who also needs this initiating code to work in Tasmota. Thank you for trying to help!
You are QUITE welcome. Yes, those are definitely 12VDC relays. Are you supplying 12VDC or 12VAC to the board, and is it responding to ESPHome log requests?
That’s very good to see.
And have you tried using the shorter hex byte strings for the relays? The codes I provided include a ‘preamble’ of several bytes that were previously necessary for only some boards. All having to do with the specific version of firmware stored on the Nuvoton microprocessor on the relay board. There are several examples of these shorter hex bytes further up this discussion thread.