Control 4 channel relay module with physical buttons

I am a total novice to coding.

I can get the app to work the way I want it to, but now I need to have physical buttons at the location to operate the relay module. Here is the code as I have it so far:

#define BLYNK_TEMPLATE_ID "xxxxxxxxx"
#define BLYNK_DEVICE_NAME "Testing Template"
#define BLYNK_AUTH_TOKEN "xxxxxxxxx"

// Comment this out to disable prints and save space
#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "xxxxxxxxx";
char pass[] = "xxxxxxxxx";

// Set your LED and physical button pins here
const int ledPin1 = 2;
const int ledPin2 = 2;
const int ledPin3 = 2;
const int btnPin1 = 1;
const int btnPin2 = 3;
const int btnPin3 = 13;
const int btnPin4 = 15;

BlynkTimer timer;

void checkPhysicalButton();

int ledState = LOW;
int btnState = HIGH;

int RelayPin1 = 4;
int RelayPin2 = 5;
int RelayPin3 = 12;
int RelayPin4 = 14;

// Every time we connect to the cloud...
  // Request the latest state from the server

  int pinValue = param.asInt();
  digitalWrite(RelayPin1, pinValue);
  int pinValue = param.asInt();
  digitalWrite(RelayPin2, pinValue); 
  int pinValue = param.asInt();
  digitalWrite(RelayPin3, pinValue);
  int pinValue = param.asInt();
  digitalWrite(RelayPin4, pinValue);

void checkPhysicalButton()
  if (digitalRead(btnPin) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btnState != LOW) {

      // Toggle LED state
      ledState = !ledState;
      digitalWrite(ledPin, ledState);

      // Update Button Widget
      Blynk.virtualWrite(V2, ledState);
    btnState = LOW;
  } else {
    btnState = HIGH;

void setup()
  // Debug console

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);

  pinMode(ledPin, OUTPUT);
  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  pinMode(RelayPin3, OUTPUT);
  pinMode(RelayPin4, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  //TURN OFF all Relays on Start 
  digitalWrite(RelayPin1, HIGH);
  digitalWrite(RelayPin2, HIGH);
  digitalWrite(RelayPin3, HIGH);
  digitalWrite(RelayPin4, HIGH);
  digitalWrite(ledPin, ledState);

  // Setup a function to be called every 100 ms
  timer.setInterval(100L, checkPhysicalButton);

void loop()

I am really trying to figure out how to incorporate the example here:

but I cannot understand what I need to do.

You’d be far better starting with the Sketch Builder example and getting that working correctly with one physical button, one widget button and one LED.

Code like this in your sketch…

won’t work, because you don’t have a variable called btnPin.
You do have variables called btnPin1, btnPin2 etc, but no btnPin.

In addition, you only have one checkPhysicalButton function, which checks one physical button pin. You’ll either need four of these, or one which checks all four button pins.

You’d actually be better using interrupts and a debounce routine rather than polling four button pins with one or more timers.
You’d also be better using an ESP32 so that you have sufficient useable GPIO pins.


1 Like

I am a novice and most of this is very dense.
I am modelling this project off of this guy’s setup:

His code is several levels over my head. When I upload it, the relays all light up for about five seconds, then off for one, then on for five, etc.

You’d also be better using an ESP32 so that you have sufficient useable GPIO pins.

The ESP32 isn’t available where I am and I thought this ESP8266 had enough gpio pins to fit all these functions. Is there some reason I shouldn’t have all of these pins used?

I am honestly shocked it is this difficult.

You should read this:

It gets easier if you improve your C++ coding skills.


1 Like