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?