Unable to use Slider value in other parts of the application

Blynk Slider value

Hi
I need some advice and help with my Hydroponic tank level control system
The reserviour level is monitored with a float switch which is High when level is low and Low when tank is full this works the input flow vale opens and closes just fine as the level varies with a notification being sent.

I can set the flow allowed via the slider eg With the slider set to a positive value of 1000.
I Want to use the Slider set value for various functions but have had no success so far.

The system works just fine however automatically controlling the level.
I want to be able to change the slider value while water is flowing to e.g. zero to stop the flow which in turn closes the valve I also want to be able to increase the flow on the slider while water is flowing .

and then flow to restart the flow when I increase the slider to a positive value.

My problems starts when, while water is flowing I reduce the slider to 0 (zero) to stop the flow the valve closes and a warning to the effect is sent which is fine however increasing the slider to a positive value again does not open the valve and the message “water is not flowing” is continually sent I cannot get it out of the if ((flowSetpoint) <= 0) loop.

The first option (flowsetpoint > 0)) is ignored as flowsetPoint is zero the system opens the valve but closes it in the second condition and stay looping here.
I have had no success in being able to use the slider value in other parts of the system.

//Adjust the blynk app slider for Maximum volume of water flow
BLYNK_WRITE(V5)
{
  flowSetpoint = param.asInt();
  Blynk.virtualWrite(13, flowSetpoint); //write debug data to virtual pin 13

  delay(500);
}

// ===== Reservoir Level Control
void floatState()
{
  int waterLevel = digitalRead(levelSwitch); // *** Read Water float Status
  switch ( waterLevel )
  {
    case HIGH:  // ***** Reservior is LOW
      Blynk.virtualWrite(V19, newSetpoint); //debug value only zero is displayed
      
// This condition works the valve opens and closes as per level
// but also does not react on the floweSetpoint condion np matter what the Slider setting.
      if ((waterLevel == HIGH) &&  (notificationsent == false) && (flowSetpoint > 0))  //(TargetVolume > 0))
      {
        Serial.println("Water is flowing.");
        lcd.clear();
        lcd.print(2, 0, "Water is now");
        lcd.print(5, 1, "Flowing");
        Blynk.email("xxxxxxx@gmail.com", "Water Level Control #1 Water is flowing.", "Valve is open on Water Level Control #1 - Water is flowing.");
        Blynk.notify("Valve is open on Water Level Control #1 - Water IS flowing.");
        digitalWrite(valvePin, HIGH); //OPEN the valve
        Blynk.virtualWrite(V7, "OPEN");
        notificationsent = true;         // stop getting messages until water stops flowing and starts again
        flowoffprintonce = false;        // when water stops flowing again we can restart serial and terminal print (once)
      }
/* checks this condition but does not get out of the condition newSetpoint
 * value  remains at zero and valve closes no matter what the slider position
 * if I leave this condition out the system works as expected   
*/
      if ((waterLevel == HIGH) && (newSetpoint) <= 0); // Slider set too low
      {
        Blynk.virtualWrite(V9, newSetpoint); //debug value only only zero is displayed
        lcd.clear();
        lcd.print(2, 0, "Water is NOT");
        lcd.print(5, 1, "flowing");
        digitalWrite(valvePin, LOW); //CLOSE the valve
        Blynk.notify("Valve NOT open Target Volume Settings too LOW");
      }
      break;

    case LOW: // ***** Reservoir is full
      if ((waterLevel == LOW) && (flowoffprintonce == false))
      {
        Serial.println("Water is NOT FLOWING.");
        lcd.clear();
        lcd.print(2, 0, "Water is NOT");
        lcd.print(5, 1, "FLOWING");
        digitalWrite(valvePin, LOW);
        Blynk.virtualWrite(V7, "CLOSED");
        notificationsent = false;  // when water starts flowing again we can send another notification
        flowoffprintonce = true;      // stop serial and terminal prints after first pass of water stopping
      }
      break;
fault:;
  }
}

Just seeing part of your code is not enough to full understand, or test, and I am not going to try manually following the logic without the ability to fully test a sketch :stuck_out_tongue_winking_eye: but I see at least one locally declared variable…

Change to globally declared variables in order for values to be used throughout the sketch.

https://www.arduino.cc/reference/en/language/variables/variable-scope--qualifiers/scope/
[/quote]

Thanks I will clean it up and post it if you are referring to the variable newSetpoint it was delacred int newSetpoint = flowSetpoint at the beginning with all other ones will post the full code as soon as I get a gap to do it. Busy cleaning house at the moment.:sweat_smile:

As @Gunner says, code snippets don’t make it easy to see what’s happening.
However, I think that your problem may lie with your If statements within your Switch Case statements.

The best way to analyse what’s happening is to throw in lots of serial print statements to show the values of key variables at key points. You can also use them to indicate which branches of the various Switch Case and If statement combinations were followed.

Pete.

I have remover all the conditioning using the slider value and the system works fine I need the slider value for eg overfilling protection adjusting the flow during floeing period etc.

/*
  Connect Vcc and Gnd of sensor to arduino, and the
  signal line to arduino digital pin 2.
*/
#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <WidgetRTC.h>

BlynkTimer Timer; // Sets up a Timer object named Timer (could be any name)

char auth[] = "xxxxxxx"; // WtrLvlCtrl#1
char ssid[] = "xxxxx";
char pass[] = "xxxxx";

WidgetLED led1(30); //StartLED in blynk app virtual pin 30
WidgetLED led2(31);//StopLED in blynk app virtual pin 31

WidgetLCD lcd0(V0); //top lcd widget in blynk app on virtual pin 0
WidgetLCD lcd1(V1); //middle lcd widget in blynk app on virtual pin 1
WidgetLCD lcd(V2); //bottom lcd widget in blynk app on virtual pin 2

WidgetTerminal terminal(V22);
WidgetRTC rtc;

// Reserviour A
int sensorInterrupt = 4;  // *** WeMos D1 = 4 (SDA) (Wemos mini = digital pin 2)
int sensorPin = 4;        // *** WeMos D1 = 4 (SDA) (Wemos mini = digital pin 2)
int valvePin = 5;         // *** WeMos = D3/D15(SCL) (Wemos mini = D6 also works on D7)
byte levelSwitch = 12;    // *** WeMos = D6/D12(MISO) (Wemos mini = D1 also works on D2)


// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// liter/minute of flow.
float calibrationFactor = 4.5; // was 4.5
volatile byte pulseCount;
float flowRate;

unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;
unsigned long totalLiters = 0;
unsigned int flowSetpoint;

#define averageperiod 5 // currently set to average the flow every 5 seconds
int countseconds = 0;   // count up to averageperiod
int averageflow = 0;    // used for averaging flow over averageperiod
bool notificationsent = false;  // to ensure just one message for each flow start
bool flowoffprintonce = false;  // to ensure just one serial and terminal print for each flow stop

int rowIndex = 1;
String currentDate  ;
String daybefore;
int rtcTimer = 1; //check if RTC is OK and then disable / delete this #1 Timer
int currentDatesi = 0;
int daybeforesi = currentDatesi;
int newSetpoint = flowSetpoint;

void setup()
{
  Serial.begin(115200);
  Blynk.syncAll();
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);
  pinMode(valvePin , OUTPUT);
  digitalWrite(valvePin, LOW);  // *** ACTIVE HIGH, valve relay set to OFF on restart
  pinMode(levelSwitch, INPUT);

  pulseCount        = 0;
  flowRate          = 0.0;
  totalMilliLitres  = 0;
  oldTime           = 0;
  pulseCount = 0;
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);

  rtc.begin();
  terminal.println("Connected to Blynk");
  terminal.println(WiFi.localIP());
  terminal.flush();
  rtcTimer = Timer.setInterval(2000L, checkRTC);   // check every 2s if RTC is correct
  Timer.setInterval(1000L, showFlow);
}
BLYNK_CONNECTED()
{
  Blynk.syncVirtual(V6, V8, V9, V19);
  Blynk.syncVirtual(V5);
  Blynk.syncVirtual(V4);
}

void  showFlow()
{
  if ((millis() - oldTime) > 1000)   // Only process counters once per second
  {
    detachInterrupt(sensorInterrupt);
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    oldTime = millis();
    flowMilliLitres = (flowRate / 60) * 1000;
    totalMilliLitres += flowMilliLitres;
    unsigned int frac;
    
    // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
    frac = (flowRate - int(flowRate)) * 10;
    // Reset the pulse counter so we can start incrementing again
    pulseCount = 0;
    countseconds++;
    if (countseconds > 0) // used to skip the first rogue data flow reading
    {
      averageflow = averageflow + flowRate;   // used to calculate the average flow over averageperiod cycles
    }
    if (countseconds == averageperiod)
    {
      countseconds = 0;  // reset the counter
      floatState();
      averageflow = 0;     // reset the average but only after floatState() function
    }
    //   attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    // Enable the interrupt again now that we've finished sending output
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);

    countseconds++;
    if (countseconds > 0) // used to skip the first rogue data flow reading
    {
      averageflow = averageflow + flowRate;   // used to calculate the average flow over averageperiod cycles
    }
    if (countseconds == averageperiod)
    {
      countseconds = 0;  // reset the counter
      floatState();
      averageflow = 0;     // reset the average but only after floatState() function
    }
  }
  Blynk.virtualWrite(V0, totalMilliLitres);
  Blynk.virtualWrite(V1, (int(flowRate)));
}

// START Button on virtual pin 6 OPENS water Solenoid Valve
BLYNK_WRITE(V6)
{
  int controlRelay = param.asInt();
  if (controlRelay == 1)
  {
    Blynk.virtualWrite(V8, 0);
    Blynk.virtualWrite(V9, 0);
    //    currentMilliLitres = 0;
    digitalWrite(valvePin, HIGH);  // Turn relay ON
    Blynk.virtualWrite(V7, "OPEN");
    Blynk.virtualWrite(V6, 1);
    led1.on();
    led2.off();

  }
}
// STOP Button on virtual pin 8 CLOSES water Solenoid Valve
BLYNK_WRITE(V8)
{
  int controlRelay = param.asInt();
  if (controlRelay == 1)
  {
    Blynk.virtualWrite(V6, 0);
    Blynk.virtualWrite(V9, 0);
    //   currentMilliLitres = 0;
    digitalWrite(valvePin, LOW);  // turn relay OFF
    Blynk.virtualWrite(V7, "CLOSED");
    Blynk.virtualWrite(V8, 1);
    led2.on();
    led1.off();
  }
}

//Adjust the blynk app slider for Maximum volume of water flow
BLYNK_WRITE(V5)
{
  flowSetpoint = param.asInt();
  Blynk.virtualWrite(13, flowSetpoint); //write debug data to virtual pin 13

  delay(500);
}

// ===== Reservoir Level Control
void floatState()
{
  int waterLevel = digitalRead(levelSwitch); // *** Read Water float Status
  switch ( waterLevel )
  {
    case HIGH:  // ***** Reservior is LOW
      Blynk.virtualWrite(V19, newSetpoint); //debug value only zero is displayed

      // This condition works the valve opens and closes as per level
      // but also does not react on the floweSetpoint condion np matter what the Slider setting.
      if ((waterLevel == HIGH) &&  (notificationsent == false))// && (flowSetpoint > 0))
      {
        Serial.println("Water is flowing.");
        lcd.clear();
        lcd.print(2, 0, "Water is now");
        lcd.print(5, 1, "Flowing");
        Blynk.email("xxxxxxx@gmail.com", "Water Level Control #1 Water is flowing.", "Valve is open on Water Level Control #1 - Water is flowing.");
        Blynk.notify("Valve is open on Water Level Control #1 - Water IS flowing.");
        digitalWrite(valvePin, HIGH); //OPEN the valve
        Blynk.virtualWrite(V7, "OPEN");
        notificationsent = true;         // stop getting messages until water stops flowing and starts again
        flowoffprintonce = false;        // when water stops flowing again we can restart serial and terminal print (once)
      }
      /* checks this condition but does not get out of the condition newSetpoint
         value  remains at zero and valve closes no matter what the slider position
         if I leave this condition out the system works as expected
      *//*
      if ((waterLevel == HIGH) && (newSetpoint) <= 0); // Slider set too low
      {
        Blynk.virtualWrite(V9, newSetpoint); //debug value only only zero is displayed
        lcd.clear();
        lcd.print(2, 0, "Water is NOT");
        lcd.print(5, 1, "flowing");
        digitalWrite(valvePin, LOW); //CLOSE the valve
        Blynk.notify("Valve NOT open Target Volume Settings too LOW");
      }
*/
      break;

    case LOW: // ***** Reservoir is full
      if ((waterLevel == LOW) && (flowoffprintonce == false))
      {
        Serial.println("Water is NOT FLOWING.");
        lcd.clear();
        lcd.print(2, 0, "Water is NOT");
        lcd.print(5, 1, "FLOWING");
        digitalWrite(valvePin, LOW);
        Blynk.virtualWrite(V7, "CLOSED");
        notificationsent = false;  // when water starts flowing again we can send another notification
        flowoffprintonce = true;      // stop serial and terminal prints after first pass of water stopping
      }
      break;
fault:;
  }
}

void checkRTC()
{
  if (year() != 1970)
  {
    Timer.disable(rtcTimer);  // disable rtcTimer now RTC is ok
    //rtcupdated = true; // can be commented out as checkRTC will stop when RTC is ok
    currentDate = String(day()) + "/" + month() + "/" + year();   // etc
    terminal.println("RTC started");
    daybefore = currentDate;
    Timer.setInterval(60000L, table);   //start table() now RTC is OK
  }
}
void table()
{
  currentDate = String(day()) + "/" + month() + "/" + year();  // etc
  if (currentDate != daybefore)
  {
    //currentDate = String(day()) + "/" + month() + "/" + year();
    Blynk.virtualWrite(V10, "add", rowIndex, daybefore, totalMilliLitres / 1000 + String(" litre"));
    //highlighting latest added row in table
    Blynk.virtualWrite(V10, "pick", rowIndex);
    rowIndex++;
    flowMilliLitres = 0;
    totalMilliLitres = 0;
    //    currentMilliLitres = 0;
    daybefore = currentDate;
  }
}

// Reset History on virtual pin 3
BLYNK_WRITE(V3)
{
  int resetdata = param.asInt();
  if (resetdata == 1)
  {
    Serial.println("Clearing data");
    Blynk.virtualWrite(V0, 0);
    Blynk.virtualWrite(V1, 0);
    Blynk.virtualWrite(V12, 0);
    averageflow = 0;
    countseconds = 0;
    flowMilliLitres = 0;
    totalMilliLitres = 0;
    //    currentMilliLitres = 0;
  }
}

// Reset Table Data on virtual Pin 20
BLYNK_WRITE(V20)
{
  int resetdata = param.asInt();
  if (resetdata == 1)
  {
    Serial.println("Clearing table data");
    Blynk.virtualWrite(V10, "clr");
  }
}

void pulseCounter()
{
  pulseCount++;// Increment the pulse counter
}
void loop()
{
  ArduinoOTA.handle();
  Blynk.run();
  Timer.run();
  floatState();
}

here the tank level was full and the valve closed as expected


The following was when the level was low and the valve opened as expected and water flowed

when the tank was full the vale closed off

So is this topic solved now?

Pete.

It works but still need to be able to use the Slider value for some conditions and I just cannot get the value to use in the code.