@Dmitriy full sketch below. The problem area is in BLYNK_WRITE(V5) from row 197. You will see many of the lcd.print commands are commented out as they crash the system with them in.
//#define BLYNK_DEBUG
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
#include <ESP8266_HardSer.h>
#include <BlynkSimpleShieldEsp8266_HardSer.h>
#include <avr/wdt.h> // watchdog timer, maybe set at 4 seconds in the sketch
#include <EEPROM.h>
int address = 100; // first EEPROM address
int MemoryValue; // EEPROM value for calibrating temperature sensor
#define EspSerial Serial // Set ESP8266 Serial object
ESP8266 wifi(EspSerial);
char auth[] = "8cb0a1931a1a402881cf348f0axxxxx";
WidgetLCD lcd(V0);
byte GreenLED = 2; // green led on pin 2
byte CentralHeating = 0;
byte ModeCount = 0 ; // select different modes of operation
// RF Variables
int rfsignal = 0; // variable to count number of signals received, maximum 200
int timeDelay = 105; // The variable used to calibrate the RF signal lengths.
#define rfTransmitPin 10 // digital 10 //RF Transmitter pin - THIS IS FOR CHEAP TRANSMITTER DVG
// see also VirtualWire message transmit pin set the same at row 82
#define voltagePin 9
#define groundPin 8
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into pin A3 on the Arduino
#define ONE_WIRE_BUS A1 // was 3 digital now analogue pins
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
#define TempvoltagePin A0
#define TempgroundPin A2
int TempNow = 0;
String TempSuffix = "ºC"; // remember create separate strings before trying to print or write them to Blynk
//String TimeSuffix = " Minute(s)";
String TimePrefix = " ";
String CurrentTemp;
String CurrentTime;
int Calibrate = 91; // percentage to calibrate temperature sensor to real temperature
byte TimerStarted = 0;
int CountdownTime = 0; // number of minutes for time to countdown
int STEP = 1; // default timer STEP adjustment on Pin V6 is 1 minuute (can be set from 1 to 20 minute steps)
#include <SimpleTimer.h>
SimpleTimer timer;
void setup()
{
pinMode(GreenLED, OUTPUT); // set D2, green LED, as output
digitalWrite(GreenLED, LOW); // turn green LED OFF
pinMode(TempgroundPin, OUTPUT);
digitalWrite(TempgroundPin, LOW);
pinMode(TempvoltagePin, OUTPUT);
digitalWrite(TempvoltagePin, HIGH);
pinMode(groundPin, OUTPUT);
digitalWrite(groundPin, LOW);
pinMode(voltagePin, OUTPUT);
digitalWrite(voltagePin, HIGH);
pinMode(rfTransmitPin, OUTPUT); //Transmit pin is an output
//pinMode(SwitchPin, INPUT_PULLUP); // set D5 as input but set high when not pressed
sensors.requestTemperatures(); // start temperature sensor
Serial.begin(9600); // Set console baud rate
delay(10);
timer.run(); // Initiates SimpleTimer
timer.setInterval(2000L, refreshLCD); // refresh LCD if needed every x seconds
timer.setInterval(40000L, sendTemp); // send current temperature to lcd V0 every 40 seconds
timer.setInterval(60000L, CheckTimer); // check timer every 60 seconds(EVERY MINUTE)
EspSerial.begin(115200); // Set ESP8266 baud rate
delay(10);
Blynk.begin(auth, wifi, "GargoyleTest", "xxxxx");
while (Blynk.connect() == false) {
// Wait until connected
}
// all Blynk stuff must be done AFTER connection
lcd.clear();
lcd.print(0, 0, "OFF");
TempNow = (((sensors.getTempCByIndex(0)* Calibrate)*1)+50)/100; // 50 is for rounding
CurrentTemp = TempNow + TempSuffix;
lcd.print(11, 0, CurrentTemp); // display temperature on line 0 from character 11
lcd.print(3, 1, "0 Minute(s)"); // set initial lcd details for manual mode on second row
NEWtransmitFixedCode(); // turn system off on restart
wdt_enable(WDTO_8S); // set WDT to 8 seconds
MemoryValue = EEPROM.read(address);
if ((MemoryValue > 79) && (MemoryValue < 121)){
//Serial.print(" Calibration value is "); // change this to LCD
//Serial.println(MemoryValue, DEC);
Calibrate = MemoryValue;
}
else{
// EEPROM will only be updated if value for Calibrate changes
EEPROM.update(address, Calibrate); // if no value in address 0 write 95 % calibration percentage
delay(20);
}
}
void(* resetFunc) (void) = 0; //declare reset function @ address 0 THIS IS VERY USEFUL
BLYNK_WRITE(V1) // reads virtual push button V1 but only when it is pressed
{ // this is main ON / OFF button
int VSwitch = param.asInt(); // read V1
if (VSwitch == 1){
if (CentralHeating == 0){ // central heating was off so turn it on
HeatingOn();
}
else{ // central heating was on so turn it off
HeatingOff();
TimerStarted = 0; // switch off timer if it was on
}
NEWtransmitFixedCode();
}
}
BLYNK_WRITE(V2) // reads virtual push button V2 but only when it is pressed
{ // this is mode / timer button
int V2Switch = param.asInt(); // read V1
if (V2Switch == 1){
if (ModeCount == 0){
lcd.print(0, 1, " PLUS to Change ");
ModeCount++; // only needed once to prompt for PLUS button Mode menu
}
else{ // PLUS button has been pressed at least once so start using the new mode
lcd.print(0, 1, " POWER to Start");
ModeCount = 0; // clear ModeCount so LCD will go back to refreshing
}
}
}
BLYNK_WRITE(V3) // Widget is reading AM timer on V3
{
int AMTimer = param.asInt();
if (AMTimer == 1) {
HeatingOn();
}
if (AMTimer == 0) {
HeatingOff();
}
NEWtransmitFixedCode();
}
void intsize(){ // no negatives for time but there can be for temperature to -99 degrees
// valLen not currently needed
if(CountdownTime > 999){
TimePrefix = "";
}
else if(CountdownTime > 99){
TimePrefix = " ";
}
else if(CountdownTime > 9){
TimePrefix = " ";
}
else if(CountdownTime < -9){
TimePrefix = " ";
}
else if(CountdownTime < 0){
TimePrefix = " ";
}
else{
TimePrefix = " ";
}
}
BLYNK_WRITE(V4){ // widget for MINUS time or temperature
int MinusBtn = param.asInt();
if (MinusBtn == 1){
if (CountdownTime > 0){
CountdownTime = CountdownTime - STEP;
}
else{
CountdownTime = 1440; // reset minutes from 0 to 1440
}
intsize();
CurrentTime = TimePrefix + CountdownTime;
Serial.println();
Serial.println(CurrentTime);
//lcd.clear(); // this crashes the system, why?
lcd.print(0, 1, CurrentTime);
}
}
BLYNK_WRITE(V5){ // widget for PLUS time or temperature
int PlusBtn = param.asInt();
if (PlusBtn == 1){
if (ModeCount == 0){ // only increase time if not in mode change
if (CountdownTime < 1440){
CountdownTime = CountdownTime + STEP;
}
else{
CountdownTime = 0; // reset minutes from 1440 to 0
}
intsize();
CurrentTime = TimePrefix + CountdownTime;
//lcd.print(0, 1, CurrentTime);
}
// different modes
if(ModeCount > 0){
ModeCount++;
if(ModeCount == 2){ // timer mode
//lcd.print(0, 1, " Countdown Mode");
//lcd.print(10, 0, "MODE1"); // why ok to write to row 0 but not row 1?
/*
if (CountdownTime > 0){ // only activate timer if 1 or more minutes set
TimerStarted = 1;
HeatingOn();
NEWtransmitFixedCode();
}
else{
lcd.print(0, 1, " Press - / + ");
}
*/
}
else if(ModeCount == 3){ // thermostatic mode
//lcd.print(0, 1, " Thermostat ");
//lcd.print(10, 0, "MODE2");
}
else if(ModeCount == 4){ // other mode for calibrate / restart etc
//lcd.print(0, 1, " Other ");
//lcd.print(10, 0, "MODE3");
}
else{
ModeCount = 0; // reset back to manual mode
//lcd.print(0, 1, " Manual Mode ");
//lcd.print(10, 0, "MODE0");
}
}
}
}
BLYNK_WRITE(V6) // reads STEP on V6 pin, range 1 to 20 minutes
{
STEP = param.asInt(); // reads STEP on V6 pin
}
void HeatingOn(){ // details for heating on
CentralHeating = 1;
digitalWrite(GreenLED, HIGH); // turn LED ON
lcd.print(0, 0, "ON ");
}
void HeatingOff(){ // details for heating off
CentralHeating = 0;
digitalWrite(GreenLED, LOW); // turn LED OFF
lcd.print(0, 0, "OFF");
}
void NEWtransmitFixedCode() {
int deviceFixedAction[28] = {28,18,3,3,11,3,11,3,11,3,11,3,11,11,3,3,11,3,11,11,3,3,11,11,3,11,3,413}; // FixedAction array for OFF
if (CentralHeating==1) {
deviceFixedAction[24] = 11;
deviceFixedAction[23] = 3;
deviceFixedAction[22] = 3;
deviceFixedAction[21] = 11; // only these 4 array items need changing for OFF to become ON
}
rfsignal = deviceFixedAction[0];
int repeats = deviceFixedAction[1];
//The signal is transmitted several times in succession - this may vary with your remote, repeats holds this variable.
for(int j = 0; j<repeats; j++){
for(int i = 2; i<rfsignal; i=i+2){ // signal starts at position 2 in the array, 0 is overall size of the array, 1 is the number of repeats
digitalWrite(rfTransmitPin, HIGH); // Transmit a HIGH signal
delayMicroseconds(deviceFixedAction[i]*timeDelay);
digitalWrite(rfTransmitPin,LOW); // Transmit a LOW signal
delayMicroseconds(deviceFixedAction[i+1]*timeDelay);
}
}
}
void refreshLCD(){ // refresh LCD every x seconds but use last temperature reading not new one
lcd.print(11, 0, CurrentTemp); // display temperature on line 0 from character 11
if (ModeCount == 0){ // only refresh row 2 if mode is not being changed
CurrentTime = TimePrefix + CountdownTime;
CurrentTime = CurrentTime + " Minute(s)";
lcd.print(0, 1, CurrentTime);
//lcd.print(5, 1, "Minute(s)"); // this will crash the system, why?
}
if (TimerStarted == 0){ // don't change status if timer has been activated
if(CentralHeating == 1){
lcd.print(0, 0, "ON ");
}
else{
lcd.print(0, 0, "OFF");
}
}
else{
lcd.print(0, 0, "ON "); // timer running so show ON
}
}
void sendTemp() // display current temperature every 40 seconds plus status and minute(s) on LCD
{ // status and minutes are added in case the screen has cleared in error
sensors.requestTemperatures();
TempNow = (((sensors.getTempCByIndex(0)* Calibrate)*1)+50)/100; // 50 is for rounding
CurrentTemp = TempNow + TempSuffix;
lcd.print(11, 0, CurrentTemp); // display temperature on line 0 from character 11
}
void CheckTimer() // every 60 seconds check if timer is still running
{
if (TimerStarted == 1) {
if (CountdownTime >=1){
CountdownTime--;
intsize();
CurrentTime = TimePrefix + CountdownTime;
lcd.print(0, 1, CurrentTime);
}
if (CountdownTime == 0){
//Blynk.notify(String(" Central Heating Timer Just Ended"));
TimerStarted = 0;
intsize();
CurrentTime = TimePrefix + CountdownTime;
lcd.print(0, 1, CurrentTime);
lcd.print(0, 0, "OFF");
HeatingOff();
NEWtransmitFixedCode();
}
}
}
void loop()
{
Blynk.run();
timer.run(); // Initiates SimpleTimer
wdt_reset(); // if we get here turn off 8 second WDT
}