Complex ESP projects

Hallo, I’m new to Home assistant and I currently have set up a couple of ESP8266. These are just some basic fastLED lights.

However, i have a ESP8266 running that is controlling my curtains. It got 4 pushbuttons, 2 step counters and 2 motor H-bridges connected to it. I want to connect this to my home assistant. I know that this is a bit to complicated for ESPHome. I was thinking that it might be possible to connect a second ESP to my project that communicated with my home assistant. It then sends these commends via serial to the second ESP. Is something like this possible?

Adding a second ESP would just make it more complicated. Use an ESP32 (as it has more i/o, better peripherals and cpu) and bung it all on the one device.

1 Like

Sorry, I guess I wasn’t explaining myself correctly. It’s not that I haven’t enough GPIO pins. I already have the automatic curtains working for a while now. It’s just not integrated with my Home assistant. It’s a stand-alone project. And I want to make the ESP8266 work with Home assistant. But the ESPHome add-on only supports simple code for things like switches, sensors and actuators (Or am I wrong?), and not complex code with interrupts and EEPROM excess.

So the question was how I would be able to make that work with ESPhome

Here is the code that’s currently running on my ESP8266. (it’s not pretty). I have the AdafruitIO connection setup for now but that is not permanent. I would like to remove that, and use Home assistant instead for the wireless controlls

#include "parameters.h"
#include "config.h"
AdafruitIO_Feed *openFeed = io.feed("open");

void Readbuttons() {
  But_ld = digitalRead(Button_ld);
  But_lu = !digitalRead(Button_lu);
  But_rd = digitalRead(Button_rd);
  But_ru = digitalRead(Button_ru);

  if (But_ld == HIGH) {
    But_state_ld = true;
  }
  if (But_lu == HIGH) {
    But_state_lu = true;
  }
  if (But_rd == HIGH) {
    But_state_rd = true;
  }
  if (But_ru == HIGH) {
    But_state_ru = true;
  }
}

void Disable_motor(byte side) {
  if (side == 1 || side == 3) {
    digitalWrite(LM_up, LOW);
    digitalWrite(LM_down, LOW);
    moveup_l = false;
    movedown_l = false;
  }
  if (side == 2 || side == 3) {
    digitalWrite(RM_up, LOW);
    digitalWrite(RM_down, LOW);
    moveup_r = false;
    movedown_r = false;
  }
}

void Move() {
  digitalWrite(LM_up, But_lu);
  digitalWrite(LM_down, But_ld);
  digitalWrite(RM_up, But_ru);
  digitalWrite(RM_down, But_rd);
  if(But_lu == true){
    moveup_l = true;
    movedown_l = false;
  }
  else if(But_ld == true){
    moveup_l = false;
    movedown_l = true;
  }
  if(But_ru == true){
    moveup_r = true;
    movedown_r = false;
  }
  if(But_rd == true){
    moveup_r = false;
    movedown_r = true;
  }
}

bool Calibrate() {
  bool x = 0;
  Readbuttons();
  if (But_lu != HIGH || But_ru != HIGH) {
    timer = millis();
    Move();
  }
  else {
    Disable_motor(3);
  }
  if (millis() - timer > 2000) {
    x = 1;
  }
  delay(10);
  return x;
}

void Automatic_l(int x){
  if (pos_l < x){
    digitalWrite(LM_up, HIGH);
    digitalWrite(LM_down, LOW);
    moveup_l = true;
    movedown_l = false;
  }
  else if (pos_l > x){
    digitalWrite(LM_down, HIGH);
    digitalWrite(LM_up, LOW);
    moveup_l = false;
    movedown_l = true;
  }
  else{
    lu_state = false;
    ld_state = false;
    Disable_motor(1);
  }
}

void Automatic_r(int x){
  if (pos_r < x){
    digitalWrite(RM_up, HIGH);
    digitalWrite(RM_down, LOW);
    moveup_r = true;
    movedown_r = false;
  }
  else if (pos_r > x){
    digitalWrite(RM_down, HIGH);
    digitalWrite(RM_up, LOW);
    moveup_r = false;
    movedown_r = true;
  }
  else{
    ru_state = false;
    rd_state = false;
    Disable_motor(2);
  }
}

void setup() {
  //pinMode(3, FUNCTION_3);
  //pinMode(1, FUNCTION_3);
  Serial.begin(115200);

  pinMode(LM_up, OUTPUT);
  pinMode(LM_down, OUTPUT);
  pinMode(LM_sensor, INPUT);
  pinMode(RM_up, OUTPUT);
  pinMode(RM_down, OUTPUT);
  pinMode(RM_sensor, INPUT);

  pinMode(Button_ld, INPUT);
  pinMode(Button_rd, INPUT);
  pinMode(Button_ru, INPUT);
  pinMode(Button_lu, INPUT);

  attachInterrupt(digitalPinToInterrupt(LM_sensor), Left_steps, CHANGE);
  attachInterrupt(digitalPinToInterrupt(RM_sensor), Right_steps, CHANGE);

  Serial.println();
  Serial.print("Connecting to Adafruit IO");
  io.connect();

  while(io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.println();
  Serial.println(io.statusText());
  openFeed->onMessage(toggleState);
  openFeed->get();
}


void loop() {
  io.run();
  switch (state) {
    case 1:        //calibrating posistion
      //io.run();
      while (calibrated == false) {
        calibrated = Calibrate();
      }
      pos_l = 0;
      pos_r = 0;
      state = 2;
      But_state_ld = false;
      But_state_lu = false;
      But_state_rd = false;
      But_state_ru = false;
      break;

    case 2:      //normal opperate mode
      //io.run();
      Readbuttons();
      //-------------------------------------------
      //-------------------Left--------------------
      //-------------------------------------------
      // Opening left curtain by holding down the button------------------------------------
      if (But_state_lu == true && But_state_ld == false) {
        if (But_lu == HIGH) {
          if ((millis() - timer_l > 500) && (pos_l < Pmax)) {
            Move();
          }
          else{
            Disable_motor(1);
          }
        }
        // Toggle left curtain open
        else if ((millis() - timer_l < 500) && (lu_state == false)){
          lu_state = true;
          But_state_lu = false;
        }
        else {
          lu_state = false;
          But_state_lu = false;
          Disable_motor(1);
        }
      }

      // Closing left curtain by holding down the button------------------------------------
      else if (But_state_lu == false && But_state_ld == true) {
        if (But_ld == HIGH) {
          if ((millis() - timer_l > 500) && (pos_l > 0)) {
            Move();
          }
          else{
            Disable_motor(1);
          }
        }
        // Toggle left curtain closed
        else if ((millis() - timer_l < 500) && (ld_state == false)) {
          ld_state = true;
          But_state_ld = false;
        }
        else {
          But_state_ld = false;
          ld_state = false;
          Disable_motor(1);
        }
      }
      else {
        timer_l = millis();
        But_state_ld = false;
        But_state_lu = false;
      }
      
      //-------------------------------------------
      //------------------Right--------------------
      //-------------------------------------------
      // Opening right curtain by holding down the button------------------------------------
      if (But_state_ru == true && But_state_rd == false) {
        if (But_ru == HIGH) {
          if ((millis() - timer_r > 500) && (pos_r < Pmax)) {
            Move();
          }
          else{
            Disable_motor(2);
          }
        }
        // Toggle left curtain open
        else if ((millis() - timer_r < 500) && (ru_state == false)){
          ru_state = true;
          But_state_ru = false;
        }
        else {
          ru_state = false;
          But_state_ru = false;
          Disable_motor(2);
        }
      }

      // Closing right curtain by holding down the button------------------------------------
      else if (But_state_ru == false && But_state_rd == true) {
        if (But_rd == HIGH) {
          if ((millis() - timer_r > 500) && (pos_r > 0)) {
            Move();
          }
          else{
            Disable_motor(2);
          }
        }
        // Toggle right curtain closed
        else if ((millis() - timer_r < 500) && (rd_state == false)) {
          rd_state = true;
          But_state_rd = false;
        }
        else {
          But_state_rd = false;
          rd_state = false;
          Disable_motor(2);
        }
      }
      else {
        timer_r = millis();
        But_state_rd = false;
        But_state_ru = false;
      }

      //-------------------------------------------
      //------------------Move to position---------
      //-------------------------------------------
      if(lu_state == true){
        Automatic_l(left_openpos);
      }
      if(ld_state == true){
        Automatic_l(0);
      }

      if(ru_state == true){
        Automatic_r(right_openpos);
      }
      if(rd_state == true){
        Automatic_r(0);
      }

      //Check for calabrating press------------------------------
      if (But_lu == HIGH && But_ld == HIGH) {
        if (millis() - timer > 1000) {
          calibrated = false;
          state = 1;
        }
      }
      else {
        timer = millis();
      }
      break;

    case 3: // Executing google assistant command-----------------------
      if (google_toggle == 1){
        lu_state = true;
        ru_state = true;
      }
      else{
        ld_state = true;
        rd_state = true;
      }
      state = 2;      
      break;
      
    case 4:
      break;
    case 5:
      break;
    case 6:
      break;
    case 7:
      break;
  }
}


ICACHE_RAM_ATTR void Left_steps() {
  if (moveup_l == true) {
    pos_l++;
  }
  if (movedown_l == true) {
    pos_l--;
  }
  Serial.println(pos_l);
}

ICACHE_RAM_ATTR void Right_steps() {
  if (moveup_r == true) {
    pos_r++;
  }
  if (movedown_r == true) {
    pos_r--;
  }
  Serial.println(pos_r);
}

void toggleState(AdafruitIO_Data *data) {

  google_toggle = data->toInt();
  //google_toggle_updated = 1
  Serial.println("Received Press: ");
  Serial.println(data->toInt());
  state = 3;
}

If you feel that the template and automation options in ESPHome are not powerful enough, keep using your code and communicate with home assistant using mqtt. It integrates very well and reliably too.

Interrupt support is limited to those that are exposed by ESPHome components, deep sleep wake pins for example I am pretty sure are interrupt driven rather than polled.

Thank you. I didnt understand the mqtt at first. But with some hours of trail and error i got it working. It was exactly what I needed!