LED works bad

So, I use some LEDs in my app, but they don’t switch on and off correctly. Here is the code:


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

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

BlynkTimer temp_timer;
BlynkTimer signal_send_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};

#define protection_pin_1 10
#define protection_pin_2 11
#define heater 12

#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

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

const byte PERIOD = 11;  //  heating period in minutes
const byte AVERAGE_FACTOR = 5;  // if 0 - don't average values

float floor1_temp;
float floor2_temp;
float podacha_temp;
float obratka_temp;
byte mode;
byte heater_system_delta;
bool heater_state;

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

BLYNK_WRITE(mode_VP)
{
  byte new_mode = param.asInt();
  mode = new_mode;
}

void setup() {
  // put your setup code here, to run once:

  pinMode(protection_pin_1, OUTPUT);
  pinMode(protection_pin_2, OUTPUT);
  pinMode(heater, OUTPUT);
  
  sensors.begin();
  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 
  
  Blynk.begin(AUTH);
  Blynk.notify("Я включился! Видимо, не было электричества.");
  Blynk.syncAll();
  temp_timer.setInterval(1500L, tempRoutine);
  signal_send_timer.setInterval(1000L, signalSender);
}

void loop() {
  Blynk.run();
  temp_timer.run();
  signal_send_timer.run();
}

void tempRoutine() {
  tempCheckerAndSender();
  heaterController();
}

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);
  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);
}

void signalSender() {
  // choose a pin to send data
  byte pin;
  static bool parity = false;  // use this variable to check the parity
  if (parity) {
    pin = protection_pin_1;
  }
  else {
    pin = protection_pin_2;
  }
  online_led.setValue(parity * 255);
  parity = !parity;
  // send short signal
  digitalWrite(pin, HIGH);
  BlynkDelay(50);
  digitalWrite(pin, LOW);
}

void BlynkDelay(int milli) {
   int end_time = millis() + milli;
   while(millis() < end_time){
       Blynk.run();
       yield();
   }
}

void heaterController() {
  if (mode == 0) {
    heater_state = false;
  }
  else {
    static unsigned long end_time;  // in millis
    byte time_on = mode + 1;  // in minutes
    byte time_off = PERIOD - time_on;  // in minutes
    if (millis() > end_time) {
      heater_state = !heater_state;
      if (heater_state) {
        end_time = millis() + (time_on * 60000);
      }
      else {
        end_time = millis() + (time_off * 60000);
      }
    }
  }
  digitalWrite(heater, heater_state);
  heater_led.setValue(heater_state * 255);
}

float averageFilter (float new_val, float old_avg) {
  if (AVERAGE_FACTOR > 0) {
    return (old_avg * (AVERAGE_FACTOR - 1) + new_val) / AVERAGE_FACTOR;
  }
  else {
    return new_val;
  }
}

Maybe, I should add “Blynk.syncVirtual(…)” for this?

LEDs do everything they want: they are switching each moment they want