String Version = "v.05.03";
/*
Что нужно добавить
1. Можно графику на олед, линии, картинки, возможно, анимацию при нагреве
2. Выключение Олед.
3. Снижение яркости олед
4. На схему нужно вернуть аналоговый датчик температуры
5. Ниже в скетче в раздел про обработку датчика даллас добавить отображение его результата на олед
6. Можно добавить аналитику по нескольким датчикам (одинаковым), для выдачи ошибки при перекосах в их показаниях
7. Гистерезис удерживаем кнопки. Тогда красные совсем убрать
*/
#include <GyverNTC.h>;
#include <LiquidCrystal_I2C.h>;
#include <EncButton.h>;
#include <microDS18B20.h>
#include <GyverOLED.h>
GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
#define RELE_PIN 2
#define LedRed_PIN 12
#define LedGreen_PIN 11
#define LedBlue_PIN 10
bool NeedSerial = true; // включаем для вывода информации в ком-порт
bool NeedDallas = true; // включаем, если задействуем второй датчик температуры, Даллас
bool BackLight = false; // для работы кнопки
int Pause = 0; // будем ставить паузу черной кнопкой
Button btnMinDown(5);
Button btnMinUp(6);
Button btnMaxDown(7);
Button btnMaxUp(8);
Button btnLight(9);
Button btnPause(3); //
GyverNTC therm1(A1, 10000, 3950); // аналоговый термометр
MicroDS18B20<13> sensor; // цифровой термометр - Даллас на ножке Д13
LiquidCrystal_I2C lcd(0x27, 16, 2);
float TempRoom = 0; // температура в комнате с аналогового датчика
float TempRoomD = 0; // температура в комнате с Цифрового датчика
float TempMin = 23.0; // темпретатура, НИЖЕ которой включается обогрев
float TempMax = 23.5; // темпретатура, ВЫШЕ которой вЫключается обогрев
void setup() {
oled.init(); // инициализация
oled.clear(); // очистка
/* пример работы с ОЛЕДом
oled.setScale(3); // масштаб текста (1..4)
oled.home(); // курсор в 0,0
oled.print("Привет!");
//delay(1000);
oled.setScale(1);
// курсор на начало 3 строки
oled.setCursor(0, 3);
oled.print("GyverOLED v1.3.2");
// курсор на (20, 50)
oled.setCursorXY(20, 50);
float pi = 3.14;
oled.print("PI = ");
oled.print(pi);
*/
if (NeedSerial) {
Serial.begin(9600);
}; // если нужен вывод в ком, то будем выводить
lcd.init(); // инициализация
lcd.noBacklight(); // выключить подсветку
pinMode(LedRed_PIN, OUTPUT); // индикация при нагреве
pinMode(LedGreen_PIN, OUTPUT); //индикация при ненагреве
pinMode(LedBlue_PIN, OUTPUT); //индикация
pinMode(RELE_PIN, OUTPUT); // даем команду реле на нагрев
// Начало. Приветствие на дисплее
lcd.backlight(); // включить подсветку
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("esaTemp ");
lcd.setCursor(16 - Version.length(), 1);
lcd.print(Version);
delay(500);
lcd.clear();
lcd.noBacklight(); // выключить подсветку
// Конец. Приветствие на дисплее
oled.setScale(3); // масштаб текста (1..4)
oled.home(); // курсор в 0,0
oled.print("esaTemp");
oled.setScale(2); // масштаб текста (1..4)
oled.setCursor(50 - Version.length(), 5);
oled.print(Version);
delay(3000);
oled.clear(); // очистка
}
void loop() {
TempRoom = therm1.getTempAverage(); // получаем данные от термометра 1
if (NeedSerial) {
Serial.println();
Serial.print("TempRoom: ");
Serial.print(TempRoom);
Serial.print(", TempMin: ");
Serial.print(TempMin);
Serial.print(", TempMax: ");
Serial.print(TempMax);
Serial.println();
Serial.print("Pause: ");
Serial.print(Pause);
}
// заполняем первую строку LCD 1602
lcd.setCursor(0, 0);
lcd.print("At");
lcd.write(223); // символ градуса
//lcd.print(" ");
lcd.print(TempRoom, 1);
oled.setScale(4); // масштаб текста (1..4)
oled.home(); // курсор в 0,0
// oled.print("At: ");
oled.print(TempRoom, 1);
// начало работы с Даллосом
// запрос температуры
sensor.requestTemp();
// вместо delay используй таймер на millis(), пример async_read
delay(1000);
// проверяем успешность чтения и выводим
if (sensor.readTemp())
{
TempRoomD = sensor.getTemp();
Serial.println(TempRoomD);
lcd.print(" Dt");
lcd.write(223); // символ градуса
//lcd.print(" ");
lcd.print(TempRoomD, 1);
}
else {
Serial.println("error");
TempRoomD = 0;
lcd.print(" Dt");
lcd.write(223); // символ градуса
//lcd.print(" ");
lcd.print("Err");
}
// конец работы с Даллосом
// заполняем вторую строку LCD 1602
lcd.setCursor(0, 1);
lcd.print(TempMin, 1); // чтобы был один знак после запятой
// lcd.write(223); // символ градуса
lcd.print(" ");
lcd.setCursor(5, 1);
lcd.write(127); //символ стрелка влево
lcd.write(45);
lcd.write(45);
lcd.write(45);
lcd.write(45);
lcd.write(126); // символ стрелка вправо
lcd.print(" ");
lcd.setCursor(12, 1);
lcd.print(TempMax, 1); // чтобы был один знак после запятой
lcd.print(" ");
oled.setScale(1); // масштаб текста (1..4)
oled.setCursor(0, 5);
oled.print(" MIN MAX"); // чтобы был один знак после запятой
oled.print(" ");
oled.setScale(2); // масштаб текста (1..4)
oled.setCursor(0, 6);
oled.print(TempMin, 1); // чтобы был один знак после запятой
oled.print(" ");
oled.print(TempMax, 1); // чтобы был один знак после запятой
oled.print(" ");
// Управление нагревателем
if (TempRoom > TempMax) {
digitalWrite(RELE_PIN, LOW);
digitalWrite(LedRed_PIN, LOW);
digitalWrite(LedBlue_PIN, HIGH);
lcd.setCursor(0, 0);
// lcd.print(" ");
lcd.setCursor(12, 0);
// lcd.print(" ");
}
if (TempRoom < TempMin) {
digitalWrite(RELE_PIN, HIGH);
digitalWrite(LedRed_PIN, HIGH);
digitalWrite(LedBlue_PIN, LOW);
lcd.setCursor(0, 0);
// lcd.print("****");
lcd.setCursor(12, 0);
// lcd.print("****");
}
// отработка нажатия кнопки Пауза
if (Pause > 0) {
digitalWrite(RELE_PIN, LOW);
digitalWrite(LedBlue_PIN, LOW);
digitalWrite(LedRed_PIN, LOW);
digitalWrite(LedGreen_PIN, HIGH);
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("PAUSE");
oled.clear();
oled.setScale(3); // масштаб текста (1..4)
oled.setCursor(20, 1);
oled.print("ПАУЗА");
while (Pause > 0) {
lcd.setCursor(4, 1);
lcd.print(SecondToTime(Pause));
lcd.print(" ");
oled.setScale(2); // масштаб текста (1..4)
oled.setCursor(20, 5);
oled.print(SecondToTime(Pause));
oled.print(" ");
delay(1000);
Pause = Pause - 1;
}
digitalWrite(LedBlue_PIN, HIGH);
digitalWrite(LedRed_PIN, LOW);
digitalWrite(LedGreen_PIN, LOW);
lcd.clear();
oled.clear();
}
}
void yield() {
// это всё мимо delay!
// кнопка 1 - включение/выключение подсветки LCD1602
btnLight.tick(); // опрос кнопки происходит здесь
if (btnLight.click()) {
if (BackLight) lcd.noBacklight();
else lcd.backlight();
BackLight = !BackLight;
}
//
btnMinDown.tick(); // опрос кнопки происходит здесь
if (btnMinDown.click()) {
TempMin = TempMin - 0.5;
if ((TempMin + 0.5) > TempMax) {
TempMax = TempMin + 0.5;
}
}
btnMinUp.tick(); // опрос кнопки происходит здесь
if (btnMinUp.click()) {
TempMin = TempMin + 0.5;
if ((TempMin + 0.5) > TempMax) {
TempMax = TempMin + 0.5;
}
}
btnMaxDown.tick(); // опрос кнопки происходит здесь
if (btnMaxDown.click()) {
TempMax = TempMax - 0.5;
if ((TempMax - 0.5) < TempMin) {
TempMin = TempMax - 0.5;
};
}
btnMaxUp.tick(); // опрос кнопки происходит здесь
if (btnMaxUp.click()) {
TempMax = TempMax + 0.5;
if ((TempMax - 0.5) < TempMin) {
TempMin = TempMax - 0.5;
};
}
btnPause.tick(); // опрос кнопки происходит здесь
if (btnPause.click()) {
/*if (Pause < 1) {
Pause = 10;
} else {
Pause = 0;
}; */
switch (Pause) {
case 0 ... 10: Pause = 15; break;
case 11 ... 150: Pause = 160; break;
case 151 ... 300: Pause = 310; break;
case 301 ... 600: Pause = 610; break;
case 601 ... 900: Pause = 910; break;
case 901 ... 1200: Pause = 1210; break;
case 1201 ... 1500: Pause = 1510; break;
default:
Pause = 0;
break;
}
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("PAUSE");
lcd.setCursor(4, 1);
lcd.print(SecondToTime(Pause));
lcd.print(" ");
oled.clear();
oled.setScale(3); // масштаб текста (1..4)
oled.setCursor(20, 1);
oled.print("ПАУЗА");
oled.setScale(2); // масштаб текста (1..4)
oled.setCursor(20, 5);
oled.print(SecondToTime(Pause));
oled.print(" ");
};
}
// Моя функция - переводим значение в секундах в часы-минуты-секунды
String SecondToTime(int Second) {
// расчитаем часы, минуты, секунды
int hours = Second / 60 / 60;
int minutes = Second / 60 - (hours * 60);
int seconds = (Second - (hours * 60) - minutes * 60);
String h = "";
String m = "";
String s = "";
h = hours;
m = minutes;
s = seconds;
if (h.length() == 1) {
h = "0" + h;
};
if (m.length() == 1) {
m = "0" + m;
};
if (s.length() == 1) {
s = "0" + s;
};
return (h + ":" + m + ":" + s);
}