Part 1 - Smart Bathroom Mirror Touch Switch

 

I have a large bathroom mirror with 2 (engraved) touch sensor ereas, surround LED lights (CCT) and a mirror defogger (220v controlled by a relay).

 

I wanted to build a smart mirror which displays a few important information. It should be  replace our current (stupid) mirror.

 

 

I have the following Touch Switch which I want to replace with a esp32 so I can also control it via Home Assistant.

I now just want to add an esp32 with 2 LED touch switches so I can have those control anything I want.

With ESPHome we can easily turn the analogue input (ADC) pin into a touch switch with a bit of clever software configuration and no external components!

 

This switch can be used like any other switch in Home Assistant and has toggle functionality.

 

This is by no means a solution that will replace a dedicated capacitive touch switch, such as the touch pads found on the ESP32, however considering we are just recycling an ADC pin the results are rather good!

 

touch-switch-4.png

 

WS08F3 Touch switch with background light  for esp32

touch-switch-3.jpg

Prerequisite

 

For this tutorial we will assume that you have Home Assistant up and running already. A very basic knowledge of configuration.yaml would also be advantageous, but we will cover as much detail as possible.

 

If you are completely new to Home Assistant then you should probably first check out my beginners guide to YAML, as well as my tutorials on automation and scripts.

 

You will also need to configure the ESPHome add-on in Home Assistant and have a compatible ESP device such as the Wemos D1 Mini, you can check out this good deal on a pack of them over at Amazon.

 

If you haven’t installed the ESP Home add-on yet, go ahead and check out my tutorial on how to add ESPHome to Home Assistant.

 

Material

1 * Touch switch with background light  for esp32

1 * TM1637

 

Configure ESPHome

 

The principle of this configuration is based upon the fact that the voltage read by the ADC increases by a miniscule amount when the pin is touched.

 

You can connect your switch plate directly to the pin, or just use a bare wire if you like.

 

We will create a sensor that reads the ADC pin and then use a binary sensor to turn the analogue reading into an binary on/off state.

 

This state can then be fed to a toggle switch. Either the binary state or toggle state can be used in Home Assistant.

Add a new device

 

First you should add a new device in ESPHome if you have not done so already.

 

When your new device is available in the user interface, go ahead and click edit and you should be presented with something like the following template.

 

Note that the parameters will reflect your device configuration.

 

esphome:
  name: little_wemos
  platform: ESP8266
  board: d1_mini
 
wifi:
  ssid: "MyWiFiRouter"
  password: "************"
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Little Wemos Fallback Hotspot"
    password: "************"
 
captive_portal:
 
# Enable logging
logger:
 
api:
 
ota:

 

Add the ADC Pin

The first thing we need to add to our code is the analogue to digital convertor pin.

 

We will set this up as a sensor using the adc platform. By specifying an update rate of 100ms, new values will be read from the pin every 100 miliseconds.

 

The difference in voltage when touching the pin is miniscule, therefore we also need to amplify the result using a multiplication factor of 100.

 

I am using a Wemos D1 Mini, therefore I will specify pin A0 as this is the ADC pin.

 

If you are using a different board then you should change this to suit the board.

esphome:
  name: little_wemos
  platform: ESP8266
  board: d1_mini
 
wifi:
  ssid: "MyWiFiRouter"
  password: "************"
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Little Wemos Fallback Hotspot"
    password: "************"
 
captive_portal:
 
# Enable logging
logger:
 
api:
 
ota:

sensor:
  - platform: adc
    pin: A0
    name: "Touch Switch ADC"
    id: touch_switch_adc
    update_interval: 100ms
    filters:
    - multiply: 100

Adding a switch

Next we will create a switch for the output which will toggle when the ADC pin is touched. Note that we need to set the optimistic parameter to true so that the reported status is immediately updated.

esphome:
  name: little_wemos
  platform: ESP8266
  board: d1_mini
 
wifi:
  ssid: "MyWiFiRouter"
  password: "************"
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Little Wemos Fallback Hotspot"
    password: "************"
 
captive_portal:
 
# Enable logging
logger:
 
api:
 
ota:

sensor:
  - platform: adc
    pin: A0
    name: "Touch Switch ADC"
    id: touch_switch_adc
    update_interval: 100ms
    filters:
    - multiply: 100

switch:
  - platform: template
    name: "Touch Switch"
    id: touch_switch
    optimistic: true

 

Adding a global variable

In the next section we will need to use a global variable to store the state of the switch. Therefore we will add a bool to globals.

esphome:
  name: little_wemos
  platform: ESP8266
  board: d1_mini
 
wifi:
  ssid: "MyWiFiRouter"
  password: "************"
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Little Wemos Fallback Hotspot"
    password: "************"
 
captive_portal:
 
# Enable logging
logger:
 
api:
 
ota:

sensor:
  - platform: adc
    pin: A0
    name: "Touch Switch ADC"
    id: touch_switch_adc
    update_interval: 100ms
    filters:
    - multiply: 100

switch:
  - platform: template
    name: "Touch Switch"
    id: touch_switch
    optimistic: true

globals:
 - id: t_sw_bool
   type: bool

 

Adding a binary sensor

In order to tie the ADC input to the switch, we need to use a binary sensor configured with the template platform.

esphome:
  name: little_wemos
  platform: ESP8266
  board: d1_mini
 
wifi:
  ssid: "MyWiFiRouter"
  password: "************"
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Little Wemos Fallback Hotspot"
    password: "************"
 
captive_portal:
 
# Enable logging
logger:
 
api:
 
ota:

sensor:
  - platform: adc
    pin: A0
    name: "Touch Switch ADC"
    id: touch_switch_adc
    update_interval: 100ms
    filters:
    - multiply: 100

switch:
  - platform: template
    name: "Touch Switch"
    id: touch_switch
    optimistic: true

globals:
 - id: t_sw_bool
   type: bool

binary_sensor:
  - platform: template
    id: touch_switch_pressed
    name: "touch switch pressed"

Now the clever bit! We will use lambda to add some C++ code that test whether the value of the ADC reading is greater than 1.

 

You may need to tweak this value depending on the board you are using.

 

If the touch switch is pressed and the value is above 1 then we will test whether or not the global variable t_w_bool is true or false.

 

If t_w_bool is false then we will toggle the switch and set t_w_bool to true.

 

This prevents the switch rapidly toggling, as the lambda code will continuously loop whilst the switch is held down.

 

When the switch is released the t_w_bool value is returned to false so that the toggle action is able to occur again when the switch is pressed again.

esphome:
  name: little_wemos
  platform: ESP8266
  board: d1_mini
 
wifi:
  ssid: "MyWiFiRouter"
  password: "************"
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Little Wemos Fallback Hotspot"
    password: "************"
 
captive_portal:
 
# Enable logging
logger:
 
api:
 
ota:

sensor:
  - platform: adc
    pin: A0
    name: "Touch Switch ADC"
    id: touch_switch_adc
    update_interval: 100ms
    filters:
    - multiply: 100

switch:
  - platform: template
    name: "Touch Switch"
    id: touch_switch
    optimistic: true

globals:
 - id: t_sw_bool
   type: bool

binary_sensor:
  - platform: template
    id: touch_switch_pressed
    name: "touch switch pressed"
    lambda: |-
      if (id(touch_switch_adc).state > 1) {
        if (id(t_sw_bool) == false){
          id(touch_switch).toggle();
        }
        id(t_sw_bool) = true;
        return true;
      } else {
        id(t_sw_bool) = false;
        return false;
      }

Configure Home Assistant

Now that the YAML configuration is finished, we can go ahead and flash the device.

 

If you need some guidance with this then go check out my tutorial on setting up ESPHome with Home Assistant.

 

Once we have flashed the device, all of the components created in ESPHome should automatically be available in Home Assistant once you have added the new device.

 

To test the configuration we will create a new entities card in the user interface and add the following entities.

 

sensor.adc

binary_sensor.adc_threshold

switch.touch_switch

This will create a new card with the raw analogue to digital reading.

 

It will show a voltage value but the unit of measurement is not relevant here. If you need to change the threshold, observe the values here when the switch us touched and not touched.

 

You can edit the binary sensor lambda as necessary.

 

Now you can go ahead and touch the switch (or just a bare wire attached to the ADC pin).

 

The ADC threshold should change to the on state when you touch the switch. The touch switch should toggle each time you touch it.

Conclusion

This is an interesting use for the solitary ADC pin found on ESP8266 devices, I do like the fact that it requires no components!

 

It is functional although not perfect and sometimes fails to trigger.

 

However it is a good demonstration of what can be done with the more advanced features of ESPHome, such as lambda.

 

useful links

 

https://community.home-assistant.io/t/bathroom-mirror-touch-sensor-for-esp8266-or-esp32/451756/7

Comments


Comments are closed