#include <Wire.h>
#include "DS1307.h"
#include <EncButton2.h>
#include <TimerMs.h>
#include "buildTime.h"
#include <EEPROM.h>
//GTimer myTimer(MS);
//GTimer myTimer2(MS);
//GTimer myTimer3(MS);
TimerMs tmr1(10000, 1, 1);
TimerMs tmr2(1000, 1, 1);
TimerMs tmr3(3000, 1, 1);
DS1307 clock;
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define INIT_ADDR 1023 // номер резервной ячейки
#define INIT_KEY 50 // ключ первого запуска. 0-254, на выбор
#define BTN1_PIN 3 // пин кнопки ВВЕРХ
#define BTN2_PIN 2 // пин кнопки ОК
#define BTN3_PIN 4 // пин кнопки ВНИЗ
#define tonePin 10 // пин пищалки
#define battery_min 3000 // минимальный уровень заряда батареи
#define battery_max 4200 // максимальный уровень заряда батареи
// диапазон для 3 пальчиковых/мизинчиковых батареек: 3000 - 4700
// диапазон для одной банки литиевого аккумулятора: 3000 - 4200
//GButton bup(BTN3_PIN);
//GButton bok(BTN1_PIN);
//GButton bd(BTN2_PIN);
EncButton2<EB_BTN> btn_up(INPUT, BTN3_PIN);
EncButton2<EB_BTN> btn_down(INPUT, BTN2_PIN);
EncButton2<EB_BTN> btn_ok(INPUT, BTN1_PIN);
//данные
//int Hour = 0, Min = 0, Sec = 0;
int voltage, alarm_hour = 24, alarm_min = 60;
int32_t Pressure_out = 0, Temperature_out = 0, precipitation = 0;
float Temperature = 23, Humidity = 70;
bool alarm_status = false, lcd_info = false, screen = true;
float my_vcc_const = 1.080;
//
byte home[8] =
{
B00000,
B00100,
B01110,
B11111,
B11111,
B11111,
B11111,
};
byte outsite[8] =
{
B00000,
B11111,
B10101,
B11111,
B10101,
B11111,
B00000,
};
byte vlag[8] =
{
B00000,
B00100,
B01110,
B11111,
B11111,
B01110,
B00000,
};
byte alarm[8] =
{
B00100,
B01110,
B01110,
B11111,
B11111,
B00100,
B00000,
B00000,
};
byte bat_100[8] = {
B01110,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111
};
byte bat_80[8] = {
B01110,
B11111,
B10001,
B11111,
B11111,
B11111,
B11111,
B11111
};
byte bat_60[8] = {
B01110,
B11111,
B10001,
B10001,
B11111,
B11111,
B11111,
B11111
};
byte bat_40[8] = {
B01110,
B11111,
B10001,
B10001,
B10001,
B11111,
B11111,
B11111
};
byte bat_20[8] = {
B01110,
B11111,
B10001,
B10001,
B10001,
B10001,
B11111,
B11111
};
void setup() {
//настройка дисплея
lcd.init(); // инициализация
lcd.backlight(); // включить подсветку
lcd.createChar(1, home);
lcd.createChar(2, outsite);
lcd.createChar(3, vlag);
lcd.createChar(4, alarm);
lcd.createChar(5, bat_100);
lcd.createChar(6, bat_80);
lcd.createChar(7, bat_60);
lcd.createChar(8, bat_40);
lcd.createChar(0, bat_20);
clock.begin();
clock.fillByYMD(BUILD_YEAR, BUILD_MONTH, BUILD_DAY);
clock.fillByHMS(BUILD_HOUR, BUILD_MIN, BUILD_SEC);
//clock.fillDayOfWeek(TUE);
clock.setTime();
tmr1.setTimerMode();
tmr2.setTimerMode();
tmr3.setTimerMode();
pinMode(tonePin, OUTPUT);
if (EEPROM.read(INIT_ADDR) != INIT_KEY) { // первый запуск
EEPROM.write(INIT_ADDR, INIT_KEY); // записали ключ
EEPROM.put(0, alarm_status);
EEPROM.put(1, alarm_hour);
EEPROM.put(2, alarm_min);
}
EEPROM.get(0, alarm_status);
EEPROM.get(1, alarm_hour);
EEPROM.get(2, alarm_min);
data_check();
}
void loop() {
if (tmr2.tick()) {
data_check();
} else {
if ((tmr1.tick()) && screen == true) {
lcd.noBacklight();
screen = false;
}
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if (((btn_up.click()) || (btn_down.click() || (btn_ok.click()))) && (screen == false)) {
lcd.backlight();
screen = true;
tmr1.start();
}
if (btn_ok.held()) {
if (screen == true) {
if (alarm_status == true) {
alarm_status = false;
EEPROM.put(0, alarm_status);
} else {
alarm_status = true;
EEPROM.put(0, alarm_status);
}
} else {
lcd.backlight();
screen = true;
tmr1.start();
}
}
if ((btn_up.held()) && (btn_down.held())) {
lcd.backlight();
screen = true;
lcd.clear();
set_time();
}
if ((btn_down.held()) && (screen == true)) {
lcd.clear();
set_alarm();
}
info_disp();
check_alarm();
}
}
void data_check() {
Pressure_out += 1;
Temperature_out += 1;
precipitation += 1;
tmr2.start();
}
void set_alarm() {
int hour, minute;
if ((alarm_hour > 23) && (alarm_min > 59)) {
clock.getTime();
hour = clock.hour;
minute = clock.minute;
} else {
hour = alarm_hour;
minute = alarm_min;
}
bool time = true;
lcd.setCursor(0, 0);
//lcd.print("Bydill");
//lcd.print("\xA1""y\xE3\xB8\xBB\xC4");
lcd.write(343);
lcd.setCursor(0, 1);
lcd.print("nik");
tmr1.start();
while (true) {
if (tmr1.tick()) {
lcd.noBacklight();
screen = false;
lcd.clear();
break;
}
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if (btn_ok.click()) {
if (time == true) {
time = false;
} else {
time = true;
}
tmr1.start();
}
if (btn_ok.held()) {
alarm_hour = hour;
alarm_min = minute;
EEPROM.put(1, alarm_hour);
EEPROM.put(2, alarm_min);
lcd.setCursor(0, 0);
lcd.print("OK ");
lcd.setCursor(0, 1);
lcd.print(" ");
tmr1.start();
delay(1000);
lcd.clear();
tmr1.start();
break;
}
lcd.setCursor(8, 0);
if (hour < 10) {
lcd.print("0");
}
lcd.print(hour);
lcd.print(":");
if (minute < 10) {
lcd.print("0");
}
lcd.print(minute);
lcd.setCursor(8, 1);
switch (time) {
case true:
lcd.print("-- ");
if (btn_down.click()) {
hour += 1;
if (hour > 23) {
hour = 0;
}
tmr1.start();
}
if (btn_up.click()) {
hour -= 1;
if (hour < 0) {
hour = 23;
}
tmr1.start();
}
break;
case false:
lcd.print(" --");
if (btn_down.click()) {
minute += 1;
if (minute > 59) {
minute = 0;
}
tmr1.start();
}
if (btn_up.click()) {
minute -= 1;
if (minute < 0) {
minute = 59;
}
tmr1.start();
}
break;
}
}
}
void set_time() {
clock.getTime();
int hour = clock.hour, minute = clock.minute;
bool time = true;
lcd.setCursor(0, 0);
lcd.print("Brema");
tmr1.start();
while (true) {
if (tmr1.tick()) {
lcd.noBacklight();
screen = false;
lcd.clear();
break;
}
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if (btn_ok.click()) {
if (time == true) {
time = false;
} else {
time = true;
}
tmr1.start();
}
if (btn_ok.held()) {
clock.fillByHMS(hour, minute, 30); // часы, минуты, секунды
clock.setTime();
lcd.setCursor(0, 0);
lcd.print("OK ");
delay(1000);
lcd.clear();
tmr1.start();
break;
}
lcd.setCursor(8, 0);
if (hour < 10) {
lcd.print("0");
}
lcd.print(hour);
lcd.print(":");
if (minute < 10) {
lcd.print("0");
}
lcd.print(minute);
lcd.setCursor(8, 1);
switch (time) {
case true:
lcd.print("-- ");
if (btn_down.click()) {
hour += 1;
if (hour > 23) {
hour = 0;
}
tmr1.start();
}
if (btn_up.click()) {
hour -= 1;
if (hour < 0) {
hour = 23;
}
tmr1.start();
}
break;
case false:
lcd.print(" --");
if (btn_down.click()) {
minute += 1;
if (minute > 59) {
minute = 0;
}
tmr1.start();
}
if (btn_up.click()) {
minute -= 1;
if (minute < 0) {
minute = 59;
}
tmr1.start();
}
break;
}
}
}
void info_disp() {
//показываем информацию в доме
lcd.setCursor(0, 0);
lcd.write(1);
int8_t temp_home = Temperature;
lcd.print(temp_home);
lcd.write(223);
lcd.setCursor(6, 0);
lcd.write(3);
int8_t hum_home = Humidity;
lcd.print(hum_home);
lcd.print("%");
//показываем информацию на улице
lcd.setCursor(0, 1);
lcd.write(2);
lcd.print(Temperature_out);
lcd.write(223);
lcd.setCursor(5, 1);
if (tmr3.tick()) {
if (lcd_info == true) {
lcd_info = false;
} else {
lcd_info = true;
}
check_bat();
tmr3.start();
}
if ((lcd_info == false) && (screen == true)) {
if (Pressure_out < 720) {
lcd.print(" Ocadki ");
} else if (Pressure_out < 740) {
lcd.print(" BeTer ");
} else if (Pressure_out < 760) {
lcd.print(" XMapno ");
} else if (Pressure_out < 770) {
lcd.print(" Colne4no ");
} else if (Pressure_out < 800) {
lcd.print(" 3acyxa ");
}
} else {
lcd.print("Osadki ");
lcd.print(precipitation);
lcd.print("%");
}
/*
if (lcd_info == false) {
//Осадки 700-720
if ((Pressure_out <= 720) && (Pressure_out < 740) && (Pressure_out < 760) && (Pressure_out < 770) && (Pressure_out < 800)) {
lcd.print(" Ocadki ");
}
//Ветер 720-740
if ((Pressure_out > 720) && (Pressure_out <= 740) && (Pressure_out < 760) && (Pressure_out < 770) && (Pressure_out < 800)) {
lcd.print(" BeTer ");
}
//Хмарно 740-760
if ((Pressure_out > 720) && (Pressure_out > 740) && (Pressure_out <= 760) && (Pressure_out < 770) && (Pressure_out < 800)) {
lcd.print(" XMapno ");
}
//Солнечно 760-770
if ((Pressure_out > 720) && (Pressure_out > 740) && (Pressure_out > 760) && (Pressure_out <= 770) && (Pressure_out < 800)) {
lcd.print(" Colne4no ");
}
//Засуха 770-800
if ((Pressure_out > 720) && (Pressure_out > 740) && (Pressure_out > 760) && (Pressure_out > 770) && (Pressure_out <= 800)) {
lcd.print(" 3acyxa ");
}
if ((Pressure_out > 720) && (Pressure_out > 740) && (Pressure_out > 760) && (Pressure_out > 770) && (Pressure_out > 800)) {
lcd.print(" 3acyxa ");
}
} else {
lcd.print("Osadki ");
lcd.print(precipitation);
lcd.print("%");
}
*/
// показываем время, дату состояние будильника
lcd.setCursor(10, 0);
if (alarm_status == true) {
lcd.write(4);
} else {
lcd.print(" ");
}
clock.getTime();
lcd.setCursor(11, 0);
if (clock.hour < 10) {
lcd.print("0");
}
lcd.print(clock.hour, DEC);
lcd.print(":");
if (clock.minute < 10) {
lcd.print("0");
}
lcd.print(clock.minute, DEC);
lcd.setCursor(15, 1);
//lcd.print(voltage);
if (voltage < 100) {
lcd.write(5);
} else if (voltage < 80) {
lcd.write(6);
} else if (voltage < 60) {
lcd.write(7);
} else if (voltage < 40) {
lcd.write(8);
} else if (voltage < 20) {
lcd.write(0);
}
// }
/*
lcd.setCursor(11, 1);
lcd.print(Day);
lcd.print(".");
lcd.print(Month);
// lcd.print(Year);
*/
}
void check_alarm() {
clock.getTime();
if ((alarm_status == true) && (alarm_hour == clock.hour) && (alarm_min == clock.minute)) {
lcd.backlight();
byte i = 61; // сколько будет пищать будильник 60 сек = 61
tmr2.start();
while (true) {
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held()) || (i < 1)) {
digitalWrite(tonePin, LOW);
break;
}
lcd.setCursor(10, 0);
if (tmr2.tick()) {
digitalWrite(tonePin, HIGH);
lcd.print(" ");
i -= 1;
tmr2.start();
} else {
digitalWrite(tonePin, LOW);
lcd.write(4);
}
}
digitalWrite(tonePin, LOW);
/*byte i = 10;
while(i--) {
tone(tonePin, 2093, 83.7209302326);
delay(93.023255814);
delay(46.511627907);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 62.7906976744);
delay(69.7674418605);
delay(46.511627907);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 83.7209302326);
delay(93.023255814);
delay(34.8837209302);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 62.7906976744);
delay(69.7674418605);
delay(546.511627907);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 83.7209302326);
delay(93.023255814);
delay(46.511627907);
lcd.setCursor(10, 0);
lcd.print(" ");
lcd.noBacklight();
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 73.2558139535);
delay(81.3953488372);
delay(34.8837209302);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 83.7209302326);
delay(93.023255814);
delay(34.8837209302);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 83.7209302326);
delay(93.023255814);
delay(534.88372093);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 83.7209302326);
delay(93.023255814);
lcd.setCursor(10, 0);
lcd.write(4);
lcd.backlight();
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
delay(23.2558139535);
tone(tonePin, 2093, 83.7209302326);
delay(93.023255814);
delay(46.511627907);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 73.2558139535);
delay(81.3953488372);
delay(34.8837209302);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 73.2558139535);
delay(81.3953488372);
delay(546.511627907);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 83.7209302326);
delay(93.023255814);
delay(34.8837209302);
lcd.setCursor(10, 0);
lcd.print(" ");
lcd.noBacklight();
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 73.2558139535);
delay(81.3953488372);
delay(46.511627907);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 73.2558139535);
delay(81.3953488372);
delay(46.511627907);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 73.2558139535);
delay(81.3953488372);
delay(534.88372093);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 83.7209302326);
delay(93.023255814);
delay(34.8837209302);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 73.2558139535);
delay(81.3953488372);
delay(46.511627907);
lcd.setCursor(10, 0);
lcd.write(4);
lcd.backlight();
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 73.2558139535);
delay(81.3953488372);
delay(46.511627907);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
tone(tonePin, 2093, 62.7906976744);
delay(69.7674418605);
delay(93.023255814);
btn_up.tick();
btn_down.tick();
btn_ok.tick();
if ((btn_up.held()) || (btn_down.held()) || (btn_ok.held())) {
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
tmr1.start();
break;
}
} */
noTone(tonePin);
alarm_status = false;
lcd.backlight();
screen = true;
delay(100);
tmr1.start();
}
}
void check_bat() {
voltage = readVcc(); // считать напряжение питания
voltage = map(voltage, battery_min, battery_max, 0, 100);
voltage = constrain(voltage, 0, 100);
}
long readVcc() { //функция чтения внутреннего опорного напряжения, универсальная (для всех ардуин)
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high << 8) | low;
result = my_vcc_const * 1023 * 1000 / result; // расчёт реального VCC
return result; // возвращает VCC
}