//регулятор температуры, чтоб не страдать от жары
 //предполагается что значение показаний температуры всегда двухзначное
 //подключаем библиотеку Wire для работы с интерфесом I2C
 //устанавливаем адрес
 #include <Wire.h>
 #define TEMP_ADDR 72
 //подключаем и иницилизируем библиотеку LiquidCrystal
 #include <LiqudCristal.h>
 LquidCristal lcd(2,3,4,5,6,7);
 //специальный символ градуса
 byte degree[8]={
  B00110,
  B01001,
  B01001,
  B00110,
  B00000,
  B00000,
  B00000,
  B00000,
 };
 //спец символ состояния "Вкл" вентилятора
 byte fan_on[8]={
  B00100,
  B10101,
  B01110,
  B11111,
  B01110,
  B10101,
  B00100,
  B00000,
 };
 //спец символ состояния "выкл" вентилятора
 byte fan_off[8]={
  B00100,
  B00100,
  B00100,
  B11111,
  B00100,
  B00100,
  B00100,
  B00000,
 };
 //константы для контактов платы Ардуино
 const int SPEAKER=8;
 const int DOWN_BUTTON=9;
 const int UP_BUTTON=10;
 const int FAN=11;
 //переменные для состояния кнопок
 boolean lastDownTempButton=LOW;
 boolean currentDownTempButton=LOW;
 boolean lastUptempButton=LOW;
 boolean currentUpTempButton=LOW;
 int set_temp=23;//пороговое значение температуры по умолчанию
 boolean one_time=false;//переменная для одноразовой подачи звукового сигнвлв оповещения

 void setup()
 {
  pinMode(FAN,OUTPUT);
  //создаем экземпляр объекта Wire для датчика температуры
  Wire.begin();
  //задаем число столбцов и строк ЖК-дисплея
  lcd.begin(16,2);
  //создаем спец символы
  lcd.createChar(0,degree);
  lcd.createChar(1,fan_off);
  lcd.createChar(2,fan_on);
  //выводим статический текст на ЖК
  lcd.setCursor(0,0);
  lcd.print("Current:");
  lcd.setCursor(10,0);
  lcd.write((byte)0);
  lcd.setCursor(11,0);
  lcd.print("C");
  lcd.setCursor(0,1);
  lsd.print("Set:");
  lcd.setCursor(10,1);
  lcd.write((byte)0);
  lcd.setCursor(11,1);
  lcd.print("C");
  lcd.setCursor(15,1);
  lcd.write(1);
 }
//функция устранения дребезга контактов
//для использования двумя кнопками
boolean debounce(boolean last, int pin)
{
  boolean current=digitalRead(pin);
  if (last !=current)
  {
    delay(5);
    current=digitalRead(pin);
  }
  return current;
}

void loop()
{
  //считываем показания температуры
  Wire.beginTransmission(TEMP_ADDR);//начинаем взаимодействие
  Wire.write(0);//запрашиваем нулевой регистр
  Wire.endTransmission();//завершаем передачу
  //запраиваем 1 ьайт
  int returned_bytes=Wire.requestFrom(TEMP_ADDR,1);
  //если не возвращенно никаких данных значит что-то не так
  if (returned_bytes==0)
  {
    lcd.clear();//очищаем дисплей
    lcd.print("I2C Error");//выводим сообщение об ошибке
    while(1);//остановка исполнения программы 
  }
  int c=Wire.read();//сохраняем значениетемпературы в переменной c
  lcd.setCursor(8,0);//перемещаем курсор ЖКИ
  lcd.print(c);
  //устраняем дребезг обеих кнопок
  currentDownTempButton=debounce(lastDownTempButton,DOWN_BUTTON);
  currentUpTempButton=debounce(lastUpTempButton,UP_BUTTON);
  //понижаем пороговое значение температуры
  if (lastDownTempButton==LOW && currentDownTempButton==HIGH)
  {
    set_temp--;
  }
  //повышаем пороговое значение температуры
  else if (lastUpTempButton==LOW && currentUpTempButton==HIGH)
  {
    set_temp++;
  }
  //выводим пороговое значение температуры на ЖКД
  lcd.setCursor(8,1);
  lcd.print(set_temp);
  lastDownTempButton=currentDownTempButton;
  lastUpTempButton=currentUpTempButton;
  //температура вые порогового значения
  if (c>=set_temp)
  {
    //чтобы сигнал оповещения звучал только один раз
    if (!one_time)
    {
      tone(SPEAKER,400);
      delay(500);
      one_time=true;
    }
    //выключаем динамик после завершения подачи сигнала
    else
    {
      noTone(SPEAKER);
    }
    //включаем вентилятор и обновляем ЖКД
    digitalWrite(FAN,HIGH);
    lcd.setCursor(15,1);
    lcd.write(2);
  }
  //если температура ниже порогового значения
  else
  {
    //проверяем что динамик выключен, сбрасываем переменную состояния
    //одноразовой подачи звукового оповещения
    //обновляем индикатор состояния вентилятора и ЖКД
    noTone(SPEAKER);
    one_time=false;
    digitalWrite(FAN,LOW);
    lcd.setCursor(15,1);
    lcd.write(1);
  }
}

