So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By wkellen
#84637 I have a project I am working on. I have a Raspberry Pi 3B that is running hass.io. I just got it running with a DHT11 giving temperatures and humidity. Now I am looking to add an automation routine that will happen at sunrise and sunset every day.

I have an ESP8266 on a module board. It is connected to a relay board that will control a couple of 12v wiper motors. It is also connected to 2 limit switches. I wrote the code using some examples and a LOT of reading/searching. I have totally confused myself on the code to the point I am not sure I have it anywhere close to correct. Could someone look through it and tell me if I am at least in the ballpark?

I want it to listen for the door switch to be changed in Home Assistant. If switched to "ON", I want it to open a door and run a feed auger for 15 seconds. If it is switched to off, I want it to close the door. Of course I need it to stop the door motor when the limit switch is hit.

Code: Select all
//Included Libs
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

//Pin Definitions
#define PowerPin 4
#define PowerInvPin 5
#define OpenLimitPin 12
#define ClosedLimitPin 13
#define FeederPin 14

// Update these with values suitable for your network.
const char* ssid = "wirelessssid";
const char* password = "password";
const char* mqtt_server = "192.168.0.101";

WiFiClient espClient;
PubSubClient client(espClient);


String door;
String strTopic;
String strPayload;
String DoorStatus;
String DoorStatus1;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

//Callback Function for Door
void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';
  strTopic = String((char*)topic);
  if(strTopic == "ha/door")
   {
    door = String((char*)payload);
    if(door == "ON")
      {
        Serial.println("ON");
        digitalWrite(PowerPin, HIGH);
        DoorStatus = digitalRead(OpenLimitPin);
        while(DoorStatus != "LOW")
         {
          DoorStatus = digitalRead(OpenLimitPin);
          delay(250);
         }
        digitalWrite(PowerPin, LOW);
        digitalWrite(FeederPin, HIGH);
        delay(1500);
        digitalWrite(FeederPin, LOW); 
         }
    else
     {
      Serial.println("OFF");
      DoorStatus1 = digitalRead(ClosedLimitPin);
      if (DoorStatus1 != "LOW")
       {
        digitalWrite(PowerInvPin, HIGH);
        delay(500);
        digitalWrite(PowerPin, HIGH);
        while (DoorStatus1 != "LOW")
         {
          DoorStatus1 = digitalRead(OpenLimitPin);
          delay(250);
         }
        digitalWrite(PowerPin, LOW);
        delay(500);
        digitalWrite(PowerInvPin, LOW);
       }
    }
   }
}
 

// Reconnect Function
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.subscribe("ha/#");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
 
//Setup Function
void setup()
{
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  //Pin Modes
  pinMode(PowerPin, OUTPUT);
  digitalWrite(PowerPin, LOW);
  pinMode(PowerInvPin, OUTPUT);
  digitalWrite(PowerInvPin, LOW);
  pinMode(OpenLimitPin, INPUT);
  pinMode(ClosedLimitPin, INPUT);
  pinMode(FeederPin, OUTPUT);
  digitalWrite(FeederPin, LOW);
 
}
 
//Loop Function
void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}



Thanks!
User avatar
By wkellen
#84663 So this didn't work.
Code: Select all//Pin Definitions
#define PowerPin 4
#define PowerInvPin 5
#define OpenLimitPin 12
#define ClosedLimitPin 13
#define FeederPin 14


I changed it to:
Code: Select allint PowerPin = 4;
int PowerInvPin = 5;
int OpenLimitPin = 12;
int ClosedLimitPin = 13;
int FeederPin = 14;


I also had to change:
Code: Select allwhile(DoorStatus != "LOW")


to

Code: Select allwhile(DoorStatus != 0)


then
Code: Select allpinMode(OpenLimitPin, INPUT);
pinMode(ClosedLimitPin, INPUT);


to

Code: Select allpinMode(OpenLimitPin, INPUT_PULLUP);
  pinMode(ClosedLimitPin, INPUT_PULLUP);

because the pins were staying whatever the last status was and giving false readings.

This is what my final code ended up looking like.
Code: Select all//Included Libs
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

//Pin Definitions
/*#define PowerPin 2
#define PowerInvPin 16
#define OpenLimitPin 12
#define ClosedLimitPin 13
#define FeederPin 14
This method did NOT work.
*/

int PowerPin = 4;
int PowerInvPin = 5;
int OpenLimitPin = 12;
int ClosedLimitPin = 13;
int FeederPin = 14;


// Update these with values suitable for your network.
const char* ssid = "wirelessid";
const char* password = "password";
const char* mqtt_server = "192.168.0.101";

WiFiClient espClient;
PubSubClient client(espClient);


String door;
String strTopic;
String strPayload;
int DoorStatus;
int DoorStatus1;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

//Callback Function for Door
void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';
  strTopic = String((char*)topic);
  if(strTopic == "coop/door")
   {
    door = String((char*)payload);
    if(door == "ON")
      {
        Serial.println("ON");
        digitalWrite(PowerPin, HIGH);
        Serial.println("Light ON");
        DoorStatus = digitalRead(OpenLimitPin);
        Serial.println(DoorStatus);
        while(DoorStatus != 0)
         {
          DoorStatus = digitalRead(OpenLimitPin);
          Serial.println(DoorStatus);
          delay(250);
         }
        digitalWrite(PowerPin, LOW);
        client.publish("coop/door1","OPEN");
        Serial.println("Light OFF");
        digitalWrite(FeederPin, HIGH);
        Serial.println("Feeder ON");
        delay(15000);
        digitalWrite(FeederPin, LOW);
        Serial.println("Feeder OFF"); 
         }
    else
     {
      Serial.println("OFF");
      DoorStatus1 = digitalRead(ClosedLimitPin);
      Serial.println(DoorStatus1);
      if (DoorStatus1 != 0)
       {
        digitalWrite(PowerInvPin, HIGH);
        Serial.println("Closed Light ON");
        delay(500);
        digitalWrite(PowerPin, HIGH);
        Serial.println("Power Light ON");
        while (DoorStatus1 != 0)
         {
          DoorStatus1 = digitalRead(ClosedLimitPin);
          Serial.println(DoorStatus1);
          delay(250);
         }
        digitalWrite(PowerPin, LOW);
        Serial.println("Power Light OFF");
        delay(500);
        digitalWrite(PowerInvPin, LOW);
        client.publish("coop/door1","CLOSED");
        Serial.println("Closed Light OFF");
       }
    }
   }
}
 

// Reconnect Function
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
      Serial.println("connected");
      client.publish("coop/door1","OPEN");
      // Once connected, publish an announcement...
      client.subscribe("ha/#");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
 
//Setup Function
void setup()
{
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  //Pin Modes
  pinMode(PowerPin, OUTPUT);
  digitalWrite(PowerPin, LOW);
  pinMode(PowerInvPin, OUTPUT);
  digitalWrite(PowerInvPin, LOW);
  pinMode(OpenLimitPin, INPUT_PULLUP);
  pinMode(ClosedLimitPin, INPUT_PULLUP);
  pinMode(FeederPin, OUTPUT);
  digitalWrite(FeederPin, LOW);
 
}
 
//Loop Function
void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}


I have since changed from a manually installed Home Assistant to the hass.io version flashed to a SD Card. For some reason the mqtt connects, but will not actually show the message going through the network. That is a different problem for a different topic discussion though.

Thanks!
User avatar
By wkellen
#84672 It is always the little things. I found this unchanged.

Code: Select all// Reconnect Function
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
      Serial.println("connected");
      client.publish("coop/door1","OPEN");
      // Once connected, publish an announcement...
      client.subscribe("ha/#");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
 


I changed
Code: Select all client.subscribe("ha/#");

to
Code: Select all client.subscribe("coop/door");


Now it at least catches the "coop/door" topic and runs the loop accordingly.

My last thing to fix is:
Code: Select allclient.publish("coop/door1","OPEN");


This does not publish "OPEN" to the MQTT network at all.

Can anyone tell me how to send "OPEN" to coop/door1 with MQTT in the code to tell my hassio the state of the limit switch?

I also tried
Code: Select allclient.connect("arduinoClient", mqtt_user, mqtt_password, mqtt_topic, 0, 0, "OPEN");

it still doesn't publish anything at all to MQTT network. I have a monitor program running that shows me all messages sent to all topics. It catches the ones from hass.io to the esp8266, so I know the monitor is working and the code I have is not sending anything back to tell it the door is open or closed.

Thanks,