Blynk and While (Alternatives)

Hello Community.
Well, In my project I want to control the temperature of my room with a NodeMCU 1.0(ESP-12E). I would like to keep the temperature between 22 to 25 degrees (i.e). The idea i had was use while to make the MCU to wait and do not keep sending the command many times. but it make the rest of the program stop. I am using others sensors in my project such as DHT22, and a CT for current. Also I am using Infrared to communication with the AC.
I have tried this code for my project:

#include "EmonLib.h" // I got this library from open from OpenEnergy Monitor website
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include "ESP8266WiFi.h"
#include "BlynkSimpleEsp8266.h"
#include <DHT.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
//IR Signals to cool down the temperature to 22 and to set Fan Mode

uint16_t ON22 //Raw code signal from the remote controller. 
uint16_t FAN //Raw code signal from the remote controller.

IRsend irsend (4); 
#define DHTPIN 5     // what digital pin the DHT22 is conected to
#define DHTTYPE DHT22   // there are multiple kinds of DHT sensors
DHT dht(DHTPIN, DHTTYPE);
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "b77d33d0befc43a0a2d5508f8e86587b";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "SSID";
char pass[] = "Password"; 
EnergyMonitor emon1;
 
 
// 220V is my Electrical Network voltage default.
int network = 220;
 
//Pin of sensor SCT
int pino_sct = A0;

 
void setup()
{
  irsend.begin();
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  //Pin, calibration - Cur Const= Ratio/BurdenResistor. 2000/24 = 85
  emon1.current(pino_sct, 85);
 

}
 BLYNK_WRITE(V1) //I set the botton V1 as switch mode.
 {
    int EcoMode= param.asInt();// .
    float t = dht.readTemperature(); // 
    if(EcoMode == 1)// 
    {
      if (t<22){
   
         irsend.sendRaw(FAN,349,38);// 349 is the variable size and 38 is the frequency in kHz.
        
while(t<22) { } //wait until temperature is over 22.
}
         
      if(t>25) {
        irsend.sendRaw(ON22,349,38);
 while (t>25) { } //wait until temperature is under 25
        }
        Blynk.run(); // Run rest of show in-between waiting for this loop to repeat or quit.
      int EcoMode = 0;  // Set V1 status to 0 to quit, 
      Blynk.syncVirtual(V1); // ...Then force BLYNK_WRITE(V1) function check of button status to determine if repeating or done.
        
                }
 }
 
BLYNK_READ(V2){
  double Irms = emon1.calcIrms(1480);
  Blynk.virtualWrite(V2,Irms);// Current.
}
BLYNK_READ(V3){
  double Irms = emon1.calcIrms(1480);
  Blynk.virtualWrite(V3,Irms*network); // The consumption of energy. 
}
BLYNK_READ(V4) {  
    float t = dht.readTemperature();
    Blynk.virtualWrite(V4,t); 
}
   BLYNK_READ(V5) {  
    float h = dht.readHumidity();
    Blynk.virtualWrite(V5,h);
   }
  
   
void loop()
{
 Blynk.run(); 
}

So the idea is when the botton V1 is pressed, the AC would enter in ā€œEcoModeā€ so this set a temperature interval and keep turning off and On the AC Compressor to save energy. So its basically a energy monitor with automation control for energy efficiency.

I was wondering if the only solution is use BlynkTimer for solve this. If you have other suggestions to improve my code I would appreciate too.

When running the Blynk library it is recommended to avoid any blocking codeā€¦ like while

It is also recommended to use timers

Here is some reference material to useā€¦

Iā€™ve done some experimentation with heating/cooling using my inverter aircon system and although Iā€™ve not finalised the setup yet, my plan is to effectively override the temperature sensor in the A/C unit and use my ESP8266 attached temperature sensor instead.
If Iā€™m using cooling mode then Iā€™ll be setting the A/C to its lowest temperature (18 degrees) and running it until the ESP8266 temperature sensor (DHT22 in your case) says weā€™ve earned the target temperature. At that point Iā€™ll either switch the A/C off, or put it in fan only mode - this will ultimately depend on the type of A/C unit and how it responds to various situations.
In heating mode Iā€™ll set the temperature to maximum 30 degrees and run it until my target temperature is reached.

The important thing with temperature control is to use Hysteresis code that builds-in a temperature tolerance that prevents the heater/cooler switching on and off every few seconds.
Say you want to use a tolerance of 0.5 degree and your target temperature is 22 degrees and youā€™re trying to cool your room. In this situation, you wouldnā€™t switch the aircon on until the temperature is 22.5 degrees and you wouldnā€™t turn it off until the temperature is 21.5 degrees. Youā€™ll need to experiment with the tolerance levels as it will depend on the power of your aircon unit and the size of your room - plus your personal preference for temperature differentials.

I realise that this doesnā€™t answer your original question though. I think youā€™ll want to use a timer to check your room temperature every so often. Once every 10 seconds maybe? In cooling mode, if the temperature is above 22.5 degrees then send the 18 degrees cooling command. If itā€™s below 21.5 degrees then send the off, or fan only command.

Pete.

@PeteKnight why are you sending max 30 and min 16 degrees and nothing in between? Isnā€™t that putting unnecessary stress on the compressor (and your wallet)? I know you are powering off when you reach your target temperature but surely thatā€™s not the optimum way of getting there.

@PeteKnight I didnā€™t get that :disappointed_relieved:

Well In my case just cooling mode would be necessary for my project so I believe I can save some energy setting intervals of temperature instead setting just one temperature so the AC doesnā€™t need to switches a lot of times to keep the target. Moreover, the temperature can still maintain the environment comfortable. In my region is very hot, something about 30 and 35 degrees (86F and 95F ) So if I keep the room temperature between 22 and 25 it could be interesting.

The code I am aiming is:

If botton ā€œEcoModeā€ press
loop() {
check the temperature
If (t<22)
fan mode to raise the temperature until 25
if(t>25)
cool down until 22 degrees}
keep running the rest of program parallel with the loop

My aircon runs at the same power, regardless of the temperature you set. All Iā€™m doing by sending an 18 degrees cooling message is to ensure that the aircon thermostat and the ESP thermostat arenā€™t working against each other. The aircon uses tolletrnces as well, so itā€™s very easy to get to a situation where they are fighting against each other.

Pete.

You are probably right @PeteKnight
I was just thinking that air con engineers always tell you to forget about max and min unless you own an oil well :slight_smile:

@Victor_Caravelas_Sou the hysteresis is basically not selecting 2 numbers like your 22 and 25 because at each end of the range it can trigger on and off repeatedly.

I got it. So that is my point! I believe the time that the temperature takes to get 25 from 22 is enough to save some energy. In usual air con (not inverter) which are the majority here this could work.

but only if t < 22 for X seconds and t > 25 for y seconds to prevent constant triggering, OK?

I thought he explained it very good :slight_smile: As the DHT22 has a resolution of 0.1, temperature readings between 21.6 and 22.4 will not trigger any action. I use timer to check my sensor(s) once a minute:

timer.setInterval(60000L, getSensorData); // get temp sensor every 60s

My function just updates the app:

void getSensorData() {
	DS18B20.requestTemperatures(); 
	temp = DS18B20.getTempCByIndex(0);
	// If you don't have enough Blynk-Juice to afford the fancy Labeled Value ;)
	float roundedValue = ceilf(temp * 100) / 100;
	Blynk.virtualWrite(5, roundedValue);
}

Add some conditions in the function like
if (temp > 22.5) { // Send IR cmd to start A/C }
if (temp < 21.5) { // Send IR cmd to stop A/C }

Something like that will workā€¦ I think. :face_with_raised_eyebrow:

(Pssst! If you are experimenting - RFM69 has a built in temp sensor :wink: )

Iā€™m not keen on devices that have built-in temperature sensors as youā€™re almost certain to get some warming effect from the device itself. Also in a real world situation you could get some warming from the power supply, depending on how you power it.

This is why Iā€™ve not implemented my system yet. I was waiting for some different sensors and some plastic cases to arrive, which I now have. The ESP (Iā€™ll be using Wemos D1 Minis) willl be mounted in a small case and powered via 5v from a mains adaptor. The temperature/humidity sensor will be a BME280 (I donā€™t need the pressure sensor for the indoor sensors, but Iā€™ll be using one of these in my outdoor weather station, so want to keep the same hardware throughout). The sensor will be mounted in a separate ventilated case that allows good airflow and connected via a length of wire to the Wemos, to avoid any possible heating effect.

Pete.

1 Like

Valid point, proven by ATmega he he:

The measured voltage has a linear relationship to the temperature as described in Table 24-2. The voltage sensitivity is approximately 1 mV/Ā°C and the accuracy of the temperature measurement is +/- 10Ā°C.

Good to know youā€™re working on a similar project as me. Iā€™m using ESP-07 instead of Mini D1 or NodeMCU this time, mainly because of power consumption and external antenna connector, and I can also drill mounting holes on ESP ā€˜whiteā€™ board. My BMEā€™s just arrived few days ago and this sensor is really, really good, way better than DHT family I previously experimented with. DHT reading time is 250ms on average and for this 250ms your mcu is dead, itā€™s unusableā€¦

Yes, my BMEā€™s arrived about a week ago and Iā€™m very impressed. The pressure reading was out by a couple of Kpa, but Iā€™ve fixed that in the code and itā€™s not something that Iā€™m too worried about - Iā€™m more interested in trends rather than absolute values but it would be nice if I could get a fairly accurate reading as Iā€™d like to push some data to Weather Underground at some point.
Power consumption isnā€™t an issue for me as I wonā€™t be able to do deep sleep because Iā€™m using interrupts on the wind speed and rainfall sensors.
Iā€™m hopefully going to be able to use just one Wemos to measure:

Windspeed
Wind direction
Rainfall
Rain drop detection
Light level
Temperature
Pressure
Humidity

Iā€™ve got the first three working together okay, and the last three working together as well. I just need to get all of the kit together in one place and see if one MCU can handle everything without losing accuracy.

Pete.

I might be wrong, but I think itā€™s like this: A reading might take ~250 ms, i.e. the first reading after start-up. The extra time is supposedly needed for the sensor to initialize correct. In the latest lib for DHT22, only 1 ms (18 ms for DHT11) is used for the wake-up call and and the data transfer takes about 5 ms. Thatā€™s a total of 6 ms! Perhaps you just need to update your lib to make it go faster.

https://playground.arduino.cc/Main/DHTLib

I have five DHT-22ā€™s working in my home network, and the latency I got on mcu every time DHT sends itā€™s readings is unacceptable. It might be up to library Iā€™ve used, but now itā€™s an old topic already, BME will be my choice in the future.

I think I found the culprit for the high latency! Since the sensors are very popular and widely used, others may find this to be of interest. If you Google DHT22, chances are youā€™ll end up at Adafruitā€™s homepage and consequently pick their library.

In the DHT.cpp from their library you find this:

 `pinMode(_pin, INPUT_PULLUP);`

and

  // Go into high impedence state to let pull-up raise data line level and
  // start the reading process.
  digitalWrite(_pin, HIGH);
  delay(250);

This doesnā€™t make any sense! Itā€™s an open drain bus and at idle it should already be HIGH, which is (normally) accomplished by using an external pull-up resistor. This is also how Adafruit wire the board on their online example. For this reason, the 250 ms delay is a complete waste of time as far as I can tell.

Also, the line should never actively be driven high when using open drain.

Just thinking out loudā€¦

1 Like