Двухканальный термостат на Arduino, код из видео

код из видео


// термостат, один датчик DS18B20, два выхода
// подробнее http://youtu.be/y62Ps_D9B1M
//
//  v 0.1 beta

#include <EEPROM.h>
#include <OneWire.h>
#include <LiquidCrystal.h>

#define OUT1 2 // выходы для реле 
#define OUT2 3

byte tempOUT1, tempOUT2;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
OneWire  ds(11); // 11 вход датчика 18b20

byte gradus[8] = {
  0b00110,
  0b01001,
  0b01001,
  0b00110,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};


void erorr(){ // останавливает работу программы и сигнализирует ошибку
  digitalWrite(OUT1, LOW); // выключаем реле
  digitalWrite(OUT2, LOW);
    while(1){ // крутим бесконечный цикл
      digitalWrite(13, !digitalRead(13));
      delay(500);
    }  
}
////

byte key(){ //// для кнопок ЛСДшилда
  int val = analogRead(0);
    if (val < 50) return 5;
    else if (val < 150) return 3;
    else if (val < 350) return 4;
    else if (val < 500) return 2;
    else if (val < 800) return 1;
    else return 0;  
}
////

void setMenu(){ // установка температуры 
  byte pos;    
  digitalWrite(OUT1, LOW); // выключаем реле
  digitalWrite(OUT2, LOW);

  lcd.clear(); 
  lcd.setCursor(0, 0); // что нужно отрисовать один раз
  lcd.print("OUT1: ");
  lcd.setCursor(0, 1);
  lcd.print("OUT2: ");
  lcd.blink();
  
  while(1){ // крутим бесконечный цикл      
    byte KEY = key(); // читаем состояние кнопок
    
    lcd.setCursor(6, 0); // выводим на экран
    lcd.print(tempOUT1);
    lcd.write(1);
    lcd.print("C  ");
    lcd.setCursor(6, 1);
    lcd.print(tempOUT2);    
    lcd.write(1);
    lcd.print("C  ");
    
     ////// обработка кнопок 
    if (pos == 0){  // если в первой позиции
      lcd.setCursor(5, 0); // устанавливаем курсор
      if (KEY == 2) { // если нажата кнопка
        tempOUT1--;   // изменяем значение
        EEPROM.write(1, tempOUT1); // сохраняем в еепром
      }
      else if (KEY == 5){
        tempOUT1++;
        EEPROM.write(1, tempOUT1);     
      }    
    }
    if (pos == 1){ 
      lcd.setCursor(5, 1);
      if (KEY == 2) {
        tempOUT2--;
        EEPROM.write(2, tempOUT2);
      }
      else if (KEY == 5){
        tempOUT2++;
        EEPROM.write(2, tempOUT2);     
      }    
    }
    
    if (KEY == 3) pos--; // крутим позицию
    else if (KEY == 4) pos++;    
    if (pos > 1) pos = 0; 
 
   delay(200);
  }
}

float getTemp(){   // возвращает температуру с датчика
  byte data[12];   // и останавливает программу на секунду
  byte addr[8];  
  
  if (!ds.search(addr)) {
    lcd.clear();
    lcd.print("No sensor."); 
    erorr(); 
  }
  
  ds.reset_search(); 
 
  if (OneWire::crc8(addr, 7) != addr[7]) {
    lcd.clear();
    lcd.print("Sensor CRC erorr");
    erorr();   
  }
  
  ds.reset();            
  ds.select(addr);        
  ds.write(0x44);      
  delay(1000);   
  
  ds.reset();
  ds.select(addr);    
  ds.write(0xBE);          

  for (int i = 0; i < 9; i++) data[i] = ds.read(); 
  int raw = (data[1] << 8) | data[0]; // Переводим в температуру   
  if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6];  
  
  return raw / 16.0;
}

void setup() {
//  Serial.begin(9600); 
  lcd.createChar(1, gradus);
  lcd.begin(16, 2);
  lcd.clear();
  
  pinMode(13, OUTPUT); 
  pinMode(OUT1, OUTPUT);
  pinMode(OUT2, OUTPUT);
  
  tempOUT1 = EEPROM.read(1); // читаем настройки 
  tempOUT2 = EEPROM.read(2); // из еепром
}

void loop() {  
  if (key() == 1) setMenu(); // если нажата селект, уходим в меню
  else if (key() == 4) analogWrite(10, 20); // если вниз, глушим подсветку
  else if (key() == 3) digitalWrite(10, HIGH);
  
  float temperature = getTemp(); // читаем температуру
 
  if (temperature < tempOUT1) digitalWrite(OUT1, HIGH); // сверяем температуру 
  else digitalWrite(OUT1, LOW);                         // и управляем выходами
  if (temperature < tempOUT2) digitalWrite(OUT2, HIGH);
  else digitalWrite(OUT2, LOW);
      
  lcd.setCursor(0, 0); /// вывод инфы на экран
  lcd.print("1:");
  lcd.print(tempOUT1);
  lcd.write(1);
//  lcd.print("C");
    if (digitalRead(OUT1)) lcd.print(" ON "); // показываем состояние выхода
    else lcd.print(" OFF");
  lcd.setCursor(0, 1);
  lcd.print("2:");
  lcd.print(tempOUT2);
  lcd.write(1);
    if (digitalRead(OUT2)) lcd.print(" ON ");
    else lcd.print(" OFF");    
    
  lcd.setCursor(9, 0); // показываем температуру с датчика
  lcd.print("|"); 
  lcd.print(temperature, 1);
  lcd.write(1);
  lcd.print("C");
  lcd.setCursor(9, 1);     
  lcd.print("|");  
}