Using two relays on one ESP-01 using MQTT

Hey guys,

first of all: sorry for my bad english. I try my very best ^^

i am a little newbie with the ESP8266 and Arduino. I play around with it since 2 weeks and i already got most things work :slight_smile:

I build some boards for the ESP-01 with two relays. One relay on GPIO 2 and one on GPIO 0.
I connected it via MQTT with ioBroker. I can now switch the relay state with:

0 = Relay_1 off
1 = Relay_1 on
2 = Relay_2 off
3 = Relay_2 on

After this was working i installed the HomeKit Adapter in ioBroker to control the relays via Siri on the iPhone. Unfortunately the HomeKit App will just send a "true" or "false" to the ESP.
So i changed the Sketch a little bit and now i am able to control the first relay:

0 or false = Relay_1 off
1 or true = Relay_1 on
2 = Relay_2 off
3 = Relay_2 on

The problem is, that i can't find a solution for the second relay, because when i add the "true/false" to the second relays, Siri would always turn on/off both relays, as the ESP can't distinguish which relay was meant.

Is there a solution for the ESP to distinguish a simple true/false ?

I ope u guys can maybe help me :slight_smile:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Bounce2.h>
#include <EEPROM.h>
#include <ESP8266WebServer.h>


const char* ssid = "...";
const char* password = "...";
const char* mqtt_server = "192.168.178.23";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

const char* clientID = "ESP 2";
//const char* outTopic = "ESPout1";
const char* inTopic1 = "ESPin2.1";
const char* inTopic2 = "ESPin2.2";

#define RelaisPin 2  // Relais
int active_low = 1;
int relay_pin1 = 2;
int relay_pin2 = 0;
bool relayState1 = LOW;
bool relayState2 = LOW;

ESP8266WebServer server(80);        // Serverport  hier einstellen
int val = 0; 

// Instantiate a Bounce object :
Bounce debouncer = Bounce(); 


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) {
    for(int i = 0; i<500; i++){
      delay(1);
    }
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  String message;
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
    char c = (char)payload[i];
    message += c;
  }
  Serial.println();

  if ((char)payload[0] == '0' || message == "false") {
    digitalWrite(relay_pin1, LOW);
    Serial.println("relay_pin1 -> LOW");
    relayState1 = LOW;
    EEPROM.write(0, relayState1);
    EEPROM.commit();
  } else if ((char)payload[0] == '1' || message == "true") {
    digitalWrite(relay_pin1, HIGH);
    Serial.println("relay_pin1 -> HIGH");
    relayState1 = LOW;
    EEPROM.write(0, relayState1);
    EEPROM.commit();
  } else if ((char)payload[0] == '2') {
    digitalWrite(relay_pin2, LOW);
    Serial.println("relay_pin2 -> LOW");
    relayState2 = LOW;
    EEPROM.write(1, relayState2);
    EEPROM.commit();
  } else if ((char)payload[0] == '3') {
    digitalWrite(relay_pin2, HIGH);
    Serial.println("relay_pin2 -> HIGH");
    relayState2 = HIGH;
    EEPROM.write(1, relayState2);
    EEPROM.commit(); 
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(clientID)) {
      Serial.println("connected");
      client.subscribe(inTopic1);
      client.subscribe(inTopic2);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      for(int i = 0; i<5000; i++){
//        extButton();
        delay(1);
      }
    }
  }
}

void setup() {
  EEPROM.begin(512);              // Begin eeprom to store on/off state
  pinMode(relay_pin1, OUTPUT);     // Initialize the relay pin as an output
  pinMode(relay_pin2, OUTPUT);     // Initialize the relay pin as an output 
  relayState1 = EEPROM.read(0);
  digitalWrite(relay_pin1,relayState1);
  relayState2 = EEPROM.read(1);
  digitalWrite(relay_pin2,relayState2);
  
  debouncer.interval(50);         // Input must be low for 50 ms
  
  Serial.begin(115200);
  setup_wifi();                   // Connect to wifi 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

Is there a solution for the ESP to distinguish a simple true/false ?

You already know the answer to that. Yes, it can distinguish true and false. But, it can't guess which relay you mean to turn on when it gets true.

Ok, i will try to explain it a little bit better...

I have connected two relays on a ESP-01.
Relay_1 is connected to GPIO 2
Relay_2 is connected to GPIO 0

In the sketch i declared:

int relay_pin1 = 2;
int relay_pin2 = 0;

Later in the sketch i got this part:

if ((char)payload[0] == '0' || message == "false") {
    digitalWrite(relay_pin1, LOW);
    Serial.println("relay_pin1 -> LOW");
    relayState1 = LOW;
    EEPROM.write(0, relayState1);
    EEPROM.commit();
  } else if ((char)payload[0] == '1' || message == "true") {
    digitalWrite(relay_pin1, HIGH);
    Serial.println("relay_pin1 -> HIGH");
    relayState1 = LOW;
    EEPROM.write(0, relayState1);
    EEPROM.commit();
  }

So actually it's like this:
when i send a payload with "0" or "false" the Relay_1 (GPIO 2) will be turned off.
when i send a payload with "1" or "true" the Relay_1 (GPIO 2) will be turned on.

That's good so far...

Farther the sketch contains this part for Relay_2:

else if ((char)payload[0] == '2') {
    digitalWrite(relay_pin2, LOW);
    Serial.println("relay_pin2 -> LOW");
    relayState2 = LOW;
    EEPROM.write(1, relayState2);
    EEPROM.commit();
  } else if ((char)payload[0] == '3') {
    digitalWrite(relay_pin2, HIGH);
    Serial.println("relay_pin2 -> HIGH");
    relayState2 = HIGH;
    EEPROM.write(1, relayState2);
    EEPROM.commit(); 
  }

So,
when i send a payload with "2" the Relay_2 (GPIO 0) will be turned off.
when i send a payload with "3" the Relay_2 (GPIO 0) will be turned on.

If i would implement the - || message == "false" - part to the payload of Relay_2 it would be the following scenario:

when i send a payload with "0" the Relay_1 (GPIO 2) will be turned off.
when i send a payload with "1" the Relay_1 (GPIO 2) will be turned on.
when i send a payload with "2" the Relay_2 (GPIO 0) will be turned off.
when i send a payload with "3" the Relay_2 (GPIO 0) will be turned on.

when i send a payload with "false" both relays (GPIO 0 and 2) will be turned off.
when i send a payload with "true" both relays (GPIO 0 and 2) will be turned on.

Because the problem is, that both parts of the Sketch would react on the "true" and "false" payload.

Unfortunately the iPhone just sends one true/false per click in the HomeKit app.
As i wrote its all connected via ioBroker on a Raspberry.

So the question is, if there is a possibility to distinguish the "true" for Relay_1 and the "true" for Relay_2...
It would be always the same payload... i know... :confused:

Seems not possible i think...