*NEW* Issue with ESP32 and Blynk - Switch Not Affecting Relay Board Selection

HARDWARE: ESP32-WROOM32
DEVICE: ANDROID 14
BYLNK SERVER REGION: NY3
BLYNK LIBRARY VERSION: 1.3.2?

I’m currently working on a project where I’m using an ESP32 to control two XL9535-K16V5 16ch relay boards via I2C, with control toggled between the boards using a virtual switch (V16) in the Blynk app.

Overview
(Controlling 32 relays w/ 16 buttons)
I’ve got 16 buttons (V0-V15) to control the first 16 relays on the first I2C relay board and I have a switch (V16 - Value 0 when off & Value 1 when on) and when the switch is turned on, the same 16 buttons will then control the 16 relays on the second I2C board.

  • Setup: I have two XL9535 boards at addresses 0x20 and 0x21. I’m using Blynk to control 16 relays (V0-V15) on these boards.
  • Control Logic: When V16 is OFF (0), buttons control relays on the first board (0x20). When V16 is ON (1), they control the second board (0x21).

Issue:
Despite the switch state changing correctly in the Blynk app and being reflected in the serial monitor, the buttons always control the first board (0x20), regardless of V16’s state.

Here’s what I’ve tried:

Direct Pin Reading: I’ve modified my code to directly read V16’s state each time a button press is processed.
Debugging Output: Added serial prints to confirm V16’s state and which board should be controlled.
Delay in Loop: Added a small delay in the loop to ensure state changes are recognized.

Code:

#define BLYNK_TEMPLATE_ID "TMPL XXXXX"
#define BLYNK_TEMPLATE_NAME "XXXXX"
#define BLYNK_AUTH_TOKEN "XXXXX"

#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <Wire.h>

// Your Wi-Fi credentials
char ssid[] = "XXXX";
char pass[] = "XXXX";


#define I2C_SDA 21
#define I2C_SCL 22

// Addresses of the two XL9535-K16V5 boards
#define XL9535_ADDR1 0x20  // First board address
#define XL9535_ADDR2 0x21  // Second board address

// Function to initialize I2C and set up the XL9535 boards
void setupXL9535() {
  Wire.begin(I2C_SDA, I2C_SCL);
  
  // Initialize both boards
  Wire.beginTransmission(XL9535_ADDR1);
  Wire.write(0x00); // Mode register
  Wire.write(0x00); // All outputs off
  Wire.endTransmission();
  
  Wire.beginTransmission(XL9535_ADDR2);
  Wire.write(0x00); // Mode register
  Wire.write(0x00); // All outputs off
  Wire.endTransmission();
}

// Function to control relays
void controlRelay(byte addr, byte relay, bool state) {
  Wire.beginTransmission(addr);
  Wire.write(0x00); // Mode register
  byte data = Wire.read();
  if (state) {
    data |= (1 << relay); // Turn on the relay
  } else {
    data &= ~(1 << relay); // Turn off the relay
  }
  Wire.write(data);
  Wire.endTransmission();
}

// Function to handle button presses
void handleButtonPress(int pin, int state) {
  int relayIndex = pin - V0;
  int board = digitalRead(V16) ? XL9535_ADDR2 : XL9535_ADDR1;
  
  controlRelay(board, relayIndex, state);
  
  Serial.print("Button ");
  Serial.print(pin);
  Serial.print(" changed state to ");
  Serial.print(state);
  Serial.print(" controlling relay ");
  Serial.print(relayIndex + 1);
  Serial.print(" on board ");
  Serial.println(board == XL9535_ADDR2 ? "2" : "1");
}

// Setup Blynk for each button
void setupBlynkButtons() {
  for (int i = V0; i <= V15; i++) {
    Blynk.virtualWrite(i, LOW); // Initialize all buttons to off state
  }
}

BLYNK_WRITE(V16) {
  int pinValue = param.asInt();
  Serial.print("Switch state changed to: ");
  Serial.println(pinValue);
  // Small delay to ensure the state change is recognized
  delay(100);
}

// Define BLYNK_WRITE for each button (V0-V15)
BLYNK_WRITE(V0) {
  int state = param.asInt();
  handleButtonPress(V0, state);
}

BLYNK_WRITE(V1) {
  int state = param.asInt();
  handleButtonPress(V1, state);
}

BLYNK_WRITE(V2) {
  int state = param.asInt();
  handleButtonPress(V2, state);
}

BLYNK_WRITE(V3) {
  int state = param.asInt();
  handleButtonPress(V3, state);
}

BLYNK_WRITE(V4) {
  int state = param.asInt();
  handleButtonPress(V4, state);
}

BLYNK_WRITE(V5) {
  int state = param.asInt();
  handleButtonPress(V5, state);
}

BLYNK_WRITE(V6) {
  int state = param.asInt();
  handleButtonPress(V6, state);
}

BLYNK_WRITE(V7) {
  int state = param.asInt();
  handleButtonPress(V7, state);
}

BLYNK_WRITE(V8) {
  int state = param.asInt();
  handleButtonPress(V8, state);
}

BLYNK_WRITE(V9) {
  int state = param.asInt();
  handleButtonPress(V9, state);
}

BLYNK_WRITE(V10) {
  int state = param.asInt();
  handleButtonPress(V10, state);
}

BLYNK_WRITE(V11) {
  int state = param.asInt();
  handleButtonPress(V11, state);
}

  BLYNK_WRITE(V12) {
  int state = param.asInt();
  handleButtonPress(V12, state);
}

BLYNK_WRITE(V13) {
  int state = param.asInt();
  handleButtonPress(V13, state);
}

BLYNK_WRITE(V14) {
  int state = param.asInt();
  handleButtonPress(V14, state);
}

BLYNK_WRITE(V15) {
  int state = param.asInt();
  handleButtonPress(V15, state);
}

void setup() {
  Serial.begin(115200);
  setupXL9535();
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
  setupBlynkButtons();
}

void loop() {
  Blynk.run();
  delay(100); // Small delay to ensure state changes are recognized
}

Serial Monitor Output:

Switch state changed to: 0
Button 0 changed state to 15 controlling relay 1 on board 1
Switch state changed to: 1
Button 0 changed state to 0 controlling relay 1 on board 1

what do you expect BLYNK_WRITE(V16) to do? It just updates a local var.

@pierredebuysscher

To be completely honest I’m not very familiar with creating code for arduino / esp / c++…

I used chapgpt to get me started and have spent 5+ hours researching and trying different things and I’ve been unable to solve this. I was up all night!

I understand how to read the state of a virtual pin and have it do something but I’m over my head trying to change what a virtual pin does depending on the state of a switch / another virtual pin.

I’d appreciate some help… Thanks!

EDIT

So I told chatgpt what you mentioned and this is the response I got:

Here’s a breakdown and potential solution:

Understanding the Issue:
BLYNK_WRITE(V16): This function is triggered when the state of V16 changes in the Blynk app. However, as noted, it only updates a local variable within its scope.
Solution Approach:
To ensure that the state change of V16 affects the board selection logic throughout your program, you need to make this state change globally accessible or directly influence the logic where it matters.

  1. Global Variable Approach:
    Declare a Global Variable: Create a global variable to track V16’s state.
int v16State = 0; // Global variable to track V16's state

Update Global Variable in BLYNK_WRITE(V16):

BLYNK_WRITE(V16) {
  int pinValue = param.asInt();
  v16State = pinValue; // Update the global variable
  Serial.print("Switch state changed to: ");
  Serial.println(v16State);
  delay(100); // Small delay to ensure state change is recognized
}

Use Global Variable in handleButtonPress:

void handleButtonPress(int pin, int state) {
  int relayIndex = pin - V0;
  int board = v16State ? XL9535_ADDR2 : XL9535_ADDR1;
  
  Serial.print("V16 state: ");
  Serial.println(v16State);
  Serial.print("Selected board: ");
  Serial.println(board == XL9535_ADDR2 ? "2" : "1");
  
  controlRelay(board, relayIndex, state);
  
  Serial.print("Button ");
  Serial.print(pin);
  Serial.print(" changed state to ");
  Serial.print(state);
  Serial.print(" controlling relay ");
  Serial.print(relayIndex + 1);
  Serial.print(" on board ");
  Serial.println(board == XL9535_ADDR2 ? "2" : "1");
}

2. Direct Check in handleButtonPress:

Alternatively, if you prefer not to use a global variable, you could directly check V16’s state each time handleButtonPress is called, as you’ve already done. However, ensure that digitalRead(V16) is correctly reading

You need to create a global variable (declared near the top of your code) that tracks the state of V16.
In the BLYNK_WRITE(V16) you need to alter the state of this variable, and in your function that controls the appropriate relay you need to check the state of this variable to decide which of the controllers you’ll be sending the instruction to.

Also, stop putting delays in your code, they mess-up the way that Blynk works.

Pete.

@PeteKnight

Thank you for your help! I do appreciate it!

Yeah one of the last things I tried to see if it would help my issue was adding the delays. So since they didn’t help and their not needed I’ll remove them.

Thx again!