Link Segmented Switch to another Button

Hello,

So i’m trying to make a button with 3 options (Segmented Switch), enable another button in the first option, making this button control a relay and in the third option enable a timer, however I can not use a BLYNK_WRITE inside another BLYNK_WRITE … What’s the best alternative for this?

BLYNK_WRITE(V0)
{
  switch (param.asInt())
  { case 1: { // Manual
        BLYNK_WRITE(V2)
        {
        Serial.println("Manual selected");
            switch (rele)
    { case 1: { // RELÉ DESLIGADO
          digitalWrite(pinRele, HIGH);
          break;
        }
      case 2: { // RELÉ LIGADO
          digitalWrite(pinRele, LOW);
          break;
        }
    }
        }
        break;   
  }
    case 2: { // Automático
        Serial.println("Automático selected");
  if (percentual <= 10 ) { // se tiver menor ou igual que 30%, liga o relé; O relé fica ligado até chegar em 70%;
    digitalWrite(pinRele, LOW);

  }
  if (percentual >= 50 ) {        // se tiver maior ou igual a 70%, desliga o relé. Caso o percentual comece a descer abaixo de 70% e a ultima ação foi desligar o relé,
    digitalWrite(pinRele, HIGH);  //  o relé continuará desligado até alcançar 30%;

  } 
        break;
      }
    case 3: { // Programado
        Serial.println("Programado selected");
        
        break;
      }
  }

Look at syncVirtual, here:

So in case 1, you would do:

Blynk.syncVirtual(Vx); // Vx - Whatever button you are trying to 'activate'

I don’t really understand what you’re doing with your Switch Case statement - it looks a mess to me.

The solution to the problem you described is to use the segmented switch BLYNK_WRITE function to set a global variable (lets call it segmented_state) to a certain value (1, 2 or 3 probably) and have a Blynk.syncVirtual for the vPin of that segmented switch so that the value of the segmented switch is synchronised when the device restarts…

When the other three switch widget controls are actuated, the corresponding BLYNK_WRITE function would include a check to see what value of the segmented_state variable is.
If the Relay button widget was pressed and segmented_state == 1 then the command to activate/deactivate the relay is processed. If not then that command is ignored and the switch widget for the relay returned to its previous state using a Blynk.virtualWrite command.

This is really a variation on previous discussions about adding security to certain widgets, so if this doesn’t make much sense to you them do a bit of searching for those old topics.

Pete.

So … I’m a beginner as you guys can see and I still can’t make it work.

the problem continues, when I click the manual option on the Segmented Switch Button, the other button (Manual Button) does not work, it doesn’t activate or deactivate the relay. i’ve tried with an IF and with an Swith Case, but can’t seen to make it work.

Please see if you guys could help me, i’m brazilian and some discussions i don’t understand everything.

Here is all of the code


// Monitoramento umidade printando em monitor serial, LCD e em aplicativo

#include <LiquidCrystal.h> //inicia lib do LCD
LiquidCrystal lcd(12, 11, 10, 9, 8, 6); // seta portas do LCD

#define sensorUmidade A0 // Sensor de umidade de solo do módulo
#define pinRele 4

unsigned long tempoAnterior = 0; // Variável utilizada para guardar o tempo anterior
unsigned long intervalo = 5000; // Intervalo de tempo em MS para cada leitura
float percentual;
int estado;
int rele;


#define BLYNK_PRINT Serial
 

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>

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

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

// Hardware Serial on Mega, Leonardo, Micro...
//#define EspSerial Serial1

// or Software Serial on Uno, Nano...
#include <SoftwareSerial.h>
SoftwareSerial EspSerial(2, 3); // RX, TX

// Your ESP8266 baud rate:
#define ESP8266_BAUD 9600

ESP8266 wifi(&EspSerial);

BlynkTimer timer;
void myTimerEvent()
{
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V5, millis() / 1000);
}

BLYNK_WRITE(V0)
{
  switch (param.asInt())
  { 
    Blynk.virtualWrite(V2, rele);
    case 1: { // Manual
        Serial.println("Manual selected");
        switch (rele)
        { case 1: { // RELÉ DESLIGADO
              Serial.println("Válvula desligada");
              digitalWrite(pinRele, HIGH);
              break;
            }
          case 2: { // RELÉ LIGADO
              Serial.println("Válvula ligada");
              digitalWrite(pinRele, LOW);
              break;
            }
        }
        break;
      }
    case 2: { // Automático
        Serial.println("Automático selected");
        estado = 2;
        if (percentual <= 10 ) { // se tiver menor ou igual que 30%, liga o relé; O relé fica ligado até chegar em 70%;
          digitalWrite(pinRele, LOW);
        }
        if (percentual >= 50 ) {        // se tiver maior ou igual a 70%, desliga o relé. Caso o percentual comece a descer abaixo de 70% e a ultima ação foi desligar o relé,
          digitalWrite(pinRele, HIGH);  //  o relé continuará desligado até alcançar 30%;
        }
        break;
      }
    case 3: { // Programado
        Serial.println("Programado selected");
        estado = 3;
        break;
      }
  }
  
}



void sendSensor()
{
  Blynk.virtualWrite(V1, percentual);
}


void setup()
{
  pinMode( pinRele, OUTPUT);
  digitalWrite(pinRele, HIGH);


  lcd.begin(16, 2);

  // Debug console
  Serial.begin(9600);

  // Set ESP8266 baud rate
  EspSerial.begin(ESP8266_BAUD);
  delay(10);

  Blynk.begin(auth, wifi, ssid, pass);
  timer.setInterval(1000L, myTimerEvent);
  timer.setInterval(1000L, sendSensor);

}

void loop()
{

  unsigned long tempoAtual = millis(); // Realizamos a leitura atual do tempo em que o nosso Arduino Nano está ligado
  if (tempoAtual - tempoAnterior > intervalo) { // Pequena lógica para realizar leituras temporizadas sem parar o microcontrolador
    tempoAnterior = tempoAtual; // Guardamos o tempo anterior como o ultimo intervalo de tempo lido
    int leitura = analogRead(sensorUmidade); // Leitura dos dados analógicos vindos do sensor de umidade de solo
    percentual = map(leitura, 1023, 0, 0, 100);
    if (leitura <= 1023 && leitura >= 682) { // Se a leitura feita for um valor entre 1023 e 682 podemos definir que o solo está com uma baixa condutividade, logo a planta deve ser regada
      Serial.println("Nível de Umidade Baixo");
      Serial.print(percentual);
      Serial.println(" % ");
      Serial.println(leitura);

      lcd.setCursor(0, 0);
      lcd.print( percentual);
      lcd.print( "%" );
      lcd.setCursor(0, 1);
      lcd.print("Umidade Baixa");

    } else {
      if (leitura <= 681 && leitura >= 341) { // Se a leitura feita for um valor entre 681 e 341 podemos definir que o solo está com um nível médio de umidade, logo dependendo da planta pode ou não ser vantajoso regar
        Serial.println("Nível de Umidade Médio");
        Serial.print(percentual);
        Serial.println(" % ");
        Serial.println(leitura);

        lcd.setCursor(0, 0);
        lcd.print( percentual);
        lcd.print( "%" );
        lcd.setCursor(0, 1);
        lcd.print("Umidade Media");
      }
      else {
        if (leitura <= 340 && leitura >= 0) { // Se a leitura feita for um valor entre 0 e 340 podemos definir que o solo está com um nível aceitável de umidade, logo talvez não seja interessante regar neste momento
          Serial.println("Nível de Umidade Alto");
          Serial.print(percentual);
          Serial.println(" % ");
          Serial.println(leitura);

          lcd.setCursor(0, 0);
          lcd.print( percentual);
          lcd.print( "%" );
          lcd.setCursor(0, 1);
          lcd.print("Umidade Alta ");
        }
      }
    }
  }


    Blynk.syncAll();


  Blynk.run();
  timer.run(); // Initiates BlynkTimer
}

You need to scrap the code you currently have in BLYNK_WRITE(V0), it doesn’t do anything near what you need it to.

Instead, it should look something like this:

BLYNK_WRITE(V0)
{
  segmented_state =  (param.asInt();
}

You’ll also need to declare segmented_state as a global variable near the top of your code:

int   segmented_state;

and add this line at the end of your void setup:

  Blynk.syncVirtual(V0);

You will then have achieved a situation where you have a global variable which is set to 1,2, or 3 depending on the position of your segmented switch, and when your device starts-up, that variable will be synchronised with the current position of the segmented switch.

You started by saying:

So if the segmented switch is in position 1, it needs to allow a relay to be turned on or off via another button?
You make no mention of what is supposed to happen if the segmented switch is in position 2
In position 3 it’s meant to activate a timer, but you don’t elaborate on that.

So, lets focus on what happens inf the segmented switch is in position 1 - the position where the control of a relay is enabled.

Lets then assume that you have a button widget set to Switch mode attached to V1, which will be used to control the relay.
The code for V1 would be structured like this:

BLYNK_WRITE(V1)
{
 int v1_state =  (param.asInt();
 
 if (segmented_state !=1) // if the segmented switch is NOT in position 1 then we want to ignore the fact that V1 has been pressed
 {
   Blynk.virtualWrite(V1,!v1_state); Set the switch widget  attached to V1 back to its original status
 }
else
{
  // We only get to this point if the segmented switch was in position 1
  if (v1_state) // If the button on V1 is now ON
  {
    // Your code in here to turn the relay ON
  }
  else
  {
    // We get here if the button on V1 is now OFF
    // Your code in here to turn the relay ON
  }
}

Then, we come to the elephant in the room, your void loop!
You didn’t share your void loop when you posted your first code snippet, but now that you have we can see that it’s even more of a mess than your attempt at writing a switch/case statement.

You need to read, and fully understand this document:
http://help.blynk.cc/getting-started-library-auth-token-code-examples/blynk-basics/keep-your-void-loop-clean
Then restructure your code so that the code in your void loop is moved into a seperate function and called with a timer. While we’re on the subject of timers, the two you have at the moment look like this:

They are both being called at EXACTLY the same time. You need to offset one so that it gives the first timer change to execute the code it’s calling before the second one is called.

Pete.

1 Like

So the position 2, it’s automatic, it is this part of the code right here. it means that if the humidity percentage of the soil is below 10, than the relay activate and when it pass 50 the relay desactivate.

I didn’t get in position 3 yet, cause i can’t make it work the 1.

        if (percentual <= 10 ) { // se tiver menor ou igual que 30%, liga o relé; O relé fica ligado até chegar em 70%;
          digitalWrite(pinRele, LOW);
        }
        if (percentual >= 50 ) {        // se tiver maior ou igual a 70%, desliga o relé. Caso o percentual comece a descer abaixo de 70% e a ultima ação foi desligar o relé,
          digitalWrite(pinRele, HIGH);  //  o relé continuará desligado até alcançar 30%;
        }

Well, restructure void loop and get the code for position 1 working then move on from there.

If you’re uncertain about the direction that your program flow is taking, or the value of variables at any point in the process then add some serial print statements to help you get a better understanding.

Pete.