How to use a variable from the slider widget in void loop?

Hardware: Node MCU ESP-12F

Hi, my Project is trying to control a Heating Plate with Relays to Keep the Fluid inside under the Set Temperature, and I wanted to use the Slider Widget to Change the Temperature where the heating plate turns on or off.
I’m using two Sliders for this, one that determines the Target Temperature and one that determines when the heater turns back on after the Target is reached.
And as you see in my code I’m Pulling the Value of the sliders with Blynk_Write but the variable that I assigned it to isn’t global, so I get the “was not declared in this scope” error, how do I solve this?

PS. I’m a Total noob in Arduino Programming

#define BLYNK_TEMPLATE_ID           ""
#define BLYNK_DEVICE_NAME           ""
#define BLYNK_AUTH_TOKEN            ""
#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>

const int oneWireBus = 4;

OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

char ssid[] = "TP Link";
char pass[] = "12345678";
char auth[] = BLYNK_AUTH_TOKEN;

BLYNK_WRITE(V4) //Temp Min
{
  int TempMin = param.asInt();
}

BLYNK_WRITE(V3)
{
  int Target = param.asInt();

}

void setup()
{
  pinMode(D3, OUTPUT);
  pinMode(D5, OUTPUT);

  Serial.begin(115200);
  sensors.begin();
  Blynk.begin(auth, ssid, pass);

}

void loop()
{
  Blynk.run();

  sensors.requestTemperatures();

  float temperatureC = sensors.getTempCByIndex(0);
  Serial.print(temperatureC);
  Serial.println("ºC");

  Blynk.virtualWrite(V1, temperatureC);

  if (temperatureC < Target) {
    digitalWrite(D3, LOW);       //Turn Relays on
    digitalWrite(D5, LOW);
    Blynk.virtualWrite(V2, 1);
  }

  if (temperatureC > TempMin) {
    digitalWrite(D3, HIGH);      //Turn Relays off
    digitalWrite(D5, HIGH);
    Blynk.virtualWrite(V2, 0);
  }
}

First of all, you should read this
https://docs.blynk.io/en/legacy-platform/legacy-articles/keep-your-void-loop-clean

I have, but the spamming issue is a non Problem because the CPU can’t keep up fast enough and only Runs at about 2 cycles per second, which is fine

You’re missing the point.

It’s not the processor that can’t keep up, it’s the sensor. You won’t have any joy with Blynk until you move that code out of the void loop into a function called with a timer.

As far as variable scope is concerned, that’s really a C++ programming 101 question, and there are lots of resources that explain how to manage variable scope.

Pete.

ok, thanks for the tip!
is that correct?

void setup()
{
  pinMode(D3, OUTPUT);
  pinMode(D5, OUTPUT);

  Serial.begin(115200);
  sensors.begin();
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(200L, temp_reading);
}

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

void temp_reading()
{
  sensors.requestTemperatures();

  float temperatureC = sensors.getTempCByIndex(0);
  Serial.print(temperatureC);
  Serial.println("ºC");

  Blynk.virtualWrite(V1, temperatureC);

  if (temperatureC < 100) {
    digitalWrite(D3, LOW);       //Turn Relays on
    digitalWrite(D5, LOW);
    Blynk.virtualWrite(V2, 1);
  }

  if (temperatureC > 95) {
    digitalWrite(D3, HIGH);      //Turn Relays off
    digitalWrite(D5, HIGH);
    Blynk.virtualWrite(V2, 0);
  }
}

Do you really need to take readings every 200ms?
If so then you should either reduce the resolution of your sensor or use a fatter sensor.

And you’re still declaring your variables locally.

Pete.

The 200ms was just for testing.
But how exactly would I declare variables globally? How can I use the temperatureC variable outside the temp_reading function?

Your help would be greatly appreciated.

global variable is a variable type that is declared outside any function and is accessible to all functions throughout the program.

for example

int target = 0;

BLYNK_WRITE(V1)  // slider widget
{
  target = param.asInt();  
}

Change it to 5000ms and you’ll make your life much simpler.

Pete.

Thank you so much John, it works now!

1 Like

Now i moved the If functions out of the temp_reading function because the relays would turn off and on very fast if the temperature was between target and tempMin, so I put them in the function relay, so that wouldn’t happen, but the problem is I declared temperatureC as float temperatureC = 0; but it doesn’t change globally, outside the temp_reading function its 0 C° as I specified in the declaration
How do I solve this?

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

void temp_reading()
{
  sensors.requestTemperatures();
  float temperatureC = sensors.getTempCByIndex(0);
  Blynk.virtualWrite(V1, temperatureC);
}

void relay()
{
  if (temperatureC < target) {
    digitalWrite(D3, LOW);       //Turn Relays on
    digitalWrite(D5, LOW);
    Blynk.virtualWrite(V2, 1);
  }

  if (temperatureC > tempMin) {
    digitalWrite(D3, HIGH);      //Turn Relays off
    digitalWrite(D5, HIGH);
    Blynk.virtualWrite(V2, 0);
  }
}

Post your whole sketch please.

#define BLYNK_TEMPLATE_ID           ""
#define BLYNK_DEVICE_NAME           ""
#define BLYNK_AUTH_TOKEN            ""
#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>

BlynkTimer timer;

const int oneWireBus = 4;

OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

char ssid[] = "TP Link";
char pass[] = "12345678";
char auth[] = BLYNK_AUTH_TOKEN;

float temperatureC = 0;
int target = 0;
int tempMin = 0;

BLYNK_WRITE(V3)
{
  target = param.asInt();
}

BLYNK_WRITE(V4)
{
  tempMin = param.asInt();
}

void setup()
{
  pinMode(D3, OUTPUT);
  pinMode(D5, OUTPUT);

  Serial.begin(115200);
  sensors.begin();
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(500L, temp_reading);
}

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

void temp_reading()
{
  sensors.requestTemperatures();
  float temperatureC = sensors.getTempCByIndex(0);
  Blynk.virtualWrite(V1, temperatureC);
}

void relay()
{
  Serial.print(temperatureC);
  Serial.println("ºC");

  if (temperatureC < target) {
    digitalWrite(D3, LOW);       //Turn Relays on
    digitalWrite(D5, LOW);
    Blynk.virtualWrite(V2, 1);
  }

  if (temperatureC > tempMin) {
    digitalWrite(D3, HIGH);      //Turn Relays off
    digitalWrite(D5, HIGH);
    Blynk.virtualWrite(V2, 0);
  }
}

You should go back to the structure of your previous ketch, where the code that is now in relay was in temp_reading.

The problem you had with the relays turning on and off rapidly was because of the logic of your if statements…

You checked if the temp was less than 100 and if it was turned the relays on. Then, immediately after checked if the temp was greater than 95 and if it was turned the relays off.
So, the code was doing exactly what you asked it to, but the logic is flawed.

Your second if test needs to be something like…

if (temperatureC > 102) {

That way, it would turn the relay on if the temp is below 100 and off when it reaches 102

Pete.

woops I switched target and tempMin by mistake, thanks

I did the relay thing because me idiot thought the timer on the reading function was causing the switching