How do I control several relays from remote button press(s)?



  • I'm fairly new to programming, Don't quite understand setting up the (URI?) or URL request for each relay.

    My goal is to have one main(AP) d1 mini connected to a small bank of relays, then other d1 minis(stations) located in other areas control their designated device/relay on the main d1 when their button is pressed. How can I accomplish this? Then, how many relays can I operate on the main mini before I run out of pins?

    Taking a different appoach this time, these will be physical on/off buttons, NOT html presses from smartphone or computer webpage. My 1st attempt at a smart home.

    This is what I had before the big crash of 217(terrible pun):

    /*This sketch is to turn ON/OFF relay shield which is connected to an etension
     * cord
     * for Christmas tree lights or whatever I want to turn on/off remotely
     */
    
    #include <ESP8266WiFi.h>
    #define relayPin 5//  Initialize D1 aka GPIO-5 as an output on the WeMOS board
    
    
    //  CONNECT TO WLAN
    const char* ssid = "ssid";//***my ssid***
    const char* password = "password";//***my password***
    
    //int ledPin = 2; // assign pin 2 for LED (GPIO2)
    
    //  CREATE WEBSERVER
    WiFiServer server(80);
    
    
    void setup() {
    //  pinMode(LED_BUILTIN, OUTPUT);  // Initialize the LED_BUILTIN pin as an output
    
      pinMode(relayPin, OUTPUT);     // Initialize the D1 aka GPIO5 as an output
    
    
    
      Serial.begin(115200);          //I'm thinking other devices communicate at different baud rates?
      delay(10);
    
    
    //  pinMode(ledPin, OUTPUT);
    //  digitalWrite(ledPin, LOW);
    
      // Connect to WiFi network
      Serial.println();
      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");
    
      // Start the server
      server.begin();
      Serial.println("Server started");
    
      // Print the IP address
      Serial.print("Use this URL to connect: ");
      Serial.print("http://");
      Serial.print(WiFi.localIP());
      Serial.println("/");
    
    }
    
    void loop() {
      // Check if a client has connected
      WiFiClient client = server.available();
      if (!client) {
        return;
      }
    
      // Wait until the client sends some data
      Serial.println("new client");
      while (!client.available()) {
        delay(1);
      }
    
      // Read the first line of the request
      String request = client.readStringUntil('\r');
      Serial.println(request);
      client.flush();
    
      // Match the request
    
      int value = LOW;
      if (request.indexOf("/LED=ON") != -1) {
      //  digitalWrite(ledPin, LOW);
        digitalWrite(relayPin, HIGH);   // Turn the RELAY on (Note the Relay is active high
        value = LOW;
      }
      if (request.indexOf("/LED=OFF") != -1) {
     //   digitalWrite(ledPin, HIGH);
        digitalWrite(relayPin, LOW);   // Turn the RELAY on (Note the Relay is active high
        value = HIGH;
      }
    
      // Set ledPin according to the request
      //digitalWrite(ledPin, value);
    
    
      // Return the response
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println(""); //  do not forget this one
      client.println("<!DOCTYPE HTML>");
      client.println("<html>");
    
      client.println("Title for bank of relays<br>");
      client.println("Relay 1 is:  ");
    
    
      if (value == LOW) {
        client.print("<b>On.");
      } else {
        client.print("<b>Off.");
      }
      client.println("<center><HR><BR>");
      client.println("<a href=\"/LED=ON\"><button>ON<\button></a><br><br>");
    
      client.println("<a href=\"/LED=OFF\"><button>OFF<\button></a><br>");
      client.println("</html>");
    
      delay(1);
      Serial.println("Client disconnected");
      Serial.println("");
    }
    

    Any help is greatly appreciated



  • @marine_hm

    I think it's possible to do what you want with this architecture, but most people (more expert than me) recommend using a more powerful hub to sync multiple devices. Blynk, MQTT, ITTT, and others exist for this purpose.

    Sorry, I'm not more helpful.



  • Interesting... I just learned something new. Can a Wemos D1 mini be a MQTT broker? I'm thinking not but it's worth asking. Hoping that I can, that way I can have a Wemos in the middle handling requests, publishing, subscriptions. I hope I understood that right. Otherwise I have to convince our IT guys to allow me to run a program on their server. Probably not going to happen.

    I just tried adding the pubsub library to arduino IDE and get an download error.



  • @marine_hm You can use a raspberry pi as a broker. There are brokers for MQTT, as well as for Blynk, and other systems.



  • @Roo-ster
    Unfortunately, I know nothing about rasberry Pi. And sadly enough, I have one sitting collecting dust. My brother gave it to me along with some car that is run by the Pi and gets driven by an android phone. I have had fun leaning arduino ide and programming chips along with Wemos d1 minis to do small tasks, therefore had no interest in the Pi. Kind of like me working on a Chevy car most of my life and someone asking me to work on their Audi

    Does a Pi have Wifi? No, but a dongle to make it wifi. Maybe do-able. Is there much transition between Arduino Uno's and a Pi?

    Pi runs on Python? which is another IDE. With it's own set of protocols, should be pretty similar.

    I'm terrible at programming in arduino.ide I am getting better, not bad for a self learner.



  • @marine_hm
    The original RPi and RPi 2 have a wired ethernet connection and can add wifi through a usb adapter. The RPi 3 has wifi built-in. They all run a version of the Linux operating system and there are versions of MQTT and Blynk servers that run under that. I don't have a Pi so I can't tell you too much more but there are plenty of tutorials on-line.



  • @Roo-ster
    My Pi Zero W came in, I've got Mosquitto MQTT running. I'm able to get an LED to switch on and off via SSH connection from my laptop. What I want to do is add a toggle switch to the sketch to turn on an attached LED and publish a message that turns on a remote wemos LED via that MQTT message. This is what I've got so far. Doesn't seem to work in my favor:

    /*
    
     Starting with the "basic ESP8266 MQTT example", making modifications for my ongoing project as I go.
    
     This sketch demonstrates the capabilities of the pubsub library in combination
     with the ESP8266 board/library.
    
     It will reconnect to the server if the connection is lost using a blocking
     reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to  achieve the same result without blocking the main loop.
    
    My goal is to get input from a toggle switch connected to D6, Publish to topic "Charts" as output status == HIGH or LOW, then the other ESP6266s 
    would Subscribe to "Charts", turn on/off LED accordingly.
    
    */
    
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    
    int togglePin = D6;//  Connect Adafruit capacitive touch toggle switch to D6
    int chartsledPin = D1;//  LED indicator for Charts-up
    boolean on = false;
    int buttonState = 0;
    
    
    // Update these with values suitable for your network.
    const char* ssid = "MYSSID";
    const char* password = "MYPASSWORD!";
    const char* mqtt_server = "Mosquitto_broker";
    
    WiFiClient espClient;
    PubSubClient client(espClient);
    long lastMsg = 0;
    char msg[50];
    int value = 0;
    
    void setup() {
      pinMode(D6, INPUT);     // Adafruit Capacitive Touch Toggle Switch to D1
      pinMode(D1, OUTPUT);
    
      Serial.begin(115200);
      setup_wifi();
      client.setServer(mqtt_server, 1883);
      client.setCallback(callback);
    }
    
    void setup_wifi() {
    
      delay(50);
      // 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());
    }
    
    void callback(char* topic, byte* payload, unsigned int length) {
      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");
      for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
      }
      Serial.println();
    
    
    }
    
    
    void reconnect() {
      // Loop until we're reconnected
      while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");
        // Attempt to connect
        if (client.connect("ESP8266Client")) {
          Serial.println("connected");
          // Once connected, publish an announcement...
          //   client.publish("outTopic", "hello world");  *** I just want to flash LED on D1 until connected***
          // ... and resubscribe
          client.subscribe("Charts/PS");
          client.subscribe("Chapperones/PSA");//       ONE STEP AT A TIME
          client.subscribe("Chapperones/PSB");//  ONCE I GET THE "CHARTS"
          client.subscribe("Chapperones/PSC");// SUB/PUB WORKING, THEN I CAN 
          client.subscribe("Chapperones/PSD");//     ADD THIS TO MY PROJECT.
        } else {
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" try again in 5 seconds");
          // Wait 5 seconds before retrying
          delay(5000);
        }
      }
    }
    
    void loop() {
    
      if (!client.connected()) {
        reconnect();
      }
    
      int value = 0;
      client.loop();
    
      {
        buttonState = digitalRead(D6);
        if (buttonState == HIGH) {
          client.publish("Charts/PS", "1");
          digitalWrite(D1, HIGH);// I DON'T THINK THIS IS CORRECT
    //                              IT COMES ON WHEN I PRESS IT BUT NOT 
    //                                       THROUGH MQTT
        }
    
        else {
          client.publish("Charts/PS", "0");
          digitalWrite(D1, LOW);//                     SAME HERE
        }
      }
    }
    

    Assistance is MUCH appreciated!



  • I'm thinking I have to redesign my connections. I wanted the Raspberry Pi to be in the hallway between all the other Wemos and act just as a broker.
    Now it looks like the Wemos can only handle one MQTT subscription. So, I have to move my Pi Zero W to the front desk in a project enclosure with leds connected to the IO pins, when the LED is powered up with the button press publish a 1 or 0 for remote leds on the Wemos to light up and a button press on the remote Wemos, publish so another led on the Pi Zero W will light up.

    Anyone good with PubSub.client, MQTT?
    This is What I have but I'm not sure how to get it to subscribe to more than one subject if that is even possible.

    /*
     * Reception
     */
    
    #include <EEPROM.h>
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    #include <Wire.h>
    
    
    // Connect to the WiFi
    const char* ssid = "MYSSID";
    const char* password = "MYPASSWORD";
    const char* mqtt_server = "Mosquitto_broker";
    
    WiFiClient espClient;
    PubSubClient client(espClient);
    
    //const byte chartsPin = D1; // LED on D1 of Wemos D1 mini
    // Constants won't change:  Name pins. It's easier to understand when reading through code
    const int buttonPin = D3;        // the pin that the pushbutton is attached to
    const int chartsPin = D1;        // LED pin for "Charts""
    const int officeaPin = D5;       // LED pin for "PHYS-SUB A"
    const int officebPin = D6;       // LED pin for "PHYS-SUB B"
    const int officecPin = D7;       // LED pin for "PHYS-SUB C"
    const int officedPin = D8;       // LED pin for "PHYS-SUB D"
    
    
    
    // Variables will change:
    int buttonPushCounter = 0;   // counter for the number of button presses
    int buttonState = 0;         // current state of the button
    int lastButtonState = 0;     // previous state of the button
    
    void callback(char* topic, byte* payload, unsigned int length) {
      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");
      for (int i = 0; i < length; i++) {
        char receivedChar = (char)payload[i];
        Serial.print(receivedChar);
        if (receivedChar == '0')
          digitalWrite(chartsPin, HIGH);
        if (receivedChar == '1')
          digitalWrite(chartsPin, LOW);
      }
      Serial.println();
    }
    
    void reconnect() {
      // Loop until we're reconnected
      while (!client.connected()) {
        Serial.println("Attempting MQTT connection...");
        // Attempt to connect
        if (client.connect("Reception")) {
          Serial.println("connected");
          // ... and subscribe to topic
          client.subscribe("Charts/PS");
        } else {
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" try again in 5 seconds");
          // Wait 5 seconds before retrying
          delay(5000);
        }
      }
    }
    
    void setup()
    {
      Serial.begin(9600);
    
      client.setServer(mqtt_server, 1883);
      client.setCallback(callback);
    
      pinMode(chartsPin, OUTPUT);
    }
    
    void loop() {
      if (!client.connected()) {
        reconnect();
      }
      // read the pushbutton input pin:
      buttonState = digitalRead(buttonPin);
    
      // compare the buttonState to its previous state
      if (buttonState != lastButtonState) {
        // if the state has changed, increment the counter
        if (buttonState == HIGH) {
          client.publish("Charts/PS", "0");
          Serial.println("LED is On");
          // if the current state is HIGH then the button
          // went from off to on:
        } else {
          // if the current state is LOW then the button
          // went from on to off:
          client.publish("Charts/PS", "1");
          Serial.println("LED is off");
        }
        // Do I need a delay for debounce with Adafruit Capacitive Touch Toggle Switch?
        delay(100);//if not I can delete this line.
      }
      // save the current state as the last state,
      //for next time through the loop
      lastButtonState = buttonState;
      client.loop();
    }```

Log in to reply
 

Looks like your connection to WEMOS Forum was lost, please wait while we try to reconnect.