#include <TimerOne.h>

volatile uint8_t ledStatus = 0;
volatile uint32_t timeOn = 0;
volatile uint32_t timeOff = 0;
volatile uint32_t blinkPeriod = 0;
volatile uint32_t blinksLeft = 0;
volatile uint32_t blinkNumber = 0;
volatile boolean blinkIsOn = false;

void stop_blink() {
  Timer1.stop();
  noInterrupts();
  ledStatus = 0;
  blinkIsOn = false;
  interrupts();
  digitalWrite(LED_BUILTIN, ledStatus);
}

void start_blink() {
  blinksLeft = blinkNumber;
  blinkIsOn = true;
  Timer1.setPeriod(timeOn);
  Timer1.resume();
}

void blink_led_ISR() {
  ledStatus ^= 0x01;
  digitalWrite(LED_BUILTIN, ledStatus);
  if (ledStatus) {
    Timer1.setPeriod(timeOn);
    if ((blinksLeft > 0)) blinksLeft--;
  } else {
    Timer1.stop();
    blinkIsOn = false;
    if (blinksLeft > 0) {
      Timer1.setPeriod(timeOff);
      blinkIsOn = true;
    }
    else if (blinkPeriod > 0) {
      Timer1.setPeriod(blinkPeriod);
      blinksLeft = blinkNumber;
      blinkIsOn = true;
    }
  }
}

void turn_off_led_ISR() {
  Timer1.stop();
  digitalWrite(LED_BUILTIN, LOW);
}

void set_blink(uint32_t tOn = 1000, uint32_t tOff = 1000, uint16_t numBlinks = 1, uint32_t repeatT = 0) {
  noInterrupts();
  Timer1.attachInterrupt(blink_led_ISR);
  timeOn = tOn * 1000UL;
  timeOff = tOff * 1000UL;
  blinkNumber = numBlinks;
  blinksLeft = blinkNumber;
  if (repeatT > 0) {
    blinkPeriod = repeatT * 1000UL - (timeOn * numBlinks + timeOff * (numBlinks - 1));
  }
  else {
    blinkPeriod = 0;
  }
  interrupts();
}

void turn_on_led() {
  digitalWrite(LED_BUILTIN, HIGH);
  noInterrupts();
  Timer1.stop();
  Timer1.attachInterrupt(turn_off_led_ISR);
  Timer1.setPeriod(500000);
  Timer1.restart();
  interrupts();
}

void setup() {
  Serial.begin(115200);
  Serial.println("Ok");
  pinMode(LED_BUILTIN, OUTPUT);
  Timer1.initialize(1000000);
  Timer1.stop();

//  Timer1.attachInterrupt(blink_led_ISR);
/*  stop_blink();
  delay(1000);
  set_blink(30, 170, 3);
  start_blink();
  while (blinkIsOn);
  delay(3000);
  set_blink(20UL, 80UL, 4, 1000UL);
  start_blink();
  delay(10000);
  stop_blink();
  set_blink(30UL, 170UL, 2, 3000UL);
  start_blink();
  delay(30000);
  stop_blink();
  digitalWrite(LED_BUILTIN, HIGH);
  delay(5000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(2000);
  start_blink();*/
}

void loop() {
  if (Serial.available()) {
    turn_on_led();
    char pp=Serial.read();
    Serial.print(pp);
  }
  delay(1);
}