c8dbaa2bbef2330a8a8ceb06034962c2873de9fe
[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           tone(1200,1000);
73           Serial.println(F("Три тройных нажатия - сбрасываю конфигурацию"));
74           reset();
75         }
76       }
77       break;
78   }
79 }
80
81 void buttonLongClickHandler(Button2& btn) {
82   if (!isButtonEnabled) return;
83   if (beepStateRequested) {
84     beepStateRequested = false;
85     return;
86   }
87   if (millis() - first_click_millis < 6000) {
88     if (isApEnabled) {    
89       setupNet(false);
90     } else {
91       setupNet(true);
92     }
93     return;
94   }
95   bool enable_alarm = cfg.getBoolValue(F("enable_alarm"));
96   enable_alarm = !enable_alarm;
97   cfg.setValue(F("enable_alarm"), enable_alarm);
98   Serial.println(F("Alarm = ")); Serial.println(enable_alarm);
99   if (enable_alarm) {
100     message(F("Будильник включен"));
101     reportChange(F("enable_alarm"));    
102   } else {
103     message(F("Будильник выключен"));
104     reportChange(F("enable_alarm"));
105   }
106
107 }
108
109 void setupHardware() {
110   int pin_sda = cfg.getIntValue(F("pin_sda"));
111   int pin_scl = cfg.getIntValue(F("pin_scl"));
112   if (pin_sda && pin_scl && cfg.getBoolValue(F("enable_rtc"))) {
113     Serial.println(F("Нестандартные пины i2c"));
114     Wire.begin(pin_sda,pin_scl);
115   }
116   int i2c_speed = cfg.getIntValue(F("i2c_speed"));
117   if (i2c_speed) Wire.setClock(i2c_speed);
118   if (cfg.getBoolValue(F("enable_rtc"))) {
119     RTC.begin();
120     time_t rtc = RTC.now().unixtime();
121     timeval tv = { rtc, 0 };
122     settimeofday(&tv, nullptr);  
123     isRTCEnabled = true;
124     Serial.println(F("Время установлено по встроенным часам"));
125   }
126   if (cfg.getBoolValue(F("enable_button"))) {
127     int button_pin = cfg.getIntValue(F("button_pin"));
128     btn.begin(button_pin, INPUT_PULLUP, !cfg.getBoolValue("button_inversed"));
129     btn.setLongClickTime(700);
130     btn.setDoubleClickTime(500);
131     btn.setClickHandler(&buttonHandler);
132     btn.setDoubleClickHandler(&buttonHandler);
133     btn.setTripleClickHandler(&buttonHandler);
134     btn.setLongClickDetectedHandler(&buttonLongClickHandler);
135     isButtonEnabled = true;
136   } else {
137     isButtonEnabled = false;
138   }
139   if (cfg.getBoolValue(F("enable_buzzer"))) {
140     isBuzzerEnabled = true;
141     buzzer_pin = cfg.getIntValue(F("buzzer_pin"));
142     pinMode(buzzer_pin,OUTPUT);
143     buzzer_passive = cfg.getBoolValue(F("buzzer_passive"));    
144   } else {
145     isBuzzerEnabled = true;
146   }
147 }
148
149 void doBeep(int note, int duration) {
150   tone(buzzer_pin, note, duration);
151 }
152
153 void tickHardware() {
154   if (isButtonEnabled) {
155     btn.loop();    
156   }
157   if (isBuzzerEnabled) {
158     static unsigned long stopBeepMillis = 0;
159     if (stopBeepMillis && millis() >= stopBeepMillis) {
160       beepStateRequested = false;
161       stopBeepMillis = 0;      
162     }
163     if (beepStateRequested != beepState && beepStateRequested) {
164       stopBeepMillis = millis() + beepLengthRequested;
165     }
166     if (buzzer_passive) {
167       static unsigned long nextmillis;
168       if (beepStateRequested != beepState) {
169         beepState = beepStateRequested;
170         nextmillis = 0;
171       }
172       if (beepState) {
173         if (millis() > nextmillis) {
174           doBeep(beepToneRequested, beepMs);
175           nextmillis = millis() + beepMs + silentMs;
176         }
177       }
178     } else {
179       static unsigned long nextonmillis;
180       static unsigned long nextoffmillis;
181       if (beepStateRequested != beepState) {
182         beepState = beepStateRequested;
183         nextonmillis = 0;
184         nextoffmillis = 0;
185       }
186       if (beepState) {
187         static unsigned pinState = 0;
188         if (millis() > nextonmillis) {
189           digitalWrite(buzzer_pin, HIGH);
190           nextoffmillis = nextonmillis + beepMs;
191           nextonmillis = nextonmillis + beepMs + silentMs;
192         } else if (millis() > nextoffmillis) {
193           digitalWrite(buzzer_pin, LOW);
194           nextoffmillis = nextonmillis;
195         }
196       } else {
197         digitalWrite(buzzer_pin, LOW);
198       }
199     }
200   }
201 }