Temperature controlled relay- NodeMcu and DS18B20

Hello everyone, I am new member and this is my first IOT project and I don’t have experience in programming.
I’ve tried to resolve my issue myself, also tried looking for similar project but I still can’t figure out what’s wrong and how to resolve it in mine.
I would like to built temperature controlled relays to switch on and off electric heaters.

Hardware used: NodeMcu v2, SSR relay and temperature sensor DS18B20
The idea is to use Blynk app to set the desired temperature with Slideg widget.

The problem is that when the sensor temperature reaches the temperature set on the Blynk slider the relay is not switching itself on or off while it should. ( For example the sensor temp is 25 and I set slider to 26 then the relay switches on, but when I warm the sensor to temperature above 26 it does not switch off the relay)

Could you please have a look at my code and help ?


#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <BlynkSimpleEsp8266.h>
#include <SPI.h>
#define BLYNK_PRINT Serial 
#define RELAY0_PIN 13

char auth[] = "317d787e96f24f23a2729a1be3e21***";
char ssid[] = "**********";
char pass[] = "*********";

int MenuItem = 1;


SimpleTimer timer;

#define ONE_WIRE_BUS 5 
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
double temp;
double setTemp;


void setup() {
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  DS18B20.begin();
  timer.setInterval(1000L, getSendData);
  pinMode(RELAY0_PIN, OUTPUT);
   digitalWrite(RELAY0_PIN, HIGH);

}

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

void getSendData()
{
  DS18B20.requestTemperatures();
  temp = DS18B20.getTempCByIndex(0);
  Serial.println(temp);
  Blynk.virtualWrite(5, temp);
}

BLYNK_WRITE(V40)
{

  double temp = DS18B20.getTempCByIndex(0);
  double setTemp = param.asDouble(); 
  Serial.print("V40 Slider value is: ");
  Serial.println(setTemp); 
   switch(MenuItem){
      case 1:
        if (temp > setTemp)
  {
    digitalWrite(RELAY0_PIN, LOW); 
      Serial.print("Relay OFF");}
      else {
        digitalWrite(RELAY0_PIN, HIGH);
     Serial.print("Relay On");
      }
        
}
}

/* ALTERNATIVE TO SWITCH 
  if (temp > setTemp)
  {
    digitalWrite(RELAY0_PIN, LOW); // relay you want to change
      Serial.print("Relay OFF");
      }
  else
  {
    digitalWrite(RELAY0_PIN, HIGH); // relay you want to change
     Serial.print("Relay On");
  }
}
 */


Your BLYNK_WRITE(V40) function is only triggered when the slider widget value changes.
You need to be checking the temperature in your getSendData function.

Once you get that working, you will find that your relay will turn on and off repeatedly when the temperature is hovering around the target setting. To overcome that, you need to include some tolerance that won’t turn the relays on/off unless the actual temperature is say 0.25° above or below target.

Pete.

Thank a lot Pete, I will try that.
I am currently busy with other things and had to leave my project for a while, but hopefully will find some spare time for IOT soon.

@PeteKnight
I 've tried your suggestion, but I am stuck now. The sketch is not compiling, and gives the error I have no Idea how to fix.

Could you please have a look?

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <BlynkSimpleEsp8266.h> // bo BLYNKS
#include <SPI.h>
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#define RELAY0_PIN 13

char auth[] = "317d787e96f24f23a2729a1be3e21f**";
char ssid[] = "****";
char pass[] = "**************";

int MenuItem = 1;


SimpleTimer timer;

#define ONE_WIRE_BUS 5 // DS18B20 on arduino pin2 corresponds to D4 on physical board 4 - D2 , 5 D1
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
double temp;
double setTemp;


void setup() {
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  DS18B20.begin();
  timer.setInterval(1000L, getSendData);
  pinMode(RELAY0_PIN, OUTPUT);
   digitalWrite(RELAY0_PIN, HIGH);

}

void loop() {
    timer.run(); // Initiates SimpleTimer
  Blynk.run();
}

void getSendData()
{
  DS18B20.requestTemperatures();
  temp = DS18B20.getTempCByIndex(0);
  Serial.println(temp);
  Blynk.virtualWrite(5, temp); 
double setTempera = BLYNK_WRITE(40);
 switch(MenuItem){
      case 1:
        if (temp > setTempera)
  {
    digitalWrite(RELAY0_PIN, LOW); 
      Serial.print("Relay OFF");}
      else {
        digitalWrite(RELAY0_PIN, HIGH); 
     Serial.print("Relay On");
      }
        
}

}
  
BLYNK_WRITE(V40)
{

  double temp = DS18B20.getTempCByIndex(0);
  double setTemp = param.asDouble(); // assigning incoming value from pin Vx to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("V40 Slider value is: ");
  Serial.println(setTemp); 
}/*
   switch(MenuItem){
      case 1:
        if (temp > setTemp)
  {
    digitalWrite(RELAY0_PIN, LOW); 
      Serial.print("Relay OFF");}
      else {
        digitalWrite(RELAY0_PIN, HIGH); 
     Serial.print("Relay On");
      }
        
}
} 

What error? Please don’t expect us do ALL your work :stuck_out_tongue_winking_eye:

I can’t make much sense of what you’re trying to achieve in your code. Some comments would help, but I think your logic and code structure is flawed at the moment.

You certainly can’t do this is in your void getSendData() function:

Pete.

@Gunner

your’ re right I was not specific.
The error I have is: exit status 1, Compilation error for NodeMCU…
What I am trying to achieve now is to move the comparison of set temperature with current temperature reading, and depending on that I would like the relay to switch on or off.
@PeteKnight noticed that I had placed that part of code in the Blynk write function which is only working when I use slider, so I moved that part of code to GetSendData but it was not working and was giving errors, so I had tried and currently while compiling the sketch it does not give me an error with the hint but only exit status 1 :frowning:

Hmm, generic enough error that could literally be anything from invalid library to a simple but undefinable (to the IDE) syntax error.

Showing verbatim error might help.

@PeteKnight
I had tried a few options. One of the wasdouble setTemp = param.asDouble(); But while compiling the code it was giving me an error that ‘parm’ is not declared or something like this.

I’d start by taking a step back and defining in broad terms what you’re trying to achieve.
Once you’ve done that, forget Blynk initially (but do bear in mind that when you put Blynk back into the equation it will need a clean void loop and to use timers to call functions).

From what I gather, you want to use Blynk to set your target temperature, then have your NodeMCU control the heating autonomously if the current temperature is below the target.
If this is the case then declare a global variable for your target temperature and assign a value to it. Refine your code so that it activates your relay if the temperature is below target and once this is working consistently use the Blynk widget controls to adjust the value of your target temperature.
If you want to use Blynk widgets to do other things like deactivate or override heating settings then define these requirements in your initial specification and add them in one at a time.

Pete.

@peterbart:
Just a guess: Is this what you’re trying to do?:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
#include <DallasTemperature.h>
#include <BlynkSimpleEsp8266.h> // bo BLYNKS
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#define RELAY0_PIN 13

char auth[] = "317d787e96f24f23a2729a1be3e21f**";
char ssid[] = "****";
char pass[] = "**************";

int MenuItem = 1;


SimpleTimer timer;

#define ONE_WIRE_BUS 5 // DS18B20 on arduino pin2 corresponds to D4 on physical board 4 - D2 , 5 D1
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
double temp;
double setTemp;

void setup() 
{
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  DS18B20.begin();
  timer.setInterval(1000L, getSendData);
  pinMode(RELAY0_PIN, OUTPUT);
  digitalWrite(RELAY0_PIN, HIGH);
}

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


void getSendData()
{
  DS18B20.requestTemperatures();
  temp = DS18B20.getTempCByIndex(0);
  Serial.println(temp);
  Blynk.virtualWrite(V5, temp); 
  switch(MenuItem)
  {
    case 1:
        if (temp > setTemp)
        {
          digitalWrite(RELAY0_PIN, LOW); 
          Serial.print("Relay OFF");
        }
        else 
        {
          digitalWrite(RELAY0_PIN, HIGH); 
          Serial.print("Relay On");
        }        
   }
}
  
BLYNK_WRITE(V40)
{
  double setTemp = param.asDouble(); // assigning incoming value from pin Vx to a variable
  Serial.print("V40 Slider value is: ");
  Serial.println(setTemp); 
}

@IBK
Thanks a lot Alex, you put me back on track.

I am facing now the problem that the switch is not going into the else part of case 1 what I tried is to swap the first and second condition but what I got is that either the relay is constantly on or off.

I’ve checked the serial monitor and it is constantly printing that the relay is on. Once I use the slider in Blynk it shows the value that is greater than current temperature reading but it is not switching the relay off an still printing relay on.

Do you reckon that I should not be using statement if and replace it with something, but with what?

I rekon you should brush up on your coding.

I would start with the difference between global and local variables.

Also I do not think a switch case (another thing you may want to research) is needed for this application.

Assuming you are in fact doing a heating controller you will probably want to follow the psudocode below:

  1. Get target temp from BLYNK App
  2. Get Actual temp from sensor
  3. Compare the two values
  4. Take action (activate relay, turn on fan, etc) based on the above comparison
  5. Repeat

@PeteKnight

Thanks :slight_smile: I can see you understand my concept, and that’s what I am trying to do.

I will use your advice and try with the global variables and define what’s needed in void setup()

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
#include <DallasTemperature.h>
#include <BlynkSimpleEsp8266.h> // bo BLYNKS
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#define RELAY0_PIN 13

char auth[] = "317d787e96f24f23a2729a1be3e21f**";
char ssid[] = "****";
char pass[] = "**************";


BlynkTimer timer;

#define ONE_WIRE_BUS 5 // DS18B20 on arduino pin2 corresponds to D4 on physical board 4 - D2 , 5 D1
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
double temp;
double setTemp;

void setup() 
{
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  DS18B20.begin();
  timer.setInterval(10000L, getSendData); //check every 10 seconds (could probable be every minute)
  pinMode(RELAY0_PIN, OUTPUT);
  digitalWrite(RELAY0_PIN, HIGH);
}

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


void getSendData()
{
  DS18B20.requestTemperatures();
  temp = DS18B20.getTempCByIndex(0);
  Serial.println(temp);
  Blynk.virtualWrite(V5, temp); 
        if (temp > setTemp)
        {
          digitalWrite(RELAY0_PIN, LOW); 
          Serial.print("Relay OFF");
        }
        else 
        {
          digitalWrite(RELAY0_PIN, HIGH); 
          Serial.print("Relay On");
        }        
}
  
BLYNK_WRITE(V40)
{
  setTemp = param.asDouble(); // assigning incoming value from pin Vx to a variable
  Serial.print("V40 Slider value is: ");
  Serial.println(setTemp); 
}

I think the issue you will find with the above code is that as the temp bounces above/below your setTemp your relay will be cycling on and off.

@Toro_Blanco
Thank you :slight_smile: I had started with the IOT just now and I have no experience in programming so the things that seem easy for others are hard or impossible for me.

It is working just the way I wanted it to work :slight_smile: thanks again
I will need to find a way to implement the tolerance like 0.25 or 0.5 so the relay is not bouncing/flickering when the temp is close to setTemp

an easy solution might be to increase the interval between temperature sensor readings. That way the temperature in the room has time to change enough to prevent the bouncing. Maybe every 5 minutes or so, depending on how fast the room cools/heats.

 timer.setInterval(300000L, getSendData);

or add this to your global variables

int hys = 5; //temp offset to prvent cycling

and change the if statement to this

if (temp > setTemp) {
digitalWrite(RELAY0_PIN, LOW);
Serial.print("Relay OFF");
}
else if (temp < (setTemp - hys))
{
    digitalWrite(RELAY0_PIN, HIGH); 
    Serial.print("Relay On");
}

If you plan on making this a hobby. I suggest you watch some YouTube Videos and do some reading on programming so you can understand how/why these things need to be certain ways, and how to accomplish certain tasks.

You may find that programming help, as such provided, is not usually given in this Community. ( I am currently just bored at work while waiting for our next project to start up)

I agree with @Toro_Blanco

Too many bemoan the same thing about lack of programming knowledge/ability as a reason for others to provide code. Having examples to work with is quite necessary (for me at least) but there is no real benefit to pursuing this hobby using others code without learning enough programming in order to fit it all together.

My programming experience was also zilch when starting with Blynk. I am by no means a programmer now, but I now know enough to work my way around most of the basics. Blynk has made that easier due the interactive GUI :slight_smile: but it is still NOT easy by any means :persevere:

We will try to help as we can, but it will go faster as you show your own work and efforts.

I keep this reference on my browser 24/7 - Arduino Reference - Arduino Reference

1 Like

@PeteKnight, @Toro_Blanco @IBK @Gunner

I’d like to say thank you :wink: to all of you for your time.
You gave me enough to work with, as well some hints and ideas how to work on my project and future projects.

I am going to work on the code now for a bit and let you know once I work out something nice :slight_smile:

1 Like