Сохранение/восстановление/сброс настроек через веб-интерфейс.
[esp-clock.git] / hardware.cpp
1 #include "Clock.h"
2 #include <Wire.h>
3 #include "time.h"
4 #include <Button2.h>
5 #include <Arduino.h>
6 #include <coredecls.h>
7
8 RTC_DS3231 RTC;
9 bool isRTCEnabled = false;
10
11 Button2 btn;
12 bool isButtonEnabled = false;
13
14 bool isBuzzerEnabled = false;
15 int buzzer_pin;
16 bool buzzer_passive;
17
18 bool beepState = false;
19 bool beepStateRequested = false;
20
21 int beepToneRequested;
22 int beepLengthRequested;
23
24 int beepMs = 400;
25 int silentMs = 200;
26 int beepTone = 1000;
27
28 void beep(int tone, int length, int beep, int silent) {
29   beepStateRequested = true;
30   beepToneRequested = tone;
31   beepLengthRequested = length;
32   if (!silent && beep>length) {
33     beepMs = length;
34   } else {
35     beepMs = beep;
36   }
37   silentMs = silent;
38 }
39
40 unsigned long first_click_millis = 0;
41
42 void buttonHandler(Button2& btn) {
43   if (!isButtonEnabled) return;
44   if (beepStateRequested) {
45     beepStateRequested = false;
46     return;
47   }
48   clickType click = btn.read();
49   Serial.println(btn.clickToString(click));
50   switch (click) {
51     case single_click:
52       screenModeRequested++;
53       if (screenModeRequested == mBarrier) { screenModeRequested = mDefault; }
54       if (screenModeRequested == mLast) { screenModeRequested = mDefault; }
55       break;
56     case double_click:
57       screenModeRequested--;
58       if (screenModeRequested <= mDefault) { screenModeRequested = mBarrier - 1; }
59       break;
60     case triple_click:
61       static int click_counter = 0;
62       if (millis() - first_click_millis > 6000) {
63         first_click_millis = millis();
64         click_counter = 1;
65         beep(400,800,200,100);
66         message(F("Длинное - точка доступа, тройное - сброс"));
67       } else {
68         message(F("Еще раз для сброса"));
69         beep(800,800,200,100);
70         click_counter++;
71         if (click_counter>2) {
72           reportMessage(F("Сбрасываю настройки"));
73           tone(1200,1000);
74           Serial.println(F("Три тройных нажатия - сбрасываю конфигурацию"));
75           reset();
76         }
77       }
78       break;
79   }
80 }
81
82 void buttonLongClickHandler(Button2& btn) {
83   if (!isButtonEnabled) return;
84   if (beepStateRequested) {
85     beepStateRequested = false;
86     return;
87   }
88   if (millis() - first_click_millis < 6000) {
89     if (isApEnabled) {
90       setupNet(false);
91     } else {
92       setupNet(true);
93     }
94     return;
95   }
96   bool enable_alarm = cfg.getBoolValue(F("enable_alarm"));
97   enable_alarm = !enable_alarm;
98   cfg.setValue(F("enable_alarm"), enable_alarm);
99   Serial.println(F("Alarm = ")); Serial.println(enable_alarm);
100   if (enable_alarm) {
101     message(F("Будильник включен"));
102     reportChange(F("enable_alarm"));
103     reportMessage(F("Будильник включен"));
104   } else {
105     message(F("Будильник выключен"));
106     reportChange(F("enable_alarm"));
107     reportMessage(F("Будильник выключен"));
108   }
109
110 }
111
112 void setupHardware() {
113   int pin_sda = cfg.getIntValue(F("pin_sda"));
114   int pin_scl = cfg.getIntValue(F("pin_scl"));
115   if (pin_sda && pin_scl && cfg.getBoolValue(F("enable_rtc"))) {
116     Serial.println(F("Нестандартные пины i2c"));
117     Wire.begin(pin_sda,pin_scl);
118   }
119   int i2c_speed = cfg.getIntValue(F("i2c_speed"));
120   if (i2c_speed) Wire.setClock(i2c_speed);
121   if (cfg.getBoolValue(F("enable_rtc"))) {
122     RTC.begin();
123     time_t rtc = RTC.now().unixtime();
124     timeval tv = { rtc, 0 };
125     settimeofday(&tv, nullptr);
126     isRTCEnabled = true;
127     Serial.println(F("Время установлено по встроенным часам"));
128   }
129   if (cfg.getBoolValue(F("enable_button"))) {
130     int button_pin = cfg.getIntValue(F("button_pin"));
131     btn.begin(button_pin, INPUT_PULLUP, !cfg.getBoolValue("button_inversed"));
132     btn.setLongClickTime(700);
133     btn.setDoubleClickTime(500);
134     btn.setClickHandler(&buttonHandler);
135     btn.setDoubleClickHandler(&buttonHandler);
136     btn.setTripleClickHandler(&buttonHandler);
137     btn.setLongClickDetectedHandler(&buttonLongClickHandler);
138     isButtonEnabled = true;
139   } else {
140     isButtonEnabled = false;
141   }
142   if (cfg.getBoolValue(F("enable_buzzer"))) {
143     isBuzzerEnabled = true;
144     buzzer_pin = cfg.getIntValue(F("buzzer_pin"));
145     pinMode(buzzer_pin,OUTPUT);
146     buzzer_passive = cfg.getBoolValue(F("buzzer_passive"));
147   } else {
148     isBuzzerEnabled = true;
149   }
150 }
151
152 void doBeep(int note, int duration) {
153   tone(buzzer_pin, note, duration);
154 }
155
156 void tickHardware() {
157   if (isButtonEnabled) {
158     btn.loop();
159   }
160   if (isBuzzerEnabled) {
161     static unsigned long stopBeepMillis = 0;
162     if (stopBeepMillis && millis() >= stopBeepMillis) {
163       beepStateRequested = false;
164       stopBeepMillis = 0;
165     }
166     if (beepStateRequested != beepState && beepStateRequested) {
167       stopBeepMillis = millis() + beepLengthRequested;
168     }
169     if (buzzer_passive) {
170       static unsigned long nextmillis;
171       if (beepStateRequested != beepState) {
172         beepState = beepStateRequested;
173         nextmillis = 0;
174       }
175       if (beepState) {
176         if (millis() > nextmillis) {
177           doBeep(beepToneRequested, beepMs);
178           nextmillis = millis() + beepMs + silentMs;
179         }
180       }
181     } else {
182       static unsigned long nextonmillis;
183       static unsigned long nextoffmillis;
184       if (beepStateRequested != beepState) {
185         beepState = beepStateRequested;
186         nextonmillis = 0;
187         nextoffmillis = 0;
188       }
189       if (beepState) {
190         static unsigned pinState = 0;
191         if (millis() > nextonmillis) {
192           digitalWrite(buzzer_pin, HIGH);
193           nextoffmillis = nextonmillis + beepMs;
194           nextonmillis = nextonmillis + beepMs + silentMs;
195         } else if (millis() > nextoffmillis) {
196           digitalWrite(buzzer_pin, LOW);
197           nextoffmillis = nextonmillis;
198         }
199       } else {
200         digitalWrite(buzzer_pin, LOW);
201       }
202     }
203   }
204 }