Blynk properties not changing in my project

Dear blynk friends hello everyone!
I’m a blynk user since one year and I really love this awesome app!

Now, I completed my last project with Wemos D1 mini and blynk and I’m finding some trouble using the Blynk.setProperty function.
My idea was to change the color of the menu character according to the selected item. In particular the menu contains the Air conditioner modes (OFF, Cool, Heat, Dry, AUTO), but changing the selected item, the color doesn’t change except for the OFF color (GRAY in the sketch).

/*
    This sketch uses Blynk to:
    1. Control an A/C using an IR LED.
    2. Reading a Temperature and Humidity sensor
    3. Turn on a Luminaire using an auxiliary relay actuating a Lamp dimmer
    4. Check if the light has been turned using a mains sensing circuit
    5. Check the lighting status using an LDR connected to the analog input

    All these stuff has been programmed for a Wemos D1 mini
    Real PIN Assignment:
    D0 - mains sensing pin
    D1 - relay pin
    D2 - Dallas 18b20 sensor. NOTE: if you use athe parassite mode, use a 1k pull-up resistor
    D3 - unassigned
    D4 - built-in LED - calibration indicator
    D5 - unassigned
    D6 - IR led
    D7 - unassigned
    D8 - LDR calibration button pin
    A0 - LDR analog pin
    Virtual PIN Assignment:
    V1 relay app activation
    V2 mains status app updating
    V3 LDR status app updating
    V4 A/C mode
    V5 Fan speed
    V6 A/C temeprature set point
    V7 A/C Vertical swing
    V8 A/C Horizontal swing
    V9 Powerfull/Quite
    V12 Dallas temperature sensor pin
*/

//#define BLYNK_DEBUG
//#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

//libraries for Heat pump control
#include <Arduino.h>
#include <PanasonicHeatpumpIR.h>

//OTA update libraries
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

//Dallas sensor ds18b20 library
#include <OneWire.h>
#include <DallasTemperature.h>

// ThingSpeak library
#include "ThingSpeak.h"

//Timing with elapsedMillis
#include <elapsedMillis.h>

elapsedMillis pulse; // time counter of the high/low state of the blink
elapsedMillis duration; //time counter of the blinking period

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

//setting Wlan
char ssid[] = "xxxxxxxxxxxx";
char pswd[] = "xxxxxxxxxxxxx";


//Virtual and physical pin settings
#define sensorPin D0 // mains sensing pin
#define RELAY_PIN D1 //pin D1 assigned to relay
#define T_pin D2 // pin assigned to the DS18b20 temperature sensor
#define indicatorLedPin D4 // built-in LED
#define IR_LED_pin D6 // pin assigned to the IR Led for A/C remote controlling 
#define buttonPin D8 // pin that the button is attached to
#define LDRpin A0 //LDR analog input
#define Relay_vPin V1 //relay app activation
#define mains_stat V2 //mains status app updating
#define LDR_Vpin V3 //LDR status app updating
#define AC_mode V4 // virtual pin for A/C mode
#define AC_fan V5 // virtual pin for A/C Fan speed
#define AC_Temp V6 // virtual pin for A/C temperature set point
#define AC_Vsw V7 // virtual pin for A/C Vertical swing
#define AC_Hsw V8 // virtual pin for A/C Horizontal swing
#define AC_PQ V9 // virtual pin for Powerfull/Quite
#define Dallas_vpin V12 // ds18b20 ambient temperature

//Set relay variables
int valueR;
boolean trigg = false;
unsigned long curr_time;

//Set mains sensing variables
#define n_sample 500
int mainsValue;
byte sensorValue;
WidgetLED led1(mains_stat);

//*Set LDR*/
int LDRValue; //analog reading for LDR
int sensorMin = 0;  // minimum sensor value
int sensorMax = 1023;     // maximum sensor value
bool btn; //button status
bool cal_trg; //calibration trigger status
unsigned long cal_time = 10000; //calibration time duration
unsigned long cal_start; //calibration starting
int ledState; //led indicator for calibration status
const long interval = 250;           // interval at which to blink (milliseconds)
int count = 0; //variable storing the number of blinks 
/************Temperature acquisition setting*******************/
// //Temperature acquisition setting
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(T_pin);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
float celsius; //global variable for temperature recording
/**************************************************************

  /*************ThingSpeak settings************************/
WiFiClient  client;
unsigned long myChannelNumber = xxxxx;
const char * myWriteAPIKey = "xxxxxxxxxxxx";

/*************IR SETTING********************************/
IRSenderBitBang irSender(IR_LED_pin);
PanasonicDKEHeatpumpIR *heatpumpIR = new PanasonicDKEHeatpumpIR(); //Panasonic A/C model selected

//Global variable controlling the A/C settings
uint8_t mode0 = MODE_AUTO; //A/C mode, default "AUTO"
uint8_t fan = FAN_1; //fan speed default "FAN1"
uint8_t T_set = 25; //set point temperature
uint8_t V_swing = VDIR_MIDDLE ; // vertical swing default "MIDDLE"
uint8_t H_swing = HDIR_MIDDLE ; // horizontal swing default "MIDDLE"
boolean ac_powerfull = false ;
boolean ac_quiet = false ;

//////////Setting menu color///////////
#define BLYNK_GREEN     "#23C48E"
#define BLYNK_BLUE      "#0000ff" //original "#04C0F8"
#define BLYNK_YELLOW    "#ED9D00"
#define BLYNK_RED       "#D3435C"
#define BLYNK_DARK_BLUE "#5F7CD8"
#define BLYNK_GRAY "#CCCCB3"

String menuColor = BLYNK_GREEN; //default value
String newColor;

BlynkTimer timer;

void pushrelay()
{
  if (valueR == 1)
  {
    trigg = true;
    curr_time = millis();
  }

  if ((trigg) && (millis() - curr_time) < 500) {
    digitalWrite(RELAY_PIN, HIGH);
    //Serial.println("acceso");
  }

  else
  {
    digitalWrite(RELAY_PIN, LOW);
    //Serial.println("spento");
    trigg = false;
  }
}

//Mains sensing function
void mains_sense()
{
  sensorValue = digitalRead(sensorPin);

  if (sensorValue == 1)
  {
    digitalWrite(indicatorLedPin, LOW);
    //Serial.println("Light ON");
    led1.on();
  }
  else
  {
    led1.off();
    //Serial.println("Light OFF");
    digitalWrite(indicatorLedPin, HIGH);
  }
  // Serial.println(sensorValue);
}

/**************Temperature reading*********************/

void DS18b20() {
//REMINDER: if you use the parassite mode, use a 1k pull-up resistor max
  sensors.requestTemperatures(); // Send the command to get temperature readings
  celsius =  sensors.getTempCByIndex(0); // Why "byIndex"?
  // You can have more than one DS18B20 on the same bus.
  // 0 refers to the first IC on the wire

  //send Temperature
  Blynk.virtualWrite(Dallas_vpin, celsius);
  /*Serial.print("Temp. = ");
    Serial.print(celsius);
    Serial.println("°C");*/
}

/**************LDR Calibration process*********************/
void calChk() {
  btn = digitalRead(buttonPin);
  if (btn == 1) {
    cal_trg = HIGH;
    sensorMin = 1023;  // reset thr minimum sensor value
    sensorMax = 0;     // reset thr maximum sensor value
    cal_start = millis();
    duration = 0;
  }
}

  //Function enabling the calibration process
  void cal_enable() {

     if ((millis() - cal_start) <= cal_time) { //setting the calibration timeout
      calibrate();
      blinking(interval, cal_time, cal_trg, indicatorLedPin);
    }
    else {
      cal_trg = LOW;
    }
  }
  void blinking( unsigned long interval, unsigned long period, bool trig, int pin ){
    
  if (duration < period && trig == HIGH){
  if (pulse > interval) 
  {        
      ledState = !ledState;         // toggle the state from HIGH to LOW to HIGH to LOW ... 
      digitalWrite(pin, ledState);
      pulse = 0;              // reset the counter to 0 so the counting starts over...
  }
  }
  else{
   trig = LOW;
}
}

  //calibrate the maximum and minimum light sensor reading
  void calibrate() {

    // read the sensor:
    LDRValue = analogRead(LDRpin);

    // record the maximum sensor value
    if (LDRValue > sensorMax) {
      sensorMax = LDRValue;
    }

    // record the minimum sensor value
    if (LDRValue < sensorMin) {
      sensorMin = LDRValue;
    }
    /* Serial.print(LDRValue);
      Serial.print(" ,");*/
    //delay(200);

  }
  void LDRsens()
  {
    int A_values[20] = {0};
    for (int i = 0; i < 20; i++) {
      A_values[i] = analogRead(LDRpin);
    }
    int A_sum = 0; //A_sum reset
    for (int j = 0; j < 20; j++) {
      A_sum = A_values[j] + A_sum;
    }
    LDRValue = A_sum / 20; //averaged LDR value

    LDRValue = analogRead(LDRpin);/*Analog reading of the LDR pin */

    // apply the calibration to the sensor reading
    LDRValue = map(LDRValue, sensorMin, sensorMax, 0, 100);

    // in case the sensor value is outside the range seen during calibration
    LDRValue = constrain(LDRValue, 0, 100);

    /* Serial.print("Normalized Light measure ");
      Serial.print(LDRValue);
      Serial.println(" %");
      Serial.print("sensorMax ");
      Serial.println(sensorMax);
      Serial.print("sensorMin ");
      Serial.println(sensorMin);*/
    Blynk.virtualWrite(LDR_Vpin, LDRValue); // Write to a virtual pin the room light status
  }

  /*********IR control system*********/

  BLYNK_WRITE(AC_mode)
  {
    int i  = param.asInt(); // Get value as integer
    Blynk.syncVirtual(AC_fan, AC_Temp, AC_Vsw, AC_Hsw);

    switch (i)
    {
      case 1:
        newColor = BLYNK_GRAY;
        break;
      case 2:
        mode0 = MODE_COOL;  break; //COOL
        newColor = BLYNK_BLUE;
      case 3:
        mode0 = MODE_HEAT;  break; //HEAT
        newColor = BLYNK_RED;
      case 4:
        mode0 = MODE_DRY; break; //DRY
        newColor = BLYNK_YELLOW;
      case 5:
        mode0 = MODE_AUTO; break; //AUTO
        newColor = BLYNK_GREEN;
    }

    if (i == 1) {
      heatpumpIR->send(irSender, POWER_OFF, mode0, fan, 25, V_swing, H_swing);
    }
    else {
      heatpumpIR->send(irSender, POWER_ON, mode0, fan, T_set, V_swing, H_swing, ac_quiet, ac_powerfull);
    }
    Blynk.setProperty(AC_mode, "color", newColor);
  }

  /*void colorChange() {
    if (newColor != menuColor) {
      menuColor = newColor;
      Blynk.setProperty(AC_mode, "color", newColor);
    }
    }*/
  BLYNK_WRITE(AC_fan) {
    int i  = param.asInt(); // Get value as integer
    switch (i) {

      case 1:
        fan = FAN_1;  //FAN1
        break;
      case 2:
        fan = FAN_2;  //FAN2
        break;
      case 3:
        fan = FAN_3;  //FAN3
        break;
      case 4:
        fan = FAN_4; //FAN4
        break;
      case 5:
        fan = FAN_5; //FAN5
        break;
      case 6:
        fan = FAN_AUTO; //FAN_AUTO
        break;
    }
  }
  BLYNK_WRITE(AC_Temp) {
    int T  = param.asInt(); // Get value as integer
    T_set = constrain(T, 16, 30); //set the Air cond. temperature by app
  }

  BLYNK_WRITE(AC_Vsw) {
    int V  = param.asInt(); // Get value as integer
    switch (V) {

      case 1:
        V_swing = VDIR_UP;  //VS_UP
        break;
      case 2:
        V_swing = VDIR_MUP;  //VS_MUP
        break;
      case 3:
        V_swing = VDIR_MIDDLE;  //MIDDLE
        break;
      case 4:
        V_swing = VDIR_MDOWN; //VS_MDOWN
        break;
      case 5:
        V_swing = VDIR_DOWN; //VS_AUTO
        break;
      case 6:
        V_swing = VDIR_AUTO; //VS_AUTO
        break;
    }
  }

  BLYNK_WRITE(AC_Hsw) {
    int H  = param.asInt(); // Get value as integer
    switch (H) {

      case -2:
        H_swing = HDIR_LEFT;  //HS_LEFT
        break;
      case -1:
        H_swing = HDIR_MLEFT;  //HS_MLEFT
        break;
      case 0:
        H_swing = HDIR_MIDDLE;  //HS_MIDDLE
        break;
      case 1:
        H_swing = HDIR_MRIGHT; //HS_MRIGHT
        break;
      case 2:
        H_swing = HDIR_RIGHT; //HS_RIGHT
        break;
      case 3:
        H_swing = HDIR_AUTO; //HS_AUTO
        break;
    }
  }

  BLYNK_WRITE(AC_PQ) {
    int p  = param.asInt(); // Get value as integer
    switch (p) {
      case 0:
        ac_powerfull = false; ac_quiet = false; break;
      case 1:
        ac_powerfull = true; ac_quiet = false; break;
      case 2:
        ac_powerfull = false; ac_quiet = true; break;
    }
    heatpumpIR->send(irSender, POWER_ON, mode0, fan, T_set, V_swing, H_swing, ac_quiet, ac_powerfull);
  }



  BLYNK_WRITE(Relay_vPin)
  {
    valueR = param.asInt(); // Get value as integer
  }

  /*********ThingSpeak comunication*********/

  void ThSpeakWrite() {
    ThingSpeak.writeField(myChannelNumber, 2, celsius, myWriteAPIKey);
  }
  void setup()
  {

    pinMode(RELAY_PIN, OUTPUT);
    pinMode(sensorPin, INPUT);
    digitalWrite(RELAY_PIN, LOW);
    pinMode(indicatorLedPin, OUTPUT);
    pinMode(buttonPin, INPUT);
    Serial.begin(9600);
    delay(100);
    //setting Dallas sensor
    sensors.begin();
    // set the resolution to 9-12 bit (Each Dallas/Maxim device is capable of several different resolutions)
    sensors.setResolution(12);
    //Booting
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, pswd);
    Blynk.begin(auth, ssid, pswd);
    delay(100);
    Serial.begin(9600);
    delay(100);
    // Functions timing setup
    timer.setInterval(2000L, DS18b20);
    //timer.setInterval(1500L, colorChange);
    timer.setInterval(300000L, ThSpeakWrite);
    timer.setInterval(250L, pushrelay);
    timer.setInterval(1000L, mains_sense);
    timer.setInterval(500L, LDRsens);
    timer.setInterval(1001L, calChk);

    delay(100);
    /***************OTA updating code***************/

    while (WiFi.waitForConnectResult() != WL_CONNECTED) {
      Serial.println("Connection Failed! Rebooting...");
      delay(5000);
      ESP.restart();
    }
    // Hostname defaults to esp8266-[ChipID]
    ArduinoOTA.setHostname("bedroom");

    // No authentication by default
    ArduinoOTA.setPassword((const char *)"1234");

    ArduinoOTA.onStart([]() {
      Serial.println("Start");
    });
    ArduinoOTA.onEnd([]() {
      Serial.println("\nEnd");
    });
    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    });
    ArduinoOTA.onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
      else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
      else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
      else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
      else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });
    ArduinoOTA.begin();
    Serial.println("Ready");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }


  void loop()
  {
    ArduinoOTA.handle();

    if (cal_trg) {
      cal_enable();
      //Serial.println("Calibration");
    }
    else {
      timer.run();
      Blynk.run();
    }
  }

I have no idea about the possible cause.
I noticed also a certain lagging in the response time of the hardware to the commands from the app. For example, if I set the relay ON period to 500 ms in the sketch, i find in the real execution a random variable ON time, between 0.5 and 2 seconds.
Is it posible that the blynk cloud is not enough for the execution of my code, and I would need a local blynk server?
Is it a problem related to the ArduinoOTA.handle() in the main loop?
Do you have any idea?

It’s a bit strange!
No one has any idea?

Hello. You have to many code to give you an answer. Please try to comment step by step your code until you find a cause.

1 Like

No, that’s fine.

It’s because you have missed the break statements from the switch function for all options except GRAY.

1 Like

Ops! This is embarassing. I made a really stupid error. Probably I went drunk!
Thank you so much Costas!
I’ll try all the code separating the functions to figure out about the timing lagging, as suggested by Dmitriy.

Dear friends I found the problem for the “lagging in the response time”!
It was due to the bad coding of the main loop. this is the bad part of the code:

void loop()
  {
    ArduinoOTA.handle();

    if (cal_trg) {
      cal_enable();
      //Serial.println("Calibration");
    }
    else {
      timer.run();
      Blynk.run();
    }

I know everywere in the Blynk documentation it’s reported to put in the main loop the only timer.run() and blynk.run() but, I was thinking that the little change would not affect the code functionality, like in the HandleDisconnect example !
I was wrong!
I modified the code so that the cal_enable() function has a normal timing set using the usual timer.setInterval(), and now everything runs well.

2 Likes