/*
К объему задания добавлен светодиод RGB, цвет свечения меняется в зависимости от величины
аналогового сигнала с датчика температуры. Выполнен плавный переход от Синего (минимальная темп.)
к Красному (максимальная температура). Диапазон значений получаемых с данного датчика лежит в 
пределах от 115 до 953.  
*/

#include <Servo.h>            //подключение библиотеки для работы с серводвигателем 
#include "SevSeg.h"           //подключение библиотеки для работы с семисегментным индикатором

#define btn 2                 //определяем константу для пина кнопки
#define sen A0                //определяем константу для пина чтения данных с термистора 
#define srv 3                 //определяем константу для пина управляющего сигнала серводвигателя (ШИМ)

#define rOut 11               //определяем константу для пина отвечающего за красный цвет светодиода RGB (ШИМ)
#define gOut 6                //определяем константу для пина отвечающего за зеленый цвет светодиода RGB (ШИМ)
#define bOut 5                //определяем константу для пина отвечающего за синий цвет светодиода RGB (ШИМ)

const float b_sen = 3950;     //B-коэффициент термистора

Servo srvOne;                 //определяем серводвигатель в качестве объекта
SevSeg indOne;                //определяем индикатор в качестве объекта
           
int avl = 0;                  //инициализация переменной для записи уровня сигнала с датчика температуры    
float celTemp = 0;            //инициализация переменной для записи результата пересчета уровня сигнала в градусы C
byte r = 0;                   //инициализация переменной для записи уровня ШИМ красного цвета
byte g = 0;                   //инициализация переменной для записи уровня ШИМ зеленого цвета
byte b = 0;                   //инициализация переменной для записи уровня ШИМ синего цвета

void setup() {
     
  pinMode(sen, INPUT);        //определяем режим работы пина sen как входа
  pinMode(btn, INPUT);        //определяем режим работы пина btn как входа
  pinMode(r, OUTPUT);         //определяем режим работы пина r как выхода
  pinMode(g, OUTPUT);         //определяем режим работы пина g как выхода
  pinMode(b, OUTPUT);         //определяем режим работы пина b как выхода  
  
  srvOne.attach(srv);         //передаем объекту srvOne пин для подключения серводвигателя
  
  byte numDigits = 2;                                               //
  byte digitPins[] = {4, 7};                                        //
  byte segmentPins[] = {0, 1, 13, 10, 12, 8, 9,};                   //инициализация переменных с параметрами            
  bool resistorsOnSegments = false;                                 //для работы с индикатором 
  byte hardwareConfig = COMMON_ANODE;                               //  
  bool updateWithDelays = false;                                    //
                                                                 
  indOne.begin(hardwareConfig, numDigits, digitPins, segmentPins,   //
  resistorsOnSegments, updateWithDelays);                           //передача параметров объекту индикатор 
  indOne.setBrightness(90);                                         //
   
}

void loop() {
  
  int avl = analogRead(sen);                                        //инициализация переменной для чтения данных термистора

  float celTemp = 1 / (log(1 / (1023. / avl - 1)) / b_sen + 1.0 / 298.15) - 273.15; //пересчет значения ацп в градусы цельсия

  int srVal = celTemp;                          //инициализация пременной для предачи сигнала серводвигателю с записью текущей температуры                                                 
  srVal = map(srVal, -24, 80, 0, 90);           //перевод дипазона температуры в градусы угла поворота серводвигателя
    
    if (digitalRead(btn) == HIGH) {             //проверка нажатия кнопки, при наличии высокого уровня сигнала: 
      srvOne.write(0);                          //- серводвигатель устанавливается в положение 0 градусов 
      srVal = 0;                                //- присваивается 0 пременной с текущим углом поворота серводвигателя 
    
      analogWrite(rOut, r = 255);               //
      analogWrite(gOut, g = 255);               //светодиод RGB светит белым
      analogWrite(bOut, b = 255);               //
    
    }
    else {                                      //в случае если условие ложно серводвигатель устанавливается 
      srvOne.write(srVal);                      //в положение в соответствие с заданным углом в зависимости от температуры     

      if (avl <= 315) {                         //задаем диапазон уровня сигнала с датчика для синего цвета
        byte cvl = map(avl, 115, 315, 255, 0);  //пересчет уровня сигнала ДТ в диапазон значений ШИМ  
        r = 255;                                //
        g = 255 - cvl;                          //запись уровня сигнала ШИМ в переменные
        b = 0;                                  //
                                                                           
      } else if (avl > 315 && avl <= 530) {     //задаем диапазон уровня сигнала с датчика для зеленого цвета
        byte cvl = map(avl, 315, 530, 255, 0);  //пересчет уровня сигнала ДТ в диапазон значений ШИМ  
        r = cvl;                                //
        g = 255;                                //запись уровня сигнала ШИМ в переменные
        b = 0;                                  //

      } else if (avl > 530 && avl <= 745) {     //задаем диапазон уровня сигнала с датчика для желтого цвета
        byte cvl = map(avl, 530, 745, 255, 0);  //пересчет уровня сигнала ДТ в диапазон значений ШИМ
        r = 0;                                  //
        g = 255;                                //запись уровня сигнала ШИМ в переменные
        b = 255 - cvl;                          //

      } else if (avl > 745 && avl <= 953) {     //задаем диапазон уровня сигнала с датчика для красного цвета
        byte cvl = map(avl, 745, 953, 255, 0);  //пересчет уровня сигнала ДТ в диапазон значений ШИМ  
        r = 0;                                  //
        g = cvl;                                //запись уровня сигнала ШИМ в переменные
        b = 255;                                //

      }
  
    analogWrite(rOut, r);                       //  
    analogWrite(gOut, g);                       //передача сигнала ШИМ на пины светодиода RGB
    analogWrite(bOut, b);                       //
  }                                            
  
  indOne.setNumber(srVal);                      //передача значения пременной srVal 
  indOne.refreshDisplay();                      //на семисегментный индикатор  
  
}