LED not changing the state, the hardware went offline

So, I made a led witch changes its value each 5 seconds. If it is not changing the state, the heardware went offline

Let me guess, you have a line in your void loop that says delay(5000);

If so, then use a Blynk timer instead.

if not, the share your code, and the details of the hardware that you’re using.

Pete.

#define MODE_EEPROM_INDEX 0
#define PUMP1_EEPROM_INDEX 1
#define PUMP2_EEPROM_INDEX 2
#define PERIOD_EEPROM_INDEX 3
#define RESET_DATA_EEPROM_INDEX 4

#include <UIPEthernet.h>
#include <BlynkSimpleUIPEthernet.h>

const char AUTH[] = "lolno"; // токен для ethernet

BlynkTimer temp_timer;
BlynkTimer online_signal_timer;
BlynkTimer protection_timer;
BlynkTimer set_all_timer;

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS A5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress floor1_temp_sensor = {0x28, 0xFF, 0xCE, 0xD0, 0x01, 0x17, 0x05, 0xDF};
DeviceAddress floor2_temp_sensor = {0x28, 0xFF, 0x09, 0xD0, 0x01, 0x17, 0x05, 0xAC};
DeviceAddress podacha_temp_sensor = {0x28, 0x41, 0x0F, 0x43, 0x98, 0x18, 0x00, 0xCC};
DeviceAddress obratka_temp_sensor = {0x28, 0x57, 0x20, 0x43, 0x98, 0x25, 0x00, 0x16};
DeviceAddress radiator_temp_sensor = {0x28, 0xFF, 0xEC, 0xCE, 0x01, 0x17, 0x05, 0x89};

#define pump1 7
#define pump2 8
#define protection_pin_1 10
#define protection_pin_2 11
#define heater 12

#define radiator_temp_VP V0
#define temp1_VP V1
#define temp2_VP V2
#define podacha_temp_VP V3
#define obratka_temp_VP V4
#define delta_VP V5
#define mode_VP V6
#define heater_led_VP V7
#define online_led_VP V8
#define pump1_VP V9
#define pump2_VP V10
#define period_VP V11

WidgetLED heater_led(heater_led_VP);
WidgetLED online_led(online_led_VP);

const byte AVERAGE_FACTOR = 5;  // if 0 - don't average values
/* TIME_MULTIPLIER corrects the time counting
   60000 - in minutes
   1000 - in seconds
   1 - in millis
*/
const unsigned long TIME_MULTIPLIER = 60000;

unsigned long end_time;  // in millis
float radiator_temp;
float floor1_temp;
float floor2_temp;
float podacha_temp;
float obratka_temp;
byte period = 10;  //  heating period in minutes
byte mode;
byte heater_system_delta;
bool heater_state;
bool pump1_state;
bool pump2_state;

BLYNK_WRITE(pump1_VP)
{
  bool x = param.asInt(); // assigning incoming value from pin V1 to a variable
  pump1_state = x;
  EEPROM.update(PUMP1_EEPROM_INDEX, x);
}

BLYNK_WRITE(pump2_VP)
{
  bool x = param.asInt(); // assigning incoming value from pin V1 to a variable
  pump2_state = x;
  EEPROM.update(PUMP2_EEPROM_INDEX, x);
}

BLYNK_WRITE(delta_VP)
{
  byte delta = param.asInt();
  heater_system_delta = delta;
}

BLYNK_WRITE(mode_VP)
{
  byte new_mode = param.asInt();
  // for the case when in the start of program new_mode == mode
  if (mode != new_mode) {
    mode = new_mode;
    end_time = 0;  // for re-count in function
    heater_state = false;  // for restart it right now
    EEPROM.update(MODE_EEPROM_INDEX, new_mode);
  }
}

BLYNK_WRITE(period_VP)
{
  byte new_period = param.asInt();
  period = new_period;
  EEPROM.update(PERIOD_EEPROM_INDEX, new_period);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("started");
  pinMode(protection_pin_1, OUTPUT);
  pinMode(protection_pin_2, OUTPUT);
  pinMode(heater, OUTPUT);
  pinMode(pump1, OUTPUT);
  pinMode(pump2, OUTPUT);

  sensors.begin();
  sensors.setResolution(radiator_temp_sensor, 11);
  sensors.setResolution(floor1_temp_sensor, 11);
  sensors.setResolution(floor2_temp_sensor, 11);
  sensors.setResolution(podacha_temp_sensor, 11);
  sensors.setResolution(obratka_temp_sensor, 11);
  sensors.setWaitForConversion(false); // make reading NON blocking
  sensors.requestTemperatures();       // start conversion for first reading

  setFromEEPROM();

  Blynk.begin(AUTH);
  if (EEPROM.read(RESET_DATA_EEPROM_INDEX)) {
    Blynk.notify("Тут сеть выпадала. Но я снова с вами!");
    EEPROM.update(RESET_DATA_EEPROM_INDEX, false);
  }
  else {
    Blynk.notify("Я включился! Видимо, не было электричества.");
  }
  Blynk.syncAll();
  set_all_timer.setInterval(1000L, setAll);
  temp_timer.setInterval(1500L, tempCheckerAndSender);
  protection_timer.setInterval(750L, protectionRoutine);
  online_signal_timer.setInterval(5000L, onlineSignalSender);
}

void loop() {
  Blynk.run();
  temp_timer.run();
  protection_timer.run();
  online_signal_timer.run();
  set_all_timer.run();
}

void setAll() {
  digitalWrite(pump1, pump1_state);
  digitalWrite(pump2, pump2_state);
  heaterController();  // for setting heater state using mode data
}

void tempCheckerAndSender() {
  floor1_temp = averageFilter(sensors.getTempC(floor1_temp_sensor), floor1_temp);
  floor2_temp = averageFilter(sensors.getTempC(floor2_temp_sensor), floor2_temp);
  podacha_temp = averageFilter(sensors.getTempC(podacha_temp_sensor), podacha_temp);
  obratka_temp = averageFilter(sensors.getTempC(obratka_temp_sensor), obratka_temp);
  radiator_temp = averageFilter(sensors.getTempC(radiator_temp_sensor), radiator_temp);
  sensors.requestTemperatures();
  Blynk.virtualWrite(temp1_VP, floor1_temp);
  Blynk.virtualWrite(temp2_VP, floor2_temp);
  Blynk.virtualWrite(podacha_temp_VP, podacha_temp);
  Blynk.virtualWrite(obratka_temp_VP, obratka_temp);
  Blynk.virtualWrite(radiator_temp_VP, radiator_temp);
}

void onlineSignalSender() {
  static bool parity;
  online_led.setValue(parity * 255);
  parity = !parity;
}

void(* resetFunc) (void) = 0;

void protectionRoutine() {
  byte pin;
  static bool parity;
  static bool need_to_notify_when_online;
  static bool reconnect;
  static unsigned long time_of_last_online;
  // after this time Arduino will stop to send signals for protection
  const unsigned long OFFLINE_IGNORE_PERIOD = 120000;  // offline ignore period in Blynk
  const unsigned long RESET_BY_PROTECTION_TIME = 300000;  // the real reset time is RESET_BY_PROTECTION_TIME + 5min
  const unsigned long SELF_RESET_TIME = 900000;  // after this time Arduino will reset itself
  
  // if the hardware went offline
  if (!Blynk.connected()) {
    if (!reconnect) {
      reconnect = true;
      time_of_last_online = millis();
    }
    else if (millis() - time_of_last_online > SELF_RESET_TIME) {
      // if there is no action for more than 10 minutes
      // soft reset routine
      EEPROM.update(RESET_DATA_EEPROM_INDEX, true);
      resetFunc();
    }
    else if (millis() - time_of_last_online > RESET_BY_PROTECTION_TIME) {
      // leave the function because we don't need to send signals for reboot arduino
      EEPROM.update(RESET_DATA_EEPROM_INDEX, true);
      return;
    }
    if (millis() - time_of_last_online > OFFLINE_IGNORE_PERIOD) {
      need_to_notify_when_online = true;
    }
  }
  else {
    // if connected, stop the protection
    reconnect = false;
    EEPROM.update(RESET_DATA_EEPROM_INDEX, false);
    if (need_to_notify_when_online) {
      need_to_notify_when_online = false;
      Blynk.notify("Тут сеть выпадала. Но я снова с вами!");
    }
    time_of_last_online = millis();
  }
  // if everything is OK, choose a pin to send the data
  if (parity) {
    pin = protection_pin_1;
  }
  else {
    pin = protection_pin_2;
  }
  // send short signal
  digitalWrite(pin, random(0, 2));  // send a random signal
  parity = !parity;
}

void heaterController() {
  static bool overheat;
  if (podacha_temp >= 90 and !overheat) {
    digitalWrite(heater, LOW);
    overheat = true;
    Blynk.notify("О-о, подача перегрелась. Но я отключил ТЭНы, не волнуйтесь. Когда температура будет меньше 82°, я все верну.");
    return;  //  leave the function
  }
  else if (overheat and podacha_temp >= 82) {
    return;
  }
  else if (overheat and podacha_temp < 82) {
    overheat = false;  //for continue working in normal mode
  }

  // the next code will be completed if the previous cases won't leave the function
  if (mode == 0) {
    heater_state = false;
  }
  else {
    unsigned long time_on = mode * TIME_MULTIPLIER;
    unsigned long time_off = (period * TIME_MULTIPLIER) - time_on;
    if (time_off == 0) {
      heater_state = true;
    }
    else {
      if (millis() > end_time) {
        heater_state = !heater_state;
        if (heater_state) {
          end_time = millis() + time_on;
        }
        else {
          end_time = millis() + time_off;
        }
      }
    }
  }

  static bool send_when_connect = false;  // it helps in case if the pump1_state changed automatically and button state in Blynk didn't changed
  if (heater_state and !pump1_state and !pump2_state) {
    pump1_state = true;
    EEPROM.update(PUMP1_EEPROM_INDEX, pump1_state);
    if (Blynk.connected()) {
      Blynk.virtualWrite(pump1_VP, pump1_state);
      Blynk.notify("Вы тут ошиблись и включили ТЭНы без насоса. Не волнуйтесь, я обо всем позаботился и включил насос первого этажа.");
    }
    else {
      send_when_connect = true;
    }
  }
  if (send_when_connect and Blynk.connected()) {
    send_when_connect = false;
    Blynk.virtualWrite(pump1_VP, pump1_state);
  }

  digitalWrite(heater, heater_state);
  heater_led.setValue(heater_state * 255);
}

float averageFilter (float new_val, float old_avg) {
  // the next code helps filter to collect statistics data correctly
  static byte times_of_calling;
  if (times_of_calling < AVERAGE_FACTOR) {
    times_of_calling++;
    return new_val;
  }
  if (AVERAGE_FACTOR > 0) {
    return (old_avg * (AVERAGE_FACTOR - 1) + new_val) / AVERAGE_FACTOR;
  }
  else {
    return new_val;
  }
}

void setFromEEPROM() {
  mode = EEPROM.read(MODE_EEPROM_INDEX);
  // next code will save from overheat
  if (mode > 5) {
    mode = 3;
  }
  pump1_state = EEPROM.read(PUMP1_EEPROM_INDEX);
  pump2_state = EEPROM.read(PUMP2_EEPROM_INDEX);
  period = EEPROM.read(PERIOD_EEPROM_INDEX);
  setAll();
}

Not the best way to set up timers on a memory constrained Arduino. A single timer can have 16 instances. Try this…

BlynkTimer timer; 
timer.setInterval(1000L, setAll);
timer.setInterval(1500L, tempCheckerAndSender); 
timer.setInterval(750L, protectionRoutine); 
timer.setInterval(5000L, onlineSignalSender);
void loop() { 
Blynk.run(); 
timer.run(); 
}

You may also want to stagger them a bit more.

For example, the 1 second timer and the 1.5 second timer will run at the same time every 3 seconds, as will the 1 second and the 5 second coincide every 5 seconds… and all three will try to run at the same time every every 15 seconds… I didn’t do the math on the 3/4 second one, but I am sure it is in the mix somewhere :stuck_out_tongue:

Now it turns offline in minute

#define MODE_EEPROM_INDEX 0
#define PUMP1_EEPROM_INDEX 1
#define PUMP2_EEPROM_INDEX 2
#define PERIOD_EEPROM_INDEX 3
#define RESET_DATA_EEPROM_INDEX 4

#include <UIPEthernet.h>
#include <BlynkSimpleUIPEthernet.h>

const char AUTH[] = "lolno"; // токен для ethernet

BlynkTimer timer;

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS A5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress floor1_temp_sensor = {0x28, 0xFF, 0xCE, 0xD0, 0x01, 0x17, 0x05, 0xDF};
DeviceAddress floor2_temp_sensor = {0x28, 0xFF, 0x09, 0xD0, 0x01, 0x17, 0x05, 0xAC};
DeviceAddress podacha_temp_sensor = {0x28, 0x41, 0x0F, 0x43, 0x98, 0x18, 0x00, 0xCC};
DeviceAddress obratka_temp_sensor = {0x28, 0x57, 0x20, 0x43, 0x98, 0x25, 0x00, 0x16};
DeviceAddress radiator_temp_sensor = {0x28, 0xFF, 0xEC, 0xCE, 0x01, 0x17, 0x05, 0x89};

#define pump1 7
#define pump2 8
#define protection_pin_1 10
#define protection_pin_2 11
#define heater 12

#define radiator_temp_VP V0
#define temp1_VP V1
#define temp2_VP V2
#define podacha_temp_VP V3
#define obratka_temp_VP V4
#define delta_VP V5
#define mode_VP V6
#define heater_led_VP V7
#define online_led_VP V8
#define pump1_VP V9
#define pump2_VP V10
#define period_VP V11

WidgetLED heater_led(heater_led_VP);
WidgetLED online_led(online_led_VP);

const byte AVERAGE_FACTOR = 5;  // if 0 - don't average values
/* TIME_MULTIPLIER corrects the time counting
   60000 - in minutes
   1000 - in seconds
   1 - in millis
*/
const unsigned long TIME_MULTIPLIER = 60000;

unsigned long end_time;  // in millis
float radiator_temp;
float floor1_temp;
float floor2_temp;
float podacha_temp;
float obratka_temp;
byte period = 10;  //  heating period in minutes
byte mode;
byte heater_system_delta;
bool heater_state;
bool pump1_state;
bool pump2_state;

BLYNK_WRITE(pump1_VP)
{
  bool x = param.asInt(); // assigning incoming value from pin V1 to a variable
  pump1_state = x;
  EEPROM.update(PUMP1_EEPROM_INDEX, x);
}

BLYNK_WRITE(pump2_VP)
{
  bool x = param.asInt(); // assigning incoming value from pin V1 to a variable
  pump2_state = x;
  EEPROM.update(PUMP2_EEPROM_INDEX, x);
}

BLYNK_WRITE(delta_VP)
{
  byte delta = param.asInt();
  heater_system_delta = delta;
}

BLYNK_WRITE(mode_VP)
{
  byte new_mode = param.asInt();
  // for the case when in the start of program new_mode == mode
  if (mode != new_mode) {
    mode = new_mode;
    end_time = 0;  // for re-count in function
    heater_state = false;  // for restart it right now
    EEPROM.update(MODE_EEPROM_INDEX, new_mode);
  }
}

BLYNK_WRITE(period_VP)
{
  byte new_period = param.asInt();
  period = new_period;
  EEPROM.update(PERIOD_EEPROM_INDEX, new_period);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("started");
  pinMode(protection_pin_1, OUTPUT);
  pinMode(protection_pin_2, OUTPUT);
  pinMode(heater, OUTPUT);
  pinMode(pump1, OUTPUT);
  pinMode(pump2, OUTPUT);

  sensors.begin();
  sensors.setResolution(radiator_temp_sensor, 11);
  sensors.setResolution(floor1_temp_sensor, 11);
  sensors.setResolution(floor2_temp_sensor, 11);
  sensors.setResolution(podacha_temp_sensor, 11);
  sensors.setResolution(obratka_temp_sensor, 11);
  sensors.setWaitForConversion(false); // make reading NON blocking
  sensors.requestTemperatures();       // start conversion for first reading

  setFromEEPROM();

  Blynk.begin(AUTH);
  if (EEPROM.read(RESET_DATA_EEPROM_INDEX)) {
    Blynk.notify("Тут сеть выпадала. Но я снова с вами!");
    EEPROM.update(RESET_DATA_EEPROM_INDEX, false);
  }
  else {
    Blynk.notify("Я включился! Видимо, не было электричества.");
  }
  Blynk.syncAll();
  timer.setInterval(946L, setAll);
  timer.setInterval(1531L, tempCheckerAndSender);
  timer.setInterval(729L, protectionRoutine);
  timer.setInterval(4834L, onlineSignalSender);
}

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

void setAll() {
  digitalWrite(pump1, pump1_state);
  digitalWrite(pump2, pump2_state);
  heaterController();  // for setting heater state using mode data
}

void tempCheckerAndSender() {
  floor1_temp = averageFilter(sensors.getTempC(floor1_temp_sensor), floor1_temp);
  floor2_temp = averageFilter(sensors.getTempC(floor2_temp_sensor), floor2_temp);
  podacha_temp = averageFilter(sensors.getTempC(podacha_temp_sensor), podacha_temp);
  obratka_temp = averageFilter(sensors.getTempC(obratka_temp_sensor), obratka_temp);
  radiator_temp = averageFilter(sensors.getTempC(radiator_temp_sensor), radiator_temp);
  sensors.requestTemperatures();
  Blynk.virtualWrite(temp1_VP, floor1_temp);
  Blynk.virtualWrite(temp2_VP, floor2_temp);
  Blynk.virtualWrite(podacha_temp_VP, podacha_temp);
  Blynk.virtualWrite(obratka_temp_VP, obratka_temp);
  Blynk.virtualWrite(radiator_temp_VP, radiator_temp);
}

void onlineSignalSender() {
  static bool parity;
  online_led.setValue(parity * 255);
  parity = !parity;
}

void(* resetFunc) (void) = 0;

void protectionRoutine() {
  byte pin;
  static bool parity;
  static bool need_to_notify_when_online;
  static bool reconnect;
  static unsigned long time_of_last_online;
  // after this time Arduino will stop to send signals for protection
  const unsigned long OFFLINE_IGNORE_PERIOD = 120000;  // offline ignore period in Blynk
  const unsigned long RESET_BY_PROTECTION_TIME = 300000;  // the real reset time is RESET_BY_PROTECTION_TIME + 5min
  const unsigned long SELF_RESET_TIME = 900000;  // after this time Arduino will reset itself
  
  // if the hardware went offline
  if (!Blynk.connected()) {
    if (!reconnect) {
      reconnect = true;
      time_of_last_online = millis();
    }
    else if (millis() - time_of_last_online > SELF_RESET_TIME) {
      // if there is no action for more than 10 minutes
      // soft reset routine
      EEPROM.update(RESET_DATA_EEPROM_INDEX, true);
      resetFunc();
    }
    else if (millis() - time_of_last_online > RESET_BY_PROTECTION_TIME) {
      // leave the function because we don't need to send signals for reboot arduino
      EEPROM.update(RESET_DATA_EEPROM_INDEX, true);
      return;
    }
    if (millis() - time_of_last_online > OFFLINE_IGNORE_PERIOD) {
      need_to_notify_when_online = true;
    }
  }
  else {
    // if connected, stop the protection
    reconnect = false;
    EEPROM.update(RESET_DATA_EEPROM_INDEX, false);
    if (need_to_notify_when_online) {
      need_to_notify_when_online = false;
      Blynk.notify("Тут сеть выпадала. Но я снова с вами!");
    }
    time_of_last_online = millis();
  }
  // if everything is OK, choose a pin to send the data
  if (parity) {
    pin = protection_pin_1;
  }
  else {
    pin = protection_pin_2;
  }
  // send short signal
  digitalWrite(pin, random(0, 2));  // send a random signal
  parity = !parity;
}

void heaterController() {
  static bool overheat;
  if (podacha_temp >= 90 and !overheat) {
    digitalWrite(heater, LOW);
    overheat = true;
    Blynk.notify("О-о, подача перегрелась. Но я отключил ТЭНы, не волнуйтесь. Когда температура будет меньше 82°, я все верну.");
    return;  //  leave the function
  }
  else if (overheat and podacha_temp >= 82) {
    return;
  }
  else if (overheat and podacha_temp < 82) {
    overheat = false;  //for continue working in normal mode
  }

  // the next code will be completed if the previous cases won't leave the function
  if (mode == 0) {
    heater_state = false;
  }
  else {
    unsigned long time_on = mode * TIME_MULTIPLIER;
    unsigned long time_off = (period * TIME_MULTIPLIER) - time_on;
    if (time_off == 0) {
      heater_state = true;
    }
    else {
      if (millis() > end_time) {
        heater_state = !heater_state;
        if (heater_state) {
          end_time = millis() + time_on;
        }
        else {
          end_time = millis() + time_off;
        }
      }
    }
  }

  static bool send_when_connect = false;  // it helps in case if the pump1_state changed automatically and button state in Blynk didn't changed
  if (heater_state and !pump1_state and !pump2_state) {
    pump1_state = true;
    EEPROM.update(PUMP1_EEPROM_INDEX, pump1_state);
    if (Blynk.connected()) {
      Blynk.virtualWrite(pump1_VP, pump1_state);
      Blynk.notify("Вы тут ошиблись и включили ТЭНы без насоса. Не волнуйтесь, я обо всем позаботился и включил насос первого этажа.");
    }
    else {
      send_when_connect = true;
    }
  }
  if (send_when_connect and Blynk.connected()) {
    send_when_connect = false;
    Blynk.virtualWrite(pump1_VP, pump1_state);
  }

  digitalWrite(heater, heater_state);
  heater_led.setValue(heater_state * 255);
}

float averageFilter (float new_val, float old_avg) {
  // the next code helps filter to collect statistics data correctly
  static byte times_of_calling;
  if (times_of_calling < AVERAGE_FACTOR) {
    times_of_calling++;
    return new_val;
  }
  if (AVERAGE_FACTOR > 0) {
    return (old_avg * (AVERAGE_FACTOR - 1) + new_val) / AVERAGE_FACTOR;
  }
  else {
    return new_val;
  }
}

void setFromEEPROM() {
  mode = EEPROM.read(MODE_EEPROM_INDEX);
  // next code will save from overheat
  if (mode > 5) {
    mode = 3;
  }
  pump1_state = EEPROM.read(PUMP1_EEPROM_INDEX);
  pump2_state = EEPROM.read(PUMP2_EEPROM_INDEX);
  period = EEPROM.read(PERIOD_EEPROM_INDEX);
  setAll();
}

Time to do some troubleshooting then…

Set up some debugging Serial print commands to track your programs timed and other function processes to the IDE Serial Monitor.

Look for patterns and see whatever was last to run before it stopped… and on that note, is the sketch stopping or just losing connection to the server?

It loses the connection. I tried to insert some prints, the sketch works fine. I guess that the problem hides in time of function routine.
I’ will explain.
When the string was like this:

else if (millis() - time_of_last_online > 120000)

It loses the connection once per day.
and when I changed the constant to this:

else if (millis() - time_of_last_online > 2100000)

It goes offline often: form each 5 minutes to one day.

My system has a reset routine, which saves my device.

it is probably a crash or exception in code that gets run as a result of the timer, i.e. not a problem with the timer itself. As @Gunner says, add a lot of Serial.println(); statements to see when it is dying.

To speed up the debugging process, reduce the time delay so it crashes sooner.