Setting "Modes" for LEDs through Blynk

So I am trying to program different “Modes” on my RGB strip that I can select between on my Blynk app. I know how I’d go about it if I was only using Arduino IDE, but I am struggling to incorporate Blynk commands/keep the void loop() clean.

When I press 1 button I want the strip to do a specific animation. When a different button is pressed, the first button would turn off. Essentially, only 1 “Mode” would be accessible at a time, because they’ll be different animations for the strip. I have a test code that I’ve been working on that has 3 “Modes”, that currently just put the strip at different colors, but this doesn’t seem to be working. What am I missing syntax-wise to do this?

Thanks in advance, I’m still a struggling newbie!

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Adafruit_NeoPixel.h>
#include <SimpleTimer.h>
    
#define BLYNK_PRINT Serial
#define LED_Pin D2
#define Led_Count 300

int selectmode = 0;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(Led_Count, LED_Pin, NEO_GRB + NEO_KHZ800);

char auth[] = "Authtoken";
char ssid[] = "network";
char pass[] = "password";

SimpleTimer timer;

void setup() 
{  
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  strip.begin();
  strip.setBrightness(50);
  pinMode(LED_Pin,OUTPUT);

  timer.setInterval(1000, modesetting);
}

void modesetting()
{
  if (V2 == HIGH)
  {
    selectmode = 1;
    Blynk.virtualWrite (V3, LOW);
    Blynk.virtualWrite (V4, LOW);
  }
  else if (V3 == HIGH) 
  {
    selectmode = 2;
    Blynk.virtualWrite (V2, LOW);
    Blynk.virtualWrite (V4, LOW);
  }
  else if (V4 == HIGH)
  {
    selectmode = 3;
    Blynk.virtualWrite (V2, LOW);
    Blynk.virtualWrite (V3, LOW);
  }
   
}


BLYNK_WRITE(V1)
{
  selectmode = param.asInt();
  modesetting;
  if (selectmode = 1)
  {
    for (int i=0;i<Led_Count;i++)
    {
    strip.setPixelColor(i,121,165,0);
    }
    strip.show();
  }
  else if (selectmode = 2)
  {
    for (int i=0;i<Led_Count;i++)
    {
      strip.setPixelColor(i,165,0,254);
    }
    strip.show();
    }
  else if (selectmode = 3)
  {
    for (int i=0;i<Led_Count;i++)
    {
      strip.setPixelColor (i,87,0,0);
    }
    strip.show();
  }
}



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

I can’t work-out what your modesetting function is supposed to be doing, or how it’s meant to be reading the values of V2, V3 and V4 (whatever they are).

It sounds to me like a Segmented Switch or Menu widget would be a better option.

Pete.

I looked all over and couldn’t find this until now; this is exactly what I need. Thank you!

So just to clarify, I had 3 switches in my Blynk code, V2, V3 and V4. I wanted to be able to turn on 1 of them which would set the RGB strip to a certain color. Then if I pressed another, it would toggle off the previous button and write a different color to the strip.

So you’d need BLYNK_WRITE(VPin) callbacks for each of the switches on V2, V3 and V4, which you don’t have.

Pete.

Ah, I see that now, thanks for the tip.

2 Likes

So I got a chance last night to follow up on Pete’s advice and use a segmented switch. It works perfectly, but with the amount of options I need, the switches are a bit small. If you could manipulate the dimensions or change it to a vertical layout it would be perfect! As is though, I think I need a different option.

I was exploring the library a bit more, and I found you can achieve similar results with normal buttons set to switch, and using the Blynk.virtualWrite/Blynk.syncVirtual commands, but I must be missing something in my test code. The switches seem to go back and forth forever?

BLYNK_WRITE(V2)
{
 if (selectmode == 2)
 {
  Blynk.virtualWrite(V3,false);
  Blynk.syncVirtual(V3);
 }
   selectmode = 1;
 Serial.println ((String)"Selectmode: "+selectmode);
}

BLYNK_WRITE(V3)
{
  if (selectmode == 1)
  {
    Blynk.virtualWrite(V2,false);
    Blynk.syncVirtual(V2);
  }
    selectmode = 2;
  Serial.println ((String)"Selectmode: "+selectmode);
}

Loose the syncVirtual that’s not needed :wink:
The sync virtual triggers the BLYNK_WRITE so it would run in a constant loop.

1 Like

Aaah gotcha, thanks! If I just have the virtualWrite will the button on the app update to reflect being off, or will the status of the virtual pin just change? I’d test but I’m at work at the moment.

1 Like

It will update the app too.

The sync virtual is a way to trigger the Blynk write function of another pin or to get the state after reset etc

Ok perfect, I’ll try this when I get home tonight. Thanks for the information!

I don’t know if it’s proper etiquette, but I figure responding in here made more sense than starting another post. I got the buttons to toggle the way I want, but they seem to remain “High” even after deactivating. selectmode should revert to 0 when they are all off, and turn off the strip, but the LEDs are staying on the last sent color. Am I missing something?

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Adafruit_NeoPixel.h>
    
#define BLYNK_PRINT Serial
#define Led D1
#define LED_Pin D2
#define Led_Count 300

Adafruit_NeoPixel strip = Adafruit_NeoPixel(Led_Count, LED_Pin, NEO_GRB + NEO_KHZ800);

char auth[] = "authtoken";
char ssid[] = "network";
char pass[] = "password";

int selectmode = 0;


void setup() 
{  
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  strip.begin();
  strip.setBrightness(50);
  strip.show();
  pinMode(LED_Pin,OUTPUT);
  pinMode(Led, OUTPUT);
}

BLYNK_WRITE(V1)
{
 if (selectmode == 2)
 {
  Blynk.virtualWrite(V2,0);
 }
 if (selectmode == 3)
 {
  Blynk.virtualWrite(V3,0);
 }
 selectmode = 1;
 Serial.println ((String)"Selectmode: "+selectmode);
}

BLYNK_WRITE(V2)
{
  if (selectmode == 1)
  {
    Blynk.virtualWrite(V1,0);
  }
  if (selectmode == 3)
  {
    Blynk.virtualWrite(V3,0);
  }
  selectmode = 2;
  Serial.println ((String)"Selectmode: "+selectmode);
}
  
BLYNK_WRITE(V3)
{
  if (selectmode == 1)
  {
    Blynk.virtualWrite(V1,0);
  }
  if (selectmode == 2)
  {
    Blynk.virtualWrite(V2,0);
  }
  selectmode = 3;
  Serial.println ((String)"Selectmode: "+selectmode);
}

void Mode()
{
  if ((digitalRead(V1))==0 && (digitalRead(V2))==0 && (digitalRead(V3))==0)
  {
    selectmode = 0;
  }
  switch (selectmode)
  {
    case 0:
    {
      for (int i=0;i<Led_Count;i++)
      {
        strip.setPixelColor(i,0,0,0);
      }
      strip.show();
      break;
    }
    case 1:
    {
      for (int i=0;i<Led_Count;i++)
      {
        strip.setPixelColor(i,200,0,0);
      }
      strip.show();
      break;
    }
    case 2:
    {
      for (int i=0;i<Led_Count;i++)
      {
        strip.setPixelColor (i,0,200,0);
      }
      strip.show();
      break;
    }
    case 3:
    {
      for (int i=0;i<Led_Count;i++)
      {
        strip.setPixelColor(i,0,0,200);
      }
      strip.show();
      break;
    }
  }  
}

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

Hold on one second, I see a few issues in you current code. Would it be ok if I were to rewrite your code, to do what I think you want it to - then explain the issues afterwards?

Here you can see the final code, and the alterations I made. I haven’t tested it so please keep your eyes peeled for any mistakes I’m likely to have made. :wink:

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Adafruit_NeoPixel.h>
    
#define BLYNK_PRINT Serial
#define Led D1
#define LED_Pin D2
#define Led_Count 300

Adafruit_NeoPixel strip = Adafruit_NeoPixel(Led_Count, LED_Pin, NEO_GRB + NEO_KHZ800);
BlynkTimer timer; 

char auth[] = "authtoken";
char ssid[] = "network";
char pass[] = "password";

int selectMode = 0;

int vPin1;
int vPin2;
int vPin3;

void setup(){  
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  strip.begin();
  strip.setBrightness(50);
  strip.show();
  pinMode(LED_Pin,OUTPUT);
  pinMode(Led, OUTPUT);
  
  timer.setInterval(100, mode); //Runs the "mode" function once every 100ms, so not to overwhelm hardware
}

BLYNK_CONNECTED(){  //Runs each time the hardware is connected to the Blynk server, e.g. after crash / disconnect.
  Blynk.syncVirtual(V1); //Runs the BLYNK_WRITE function assigned to the pin, in order to get the current button states from the app.
  Blynk.syncVirtual(V2);
  Blynk.syncVirtual(V3);
}

BLYNK_WRITE(V1){ // Called each time switch changes
 vPin1 = param.asInt(); // Catches the value of V1 as integer and stores it in vPin1 for later comparison

 if (vPin1 == 1){ // Switch was turned on, thus turn other switches off
  selectMode = 1;
  Blynk.virtualWrite(V2, LOW);
  Blynk.virtualWrite(V3, LOW);
 }else if (vPin1 == 0){ // Switch is off
  // Do something if switch turned off
 } 
 Serial.println ((String)"Selectmode: " + selectMode);
}

BLYNK_WRITE(V2){ // Called each time switch changes
 vPin2 = param.asInt();

 if (vPin2 == 1){ // Switch was turned on, thus turn other switches off
  selectMode = 2;
  Blynk.virtualWrite(V1, LOW);
  Blynk.virtualWrite(V3, LOW);
 }else if (vPin2 == 0){ // Switch is off
  // Do something if switch turned off
 } 
 Serial.println ((String)"Selectmode: " + selectMode);
}
  
BLYNK_WRITE(V3){ // Called each time switch changes
 vPin3 = param.asInt();

 if (vPin3 == 1){ // Switch was turned on, thus turn other switches off
  selectMode = 3;
  Blynk.virtualWrite(V1, LOW);
  Blynk.virtualWrite(V2, LOW);
 }else if (vPin3 == 0){ // Switch is off
  // Do something if switch turned off
 } 
 Serial.println ((String)"Selectmode: " + selectMode);
}

void mode(){
  if ((vPin1 == 0) && (vPin2 == 0) && (vPin3 == 0)){
    selectmode = 0;
  }
  switch (selectmode)
  {
    case 0:
    {
      for (int i=0;i<Led_Count;i++)
      {
        strip.setPixelColor(i,0,0,0);
      }
      strip.show();
      break;
    }
    case 1:
    {
      for (int i=0;i<Led_Count;i++)
      {
        strip.setPixelColor(i,200,0,0);
      }
      strip.show();
      break;
    }
    case 2:
    {
      for (int i=0;i<Led_Count;i++)
      {
        strip.setPixelColor (i,0,200,0);
      }
      strip.show();
      break;
    }
    case 3:
    {
      for (int i=0;i<Led_Count;i++)
      {
        strip.setPixelColor(i,0,0,200);
      }
      strip.show();
      break;
    }
  }  
}

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

If you want help understanding any of the changes / alterations that I made, please feel free to ask. And of course you can always adapt the code to suit your future needs.

First off, thank you sooo much for your help!

When I used your code everything worked, except when I deactivate all 3 buttons, it still maintains the last “mode” that was on and doesn’t reset to blank. This is the exact problem I was having! I added an extra button to check the status of V1:

BLYNK_WRITE(V0)
{
  Serial.println((String)"V1 Status: "+vPin1);
}

When I checked the status of V1, it was LOW at the initiation of the code, as expected, but once I pressed the button, it remained HIGH, even after I deactivated it. After some experimenting, I ended up changing the BLYNK_WRITE functions to:

BLYNK_WRITE(V1) // Called each time switch changes
{
 vPin1 = param.asInt(); // Catches the value of V1 as integer and stores it in vPin1 for later comparison
 if (vPin1 == 1) // Switch was turned on, thus turn other switches off
 {
  selectMode = 1;
  Blynk.virtualWrite(V2, LOW);
  vPin2 = 0;
  Blynk.virtualWrite(V3, LOW);
  vPin3 = 0;
 }
 else if (vPin1 == 0) // Switch is off 
 {
  Serial.println ((String)"Selectmode: " + selectMode);   // Do something if switch turned off
 }
}

BLYNK_WRITE(V2) // Called each time switch changes
{
 vPin2 = param.asInt();
 if (vPin2 == 1) // Switch was turned on, thus turn other switches off
 {
  selectMode = 2;
  Blynk.virtualWrite(V1, LOW);
  vPin1 = 0;
  Blynk.virtualWrite(V3, LOW);
  vPin3 = 0;
 }
 else if (vPin2 == 0) // Switch is off
 { 
  Serial.println ((String)"Selectmode: " + selectMode);   // Do something if switch turned off
 }
}
  
BLYNK_WRITE(V3) // Called each time switch changes
{
 vPin3 = param.asInt();
 if (vPin3 == 1) // Switch was turned on, thus turn other switches off
 {
  selectMode = 3;
  Blynk.virtualWrite(V1, LOW);
  vPin1 = 0;
  Blynk.virtualWrite(V2, LOW);
  vPin2 = 0;
 }
 else if (vPin3 == 0) // Switch is off
 { 
  Serial.println ((String)"Selectmode: " + selectMode);  // Do something if switch turned off
 }
}

Now everything seems to be working as intended.I’m not sure if this is the cleanest solution, but it seems to works. Thanks so much for the advice, it feels so good to have finally cracked this! Was my mistake trying to digitalRead instead of defining the parameter and reading that?

Yeah, you can’t use digitalRead, that’s exclusively for physical pins, sorry about that omission by the way, I was planning on including something to correct that, but I clearly forgot.

2 Likes

No worries at all, it was a good learning experience! Now to remove the “test” code from my switch function and put in my animations! :crossed_fingers:

Thanks again for your help!

2 Likes