Using Blynk to Control Lights in Shop

I’m using the Blynk app and a Nano 33 IoT with relays to control my shop lights and super close to making it work exactly how I want, but not quite there. My goal is to have the Blynk app turn the lights on and off and also have 3 physical momentary buttons in place of the old flip switches. As of right now the app will activate 3 relays and 1 momentary button will activate one relay. I also want the app to reflect the status of the lights. If I push the button in the shop and the lights come on, I want the button in the app to show on, and the same for off. Here is the code I have so far. Let me know what you think .

/*************************************************************
  Download latest Blynk library here:
    https://github.com/blynkkk/blynk-library/releases/latest

  Blynk is a platform with iOS and Android apps to control
  Arduino, Raspberry Pi and the likes over the Internet.
  You can easily build graphic interfaces for all your
  projects by simply dragging and dropping widgets.

    Downloads, docs, tutorials: http://www.blynk.cc
    Sketch generator:           http://examples.blynk.cc
    Blynk community:            http://community.blynk.cc
    Follow us:                  http://www.fb.com/blynkapp
                                http://twitter.com/blynk_app

  Blynk library is licensed under MIT license
  This example code is in public domain.

 *************************************************************

  Blynk using a LED widget on your phone!

  App project setup:
    LED widget on V3
 *************************************************************/

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


#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxxxxxxxxxx";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxxxxxxx";
char pass[] = "xxxxxxxx";


// Set your LED and physical button pins here
const int ledPin1 = 9;
const int ledPin2 = 11;
const int ledPin3 = 12;
const int btnPin1 = 2;
const int btnPin2 = 3;
const int btnPin3 = 4;

BlynkTimer timer;
void checkPhysicalButton();

int ledState = LOW;
int btnState = HIGH;

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  //Blynk.syncVirtual(V2);

  // Alternatively, you could override server state using:
  Blynk.virtualWrite(V2, ledState);
}

// When App button is pushed - switch the state
BLYNK_WRITE(V2) {
  ledState = param.asInt();
  digitalWrite(ledPin1, ledState);
  digitalWrite(ledPin2, ledState);
  digitalWrite(ledPin3, ledState);
}

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

      // Toggle LED state
      ledState = !ledState;
      digitalWrite(ledPin1, ledState);
            
      // Update Button Widget
      Blynk.virtualWrite(V2, ledState);
    }
    btnState = LOW;
  } else {
    btnState = HIGH;
  }
}

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(btnPin1, INPUT_PULLUP);
  pinMode(btnPin2, INPUT_PULLUP);
  pinMode(btnPin3, INPUT_PULLUP);
  digitalWrite(ledPin1, ledState);


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

void loop()
{
  Blynk.run();
  timer.run();
}

I think you should ask a concrete question best regards Stefan

My question is, what is missing or what can I change to get feedback to the Blynk app? With my very limited knowledge everything looks to be correct, but the app never reacts to the physical button changes even though the Arduino does exactly what I want

I don#T know much about Blynk how often do you send commands towards Blynk. The send-frequency is quite limited. ANd for such a Blynk-related question: Did you ask in the Blynk-User-Forum?

community.blynk.cc

best regards Stefan

I tried the forum there. They seem to have one guy that helps, but is kind of vague for my knowledge level.

That code is from one of their samples and just slightly modified to handle more lights. I assumed it was often enough to do the job. I can deal with a slight delay in the change. I mostly want it so I know sitting at home if my shop lights got left on by someone.

If you send data at a too high frequency towards blynk. Blynk will block your data. So you have to slow down sending data towards blynk.

best regards Stefan

Seems odd that they would give example code that they wouldn't support. I tried playing with the frequency with no change other than making my physical buttons more or less responsive.

For now I am just grounding the pin designated for the physical buttons. Would there be any reason to need anything else in there like a resistor or something?

So what happens if you load the provided original example-sketch? Does this sketch work like expected?

If you start modifying this original sketch in really small tiny steps where is the point it stops working like expected?

As an alternative for analysing add serial-debug-output to see if the speed for sending data towards the blynk-server is slow enough.

best regards Stefan

Philtubbs: For now I am just grounding the pin designated for the physical buttons. Would there be any reason to need anything else in there like a resistor or something?

No, the internal pullup takes care of it, your method is fine.

++for Stefan's suggestion - get something that works and tweak it gently until you break it.

StefanL38: If you start modifying this original sketch in really small tiny steps where is the point it stops working like expected?

My messing with the sample sketch never removes any functionality. It never sends feedback to the app even if I only change pin numbers to match my build. Maybe I will try moving my button and led wires to match the original sketch and see what happens.

Philtubbs: Maybe I will try moving my button and led wires to match the original sketch and see what happens.

That's what I would do.

Ok, I copied the sketch direct from the Blynk website examples. I changed nothing in the sketch at all and moved my physical connections to match the sketch. Still no feedback to the app, but the app will turn the light on and off along with the physical button. Does anything stand out as being wrong here?

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


#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxxxxxxxxx";
char pass[] = "xxxxxxx";

// Set your LED and physical button pins here
const int ledPin = 7;
const int btnPin = 8;

BlynkTimer timer;
void checkPhysicalButton();

int ledState = LOW;
int btnState = HIGH;

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(V2);

  // Alternatively, you could override server state using:
  //Blynk.virtualWrite(V2, ledState);
}

// When App button is pushed - switch the state
BLYNK_WRITE(V2) {
  ledState = param.asInt();
  digitalWrite(ledPin, ledState);
}

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
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);

  pinMode(ledPin, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  digitalWrite(ledPin, ledState);

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

void loop()
{
  Blynk.run();
  timer.run();
}

One problem with example sketches, they are short cuts past the basic knowledge that allowed them to be built. With a well established system like Blynk, it's possible and desirable to study the API documentation as well as just tinkering with an example.

I’m not sure what this is doing:

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;
  }
}

Try doing the virtualWrite unconditionally at the end of that function.

I somewhat figured it out. I assumed that the button on the app needed to be assigned to pin 7 which is what the LED is connected to. I changed that and it works perfectly. What I don't understand is how that works. I don't see anything in the code that makes that make sense. I am clueless though.

I also need to make this happen for 2 more lights, 2 more app buttons and 2 more physical switches.

I think that's the distinction between Blynk's virtual pins and your Arduino physical pins. There is no need to correlate them. I assumed you switched to virtual pin 2?

Right now using the last sketch I posted, I have an LED connected to pin D7 and a momentary button connected to D2. The app will turn the LED on and shows “on” on the app. If I turn it off with the momentary button, the app changes it’s status to “off”. It’s working perfectly for a single light and button. I just need to figure out how to do that 2 more times to have 3 lights and 3 buttons. I tried just adding 2 more of everything and get a compile error.

Try_Again:97:1: error: a function-definition is not allowed here before ‘{’ token

and it highlights the line between void loop() and blynk run; at the bottom

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


#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxxxxxxxxx";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";

// Set your LED and physical button pins here
const int ledPin1 = 7;
const int ledPin2 = 8;
const int ledPin3 = 9;
const int btnPin1 = 2;
const int btnPin2 = 3;
const int btnPin3 = 4;

BlynkTimer timer;
void checkPhysicalButton();

int ledState = LOW;
int btnState = HIGH;

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(V2);
  Blynk.syncVirtual(V3);
  Blynk.syncVirtual(V4);

  // Alternatively, you could override server state using:
  //Blynk.virtualWrite(V2, ledState);
}

// When App button is pushed - switch the state
BLYNK_WRITE(V2) {
BLYNK_WRITE(V3) {
BLYNK_WRITE(V4) {  
}
  ledState = param.asInt();
  digitalWrite(ledPin1, ledState);
  digitalWrite(ledPin2, ledState);
  digitalWrite(ledPin3, ledState);
}

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

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

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

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(btnPin1, INPUT_PULLUP);
  pinMode(btnPin2, INPUT_PULLUP);
  pinMode(btnPin3, INPUT_PULLUP);
  digitalWrite(ledPin1, ledState);
  digitalWrite(ledPin2, ledState);
  digitalWrite(ledPin3, ledState);

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

void loop()
{
  Blynk.run();
  timer.run();
}

The curly braces in this section don’t look right. T will format the code text to make indentations easier to follow.

BLYNK_WRITE(V2) {
  BLYNK_WRITE(V3) {
    BLYNK_WRITE(V4) {
    }
    ledState = param.asInt();
    digitalWrite(ledPin1, ledState);
    digitalWrite(ledPin2, ledState);
    digitalWrite(ledPin3, ledState);
  }

Plus, the brace for V2 is unmatched.

You're trying to define functions inside each other. C++ doesn't like that. Maybe keep it simple and just add a second one for now. Once that's done, adding the third will be easy.

You can't nest function definitions like you're trying to do with the BLYNK_WRITE functions.