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?
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.
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 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?
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.
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?
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.
#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.
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:
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.