Advanced Pellet Stove Auger control inside ESPhome

I want to control an Auger motor in my pellet stove within ESPHome. I could do this in an automation in home assistant but if home assistant dies, I want it to keep running, I’m not a programmer, but I can write pseudo code. This is a simple function, but getting this to work inside esphome is daunting!
My reflashed Tuya ESP in the pellet stove is working great, this will just enhance it.

Any help appreciated!

New auger motor control

cut the trace on the MCU board from the auger control pin and the opto isolator it controls
and attach a wire to each side of the cut. attach them to the GPIO pins specified below on the TYWE1S chip

  • auger.input is the auger control signal from the MCU’s auger control pin’that now goes to the tywe1s GPIO1
    under normal conditions, we echo this signal to the opto isolator to let the stoves MCU control the burn rate for all 4 factory power levels

  • auger.output is GPIO2 on the tywe1s chip that is now rerouted to the auger opto isolator chip

P5 is a new power level we are defining in the stove, we take over the auger function from the MCU
and create our own auger feed rate on/off signal in the tywe1s chip using GPIO2 to feed
the opto isolator that controls the auger

  • auger.input=GPIO1 # we feed the auger control signal from the MCU to this unused GPIO1 on the tywe1s
  • auger.output=GPIO2 # we send this unused GPIO2 on the tywe1s to the opto isolator pin that controls the auger
  • P5 is a switch in home assistant that when on, creates a new power level P5

ESPHome psudo code:

if exhaust.temp >= 250 
  pot.burning == true
  else pot.burning==false #we now know the pellets are burning in the burn pot

#echo auger pin
 if auger.input == low and not P5 #auger is triggered by MCU and we are not using new P5 power level
   auger.output == low #turn on the auger motor to feed pellets
   else auger.output ==high #turn it off
   
#create new power level that controls the auger opto isolator pin
 while P5 true and pot.burning # only take control if the stove is lit and we throw the new P5 level switch in HA
   auger.output== low #turn on auger
   delay 1.5s
   auger.output == high #turn it off
   delay 10s
   endwhile

To control the Auger motor in ESPHome, you can use the binary_sensor and switch components. The binary_sensor will be used to receive the input signal from the MCU’s auger control pin, and the switch will be used to control the output signal to the opto isolator.

Here is an example of how this could be implemented in ESPHome:

binary_sensor:
  - platform: gpio
    pin: GPIO1
    name: "Auger Input"

switch:
  - platform: gpio
    pin: GPIO2
    name: "Auger Output"
    on_turn_on:
      - binary_sensor.auger_input.publish: "on"
    on_turn_off:
      - binary_sensor.auger_input.publish: "off"

Then, in your Home Assistant automation, you can use the input_boolean component to create a switch for the new power level P5.

When this switch is turned on, it will turn on the auger output switch in ESPHome, which will control the opto isolator and ultimately the Auger motor.

Here is an example of how this could be implemented in Home Assistant:


input_boolean:
  p5:
    name: "P5"

automation:
  - alias: Auger P5 control
    trigger:
      platform: state
      entity_id: input_boolean.p5
    action:
      - service: switch.turn_on
        entity_id: switch.auger_output

This is just one way to implement this functionality, and there may be other ways to achieve the same result. You can also use ESPHome’s Template and lambda components to create more complex logic for controlling the Auger motor.

I hope this helps! Let me know if you have any other questions.

That would certainly work and this is exactly how I’d do it in an automation!

However, I want to remove home assistant from the equation. This is a burning pellet stove, and keeping the control inside the esp with ESPHome is critical. If home assistant crashes and the auger motor is ON, guess what happens… pellets are continuously fed into the burning stove. It doesn’t end well after that.

I know the code to do this inside ESPHome is possible, just above my rudimentary programming ability. All my experience is based on controlling esp devices from home assistant, not contained solely within ESPHome…

In that case, you can use the “binary_sensor” and “switch” components in ESPHome to control the Auger motor without using Home Assistant.

To do this, you will need to create a binary sensor that detects when the Auger motor needs to be turned on, and a switch that controls the Auger motor.

Here is some sample code that you can use as a starting point:

binary_sensor:
  - platform: gpio
    pin: 12
    name: "Auger Motor Sensor"

switch:
  - platform: gpio
    pin: 14
    name: "Auger Motor"
    id: auger_motor

# This is the code that will run when the binary sensor detects that the Auger motor needs to be turned on
on_binary_sensor:
  auger_motor_sensor:
    then:
      # Turn on the Auger motor
      - switch.turn_on: auger_motor

# This is the code that will run when the binary sensor detects that the Auger motor needs to be turned off
on_binary_sensor:
  auger_motor_sensor:
    then:
      # Turn off the Auger motor
      - switch.turn_off: auger_motor

This code will turn the Auger motor on when the binary sensor detects that it is needed, and turn it off when the binary sensor no longer detects a need for the motor to be running. You can adjust the pin numbers and other settings as needed to match your specific setup.

Once you have written your code, you can upload it to your ESP device using ESPHome. I hope this helps!

1 Like

Ok, I’m totally following!
I think I can come up with a template sensor for my If then statements, but I get stuck trying to implement a While Do loop. Any insight there?

while P5 true and pot.burning # only take control if the stove is lit and we throw the new P5 level switch in HA
   auger.output== low #turn on auger
   delay 1.5s
   auger.output == high #turn it off
   delay 10s
   endwhile

In ESPHome, you can use the “while” keyword to create a loop that will continue to execute a set of instructions until a specified condition is met.

To use this feature, you will need to specify the condition that will trigger the loop to end, as well as the instructions that should be executed while the loop is running.

Here is an example of how you could use a “while” loop in ESPHome to control the auger motor of your pellet stove:

while P5.state == true and pot.burning:
  auger.turn_on()
  delay(1.5s)
  auger.turn_off()
  delay(10s)

In this example, the “while” loop will continue to execute as long as the P5 binary sensor is in the “true” state and the “pot.burning” variable is true.

This means that the loop will only run when the stove is lit and the P5 level switch is activated in Home Assistant. Inside the loop, the “auger” switch will be turned on for 1.5 seconds, then turned off for 10 seconds. This process will repeat until the loop ends.

1 Like

Hmmm. I searched the docs but must have missed that! Ok, I’m headed to the shop to cut some traces on an MCU!

Much appreciated!

Jeff

2 Likes

These on_binary_sensor blocks are identical. How do they turn on and then off??

It also throws an error

Component not found: on_binary_sensor <---- no such component in ESPHOME
auger_motor_sensor:
then:
- switch.turn_on: auger_motor

And this error

ERROR Error while reading config: Invalid YAML syntax:

Duplicate key “on_binary_sensor”
in “/config/esphome/dev-wood-pellet-stove.yaml”, line 67, column 1:
on_binary_sensor:
^
NOTE: Previous declaration here:
in “/config/esphome/dev-wood-pellet-stove.yaml”, line 61, column 1:
on_binary_sensor:
^

I think this might be what you were thinking? From the docs:

binary_sensor.is_on / binary_sensor.is_offCondition

This Condition checks if the given binary sensor is ON (or OFF).

# In some trigger: 
on_...:
  if:
    condition:
      # Same syntax for is_off
      binary_sensor.is_on: my_binary_sensor

You are right, apologize for that… the code provided is an example of incorrect syntax for the ESPHome configuration file.

The on_binary_sensor block should only be defined once, and the code inside the block should specify both the actions to take when the binary sensor is turned on and when it is turned off. Here’s an example of how the code could be written correctly:

on_binary_sensor:
  auger_motor_sensor:
    then:
      # Turn on the Auger motor when the binary sensor is turned on
      - switch.turn_on: auger_motor
      # Turn off the Auger motor when the binary sensor is turned off
      - switch.turn_off: auger_motor

The code in the previous example provided defines two separate on_binary_sensor blocks with the same name, which is not allowed.

This is why it is giving an error saying that the on_binary_sensor component was not found and that there is a duplicate key.

Regarding your follow up question, yes that is correct! The code provided is an example of using the binary_sensor.is_on condition to check whether a binary sensor is turned on or off.

In this code, the if block will only be executed if the my_binary_sensor binary sensor is turned on.

I don’t think “on_binary_sensor:” is a trigger in ESPHome. I get errors when validating and it’s nowhere in any google search for the term.

Perhaps theres another way to trigger when a sensor changes?

an if then condition could work if only I can find the right trigger, its obviously nor on_boot… it has to be based on the binary sensor somehow.

  on_boot:  <-- what trigger to use???
    then:
      - if:
          condition:
            - binary_sensor.is_off: "Auger_pin_from_MCU"
          then:
            - switch.turn_off: "ESP_Auger_to_opto_isolator"
      - if:
          condition:
            - binary_sensor.is_on: "Auger_pin_from_MCU"
          then:
            - switch.turn_on: "ESP_Auger_to_opto_isolator"

EDIT: I figured it out. “on_state”… thats the key!!!

binary_sensor:
  - platform: gpio
    pin: GPIO4
    id: esph_house_auger_sensor_from_mcu
    name: "esph House Auger Sensor from MCU" #pinAuger signal from MCU, goes low when motor is running
    filters:
      - invert:

# This is the code that will run when the binary sensor detects that the Auger motor needs to be turned off
    on_state:
      then:
     # Turn on the Auger motor
        - if:
            condition:
              - binary_sensor.is_off: esph_house_auger_sensor_from_mcu
            then:
              - switch.turn_off: auger_output_to_optoisolator
        - if:
            condition:
              - binary_sensor.is_on: esph_house_auger_sensor_from_mcu
            then:
              - switch.turn_on: auger_output_to_optoisolator

this works perfectly. The output echos the input exactly. And its all done inside ESPHome.

image

Now I can add my own timing routine for the Auger on a new Power level.