#include <EncButton.h>
#include <GyverMAX7219.h>
#include "RTClib.h"

RTC_DS1307 rtc;

EncButton<EB_TICK, 9> bmode(INPUT_PULLUP);
EncButton<EB_TICK, 8> bprev(INPUT_PULLUP);
EncButton<EB_TICK, 7> bnext(INPUT_PULLUP);
EncButton<EB_TICK, 6> bset(INPUT_PULLUP);
EncButton<EB_TICK, 12, 3, 2> enc;
MAX7219 < 4, 1, 10 > mtrx;

byte mode = 1;
byte H;
byte M;
byte Hcor;
byte Mcor;
#define MY_PERIOD 500  // период в мс
uint32_t tmr1;         // переменная таймера
uint32_t tmr2;
uint32_t tmr3;
uint32_t tmr4;
uint32_t tmr5;
uint32_t tmr6;
uint32_t tmr7;
bool set = false;
bool setTime = true;
byte set1;
byte set2;
int RPM = 0;
int RPML = 5000;
int V = 0;
bool RUN = false;
float input_volt = 0.0;
float temp=0.0;
float r1=25000.0; //сопротивление резистора r1
float r2=10000.0; // сопротивление резистора r2


void setup() {

  mtrx.begin();       // запускаем
  mtrx.setBright(5);  // яркость 0..15
  mtrx.textDisplayMode(GFX_REPLACE);

  Serial.begin(9600);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
  }
}

void loop() {

  //ОПРОС РТС, ЗАДАЧА ВРЕМЕНИ
  
  DateTime now = rtc.now();
  H = now.hour() + Hcor;
  H = constrain(H, 0, 23);
  M = now.minute() + Mcor;
  M = constrain(M, 0, 59);

  //ОПРОС ОРГАНОВ ВВОДА

  bmode.tick();
  bprev.tick();
  bnext.tick();
  bset.tick();
  enc.tick();

    //ТАЙМЕР НА ВЫВОД НА ЭКРАН

  if (millis() - tmr1 >= 500) {  // ищем разницу
    tmr1 = millis();                   // сброс таймера
    if (mode == 1) {
     mtrx.clear();
     mtrx.setCursor (3, 0);
     if (H < 10) {mtrx.println(String ("0")+ H);} else mtrx.println(H);
     mtrx.rect(15, 1, 16, 2);
     mtrx.rect(15, 4, 16, 5);
     mtrx.setCursor (18, 0);
     if (M < 10) {mtrx.println(String ("0") + M);} else mtrx.println(M);
     mtrx.update();
    }

    if (mode == 2 && set) {

      mtrx.setCursor (0, 0);
      mtrx.println(RPML + String(" "));
      mtrx.update(); }
    
    if (!set && bnext.click()) {
      mtrx.clear();
      mtrx.setCursor (8, 0);
      mtrx.println(">>>");
      mtrx.update();
       }

    if (!set && bprev.click()) {
      mtrx.clear();
      mtrx.setCursor (8, 0);
      mtrx.println("<<<");
      mtrx.update();
    }
    
    if (!set && enc.click()) {
      mtrx.clear();
      mtrx.setCursor (3, 0);
      mtrx.println("MUTE");
      mtrx.update();
       }

    if (!set && enc.isRight()) {
      V = V + 1;
      V = constrain(V, 0, 50);
      mtrx.clear();
      mtrx.setCursor (10, 0);
      mtrx.println("V ");
      mtrx.setCursor (18, 0);
      mtrx.println(V);
      mtrx.update();
    }

    if (!set && enc.isLeft()) {
      V = V - 1;
      V = constrain(V, 0, 50);
      mtrx.clear();
      mtrx.setCursor (10, 0);
      mtrx.println("V ");
      mtrx.setCursor (18, 0);
      mtrx.println(V);
      mtrx.update();
    }
  }


    //ТАЙМЕР НА ОЧИСТКУ ЭКРАНА

if (millis() - tmr2 >= 1000) {  // ищем разницу
    tmr2 = millis();                   // сброс таймера
     
    if (mode == 1 && set) {
      mtrx.rect(set1, 0, set2, 7, GFX_CLEAR);
      mtrx.update(); }

    if (mode == 2 && set) {
      mtrx.setCursor (0, 0);
      mtrx.println("    ");
      mtrx.update(); }
  
    }

  

    //ИМИТАЦИЯ И ВЫВОД ОБОРОТОВ ДВИГАТЕЛЯ

    if (mode == 2 && !set && !RUN && enc.isRight()) {RPM = 500; RUN = true;}

    if (mode == 2 && !set &&  millis() - tmr3 >= 100) {  // ищем разницу
    tmr3 = millis();                   // сброс таймера
     
     //ИМИТАЦИЯ
     if (RPM > 490) RPM = RPM + 100;
     if (RPM == RPML + 1000) RPM = 1000;

     //ВЫВОД
     mtrx.setCursor (0, 0);
     if (RPM == 0) {mtrx.println("READY"); mtrx.update();}
     if (RPM < 1000) {mtrx.println(String (" ") + RPM + String (" ")); mtrx.update();} else 
     {mtrx.println(RPM); mtrx.update();}
    
  }


  //ОЧИСТКА ПРИ ОТСЕЧКE

  if (mode == 2 &&!set && millis() - tmr4 >= 150) {  // ищем разницу
    tmr4 = millis();                   // сброс таймера

     if (RPM > RPML && mode == 2) {
      mtrx.rect(0, 0, 31, 7, GFX_CLEAR);
      mtrx.update(); }
  }

// ВЫВОД ВОЛЬТМЕТРА

if (mode == 3 && millis() - tmr5 >= 150) {  // ищем разницу
    tmr5 = millis();                   // сброс таймера
      
      mtrx.setCursor(0,0);
      mtrx.println(input_volt);
      mtrx.update();
  }


    //ПЕРЕКЛЮЧАТЕЛЬ РЕЖИМОВ
    if (bmode.press()) {

      mode++;
      mtrx.clear();
      set = false;
      if (mode > 3) mode = 1;
      Serial.println(mode);
      }
    
    //ВЫХОД В РЕЖИМ НАСТРОЙКИ

    if (bset.held() && !set) {

      set = true;
      Serial.println("Set");
      }

    if (bset.click() && set) {

      set = false;
      }  
    
    //ВЫБОР ВРЕМЕНИ

    if (mode == 1  && set  && bprev.click()) {setTime = true;}
    if (mode == 1  && set  && bnext.click()) {setTime = false;}

    if (setTime) {set1 = 3; set2 = 13;}
    if (!setTime) {set1 = 18; set2 = 28;}

    if (mode == 1 && set && setTime && enc.isRight()) {Hcor++;}
    if (mode == 1 && set && setTime && enc.isLeft()) {Hcor--;}

    if (mode == 1 && set  && !setTime && enc.isRight()) {Mcor++;}
    if (mode == 1 && set && !setTime && enc.isLeft()) {Mcor--;}

    //ВЫБОР ОТСЕЧКИ
    
    if (mode == 2 && set && enc.isRight()) {RPML = RPML + 500;}
    if (mode == 2 && set && enc.isLeft()) {RPML = RPML - 500;}
    RPML = constrain(RPML, 3000, 8000);
    
    //ВЫВОД ВОЛЬТАЖА

    int analogvalue = analogRead(A0);
    temp = (analogvalue * 5.0) / 1024.0; // формула для конвертирования значения напряжения
    input_volt = temp / (r2/(r1+r2));
    if (input_volt < 0.1)
    {
     input_volt=0.0;
    }


    
    if (enc.held()) Serial.println("MusOFF");
    
    


}
GND5VSDASCLSQWRTCDS1307+