-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbazen.ino
416 lines (381 loc) · 14.5 KB
/
bazen.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
#include "Wire.h"
#include <OneWire.h>
OneWire oneWire(2); // pin čidel
// ----------- Display ------------
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,20,4);
// -------- Nastavení čidel -------------
#include <DallasTemperature.h>
DallasTemperature sensors(&oneWire);
DeviceAddress PANEL = { 0x28, 0xFF, 0x99, 0x70, 0x01, 0x17, 0x03, 0x6F }; // adresa čidla pro solární panel
DeviceAddress BAZEN = { 0x28, 0xFF, 0xF1, 0x88, 0x01, 0x17, 0x03, 0x2D }; // adresa čidla pro bazén
/* Zjištění adres pro čidla:
* https://codebender.cc/sketch:75043#DS18B20%20Address%20Finder.ino
*/
// ------- Nastavení vstupů a výstupů--------
int releFiltr = A2; // hlavní čerpadlo
int releChlor = A0; // čerpadlo chloru
int releVentil = A1; // ventil ohřevu
int buttonOn = 4; // zapnutí automatu
int buttonOff = 3; // vypnutí všeho
int buttonFiltr = 6; // zapnutí filtrace
int buttonChlor = 5; // Dávka chloru
// nastavení proměnných pro teplotu a funkce
float Tbazen, Tpanel;
boolean filtraceAuto, cisteni, chlor;
int vodaTemp = 25;
// nastavení časování
long previousMillis = 0;
long previousMillisTemp = 0;
long previousMillisTempP = 0;
long interval = 1000; // čas snímání teploty (ms)
long previousButton = 0;
long intervalButton = 50; // čas omezení prokliku tlačítka
// ------------ Nastavení hodin ------------
#define DS3231_I2C_ADDRESS 0x68
byte decToBcd(byte val){
return( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val){
return( (val/16*10) + (val%16) );
}
// ------------ Nastavení hodin konec------------
void setup(){
Wire.begin();
Serial.begin(9600);
// -------- nastavení pinů ------------
pinMode(releFiltr, OUTPUT);
pinMode(releChlor, OUTPUT);
pinMode(releVentil, OUTPUT);
pinMode(buttonOn, INPUT_PULLUP);
pinMode(buttonOff, INPUT_PULLUP);
pinMode(buttonFiltr, INPUT_PULLUP);
pinMode(buttonChlor, INPUT_PULLUP);
digitalWrite(releFiltr, HIGH);
digitalWrite(releChlor, HIGH);
digitalWrite(releVentil, HIGH);
lcd.init();
lcd.backlight();
lcd.setCursor(3,1);
lcd.print("BAZENBOT 2018");
lcd.setCursor(3,2);
lcd.print("(R) Dusan Vala");
delay(3000);
lcd.clear();
lcd.setCursor(0,1);
lcd.print("Vypnuto");
lcd.setCursor(0,0);
lcd.print(" ");
// ---------- POUZE PRO NASTAVENÍ ČASU! ---------------------
// sekundy, minuty, hodiny, den v týdnu (1- neděle), datum, měsíc, rok
//setDS3231time(00,00,9,1,8,4,18);
// ---------- POUZE PRO NASTAVENÍ ČASU! KONEC ---------------
//nastavení rozlišení snímání teplotních čidel (9 - 0,5°C 10 - 0,25°C..)
sensors.begin();
sensors.setResolution(9);
}
// ---------- POUZE PRO NASTAVENÍ ČASU! ---------------------
/*void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year){
// sets time and date data to DS3231
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}*/
void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year){
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
// ------- Hodiny ---------
void displayTime(){
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
lcd.setCursor(0,0);
if (hour<10){
lcd.print(" ");
}
lcd.print(hour, DEC);
lcd.print(":");
if (minute<10){
lcd.print("0");
}
lcd.print(minute, DEC);
lcd.print(":");
if (second<10){
lcd.print("0");
}
lcd.print(second, DEC);
lcd.print(" ");
lcd.print(dayOfMonth, DEC);
lcd.print("/");
lcd.print(month, DEC);
lcd.print(" 20");
lcd.print(year, DEC);
}
//-------------------- LOOP --------------
void loop(){
// ------------- ZAPNUTÍ AUTOMATIKY --------
if (digitalRead(buttonOn) == LOW) {
unsigned long currentMillis = millis();
if(currentMillis - previousButton > intervalButton) {
previousButton = currentMillis;
sensors.requestTemperatures();
off();
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Automaticky provoz");
filtraceAuto = true;
}
}
// ----------- POUZE FILTRACE / ČÍŠTĚNÍ ------------
if (digitalRead(buttonFiltr) == LOW) {
unsigned long currentMillis = millis();
if(currentMillis - previousButton > intervalButton) {
previousButton = currentMillis;
sensors.requestTemperatures();
off();
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Cisteni / Filtrace");
cisteni = true;
}
}
// -------- DÁVKOVÁNÍ CHLORU --------
if (digitalRead(buttonChlor) == LOW) {
unsigned long currentMillis = millis();
if(currentMillis - previousButton > intervalButton) {
previousButton = currentMillis;
sensors.requestTemperatures();
off();
digitalWrite(releChlor, HIGH);
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(14,2);
lcd.print(" ");
lcd.setCursor(14,3);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Davka chloru");
chlor = true;
}
}
// ------------- VYPNUTO -----------
if (digitalRead(buttonOff) == LOW) {
unsigned long currentMillis = millis();
if(currentMillis - previousButton > intervalButton) {
previousButton = currentMillis;
sensors.requestTemperatures();
off();
}
}
filtraceChlor(); // načtení funkce denního programu
filtrace(); // funkce pro filtraci nebo čištění
displayTime(); // zobrazení hodin
bazenTemp(); // zobrazení teploty bazénu
panelTemp(); // je zobrazena teplota soláního panelu
}
//-------------------- LOOP END ----------------
// ---------- VYPNUTÍ VŠECH FUNKCÍ --------------
void off(){
digitalWrite(releFiltr, HIGH);
digitalWrite(releChlor, HIGH);
digitalWrite(releVentil, HIGH);
cisteni = false;
filtraceAuto = false;
chlor = false;
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Vypnuto");
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print(" ");
}
/* zapnutí pouze filtrace nebo dávky chloru
* Následující funkce řeší samotné filtrování (čištění) bazénu
* a dávkování chloru. Pokud se zvolí filtrace, tak vypne automatický režim a
* spustí se pouze filtrační čerpadlo. Pokud se zvolí dávka chloru, tak se navíc
* na nastavený čas zapne i čerpadlo chloru. Funkci "chlorování" je nutné používat
* v rozmezí 0-5 sekund (v jakékoliv minutě). Pokud se zvolí později tak
* to nevadí, jen bude dávka o to menší. Chlor čerpadlo vypne vždy v nastavenou sekundu.
* Po cca 15 sekundách po vypnutí chlor čerpadla, přejde systém na automat.
*/
void filtrace(){
if(cisteni || (chlor)){// pokud je aktivována filtrace, nebo extra dávka chloru
digitalWrite(releFiltr, LOW); //zapni čerpadlo
digitalWrite(releVentil, HIGH); //a vypni ventil pokud by byl otevřený
if(chlor) { // pokud je aktuvována extra dávka chloru
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
if((second >= 5 & (second < 45))) { // nastavení 40s dávky chloru (nutno zapnout mezi 0-5 sec)
digitalWrite(releChlor, LOW);
} else {
if(second == 59) { // v 59 sekundě přejde systém zpět do automatického režimu
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Automaticky provoz");
digitalWrite(releFiltr, HIGH);
filtraceAuto = true;
chlor = false;
}
digitalWrite(releChlor, HIGH);
}
}
} else {
if(!filtraceAuto){
digitalWrite(releFiltr, HIGH);
}
}
}
/* ------------ AUTOMATICKÁ FILTRACE ----------
* Ráno a večer zapne filtraci a nadávkuje chlor
* Mimo časovou filtraci zapíná denní program ohřevu bazénu
*/
void filtraceChlor(){
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
if(filtraceAuto & (!cisteni & (!chlor))) {
// --------------- VEČER / RÁNO------------
if((hour >= 21 & (hour < 22) || (hour >= 5 & (hour< 6)))) { // filtrace pojede mezi 21-22hod večer a mezi 5-6hod ráno
digitalWrite(releFiltr, LOW); //zapni čerpadlo
digitalWrite(releVentil, HIGH);
if((minute == 1) & (second >=5) & (second <=45)) { // u každé filtrace bude přidán chlor po dobu 40s
digitalWrite(releChlor, LOW);
} else {
digitalWrite(releChlor, HIGH);
}
} else {
teplota(); // mimo daný čas zapne denní režim ohřevu bazénu
}
}
}
// ------------- DENNÍ PROGRAM OHŘEVU -------------
void teplota(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
sensors.requestTemperatures();
Tbazen = sensors.getTempC(BAZEN); //teplota bazenu
Tpanel = sensors.getTempC(PANEL); //teplota panelu
if(Tbazen == -127 || (Tpanel == -127)){ // pokud není čidlo připojeno hlásí teplotu -127
lcd.setCursor(14, 2);
lcd.print("Ohrev");
lcd.setCursor(14, 3);
lcd.print("OFF");
} else {
if(Tbazen <= 25) {//pokud je teplota bazénu menší
if((Tpanel - Tbazen) >= 10 ) { //a teplota panelu větší
digitalWrite(releFiltr, LOW); // zapni čerpadlo
digitalWrite(releVentil, LOW); // a uzavři ventil
lcd.setCursor(14, 2);
lcd.print(" ");
lcd.setCursor(14, 2);
lcd.print("Ohrev");
lcd.setCursor(14, 3);
lcd.print(" ");
lcd.setCursor(14, 3);
lcd.print("ON");
} else {
if((Tpanel - Tbazen) >= 3) { // pokud teplota panelu klesne na teplotu bazénu
digitalWrite(releFiltr, HIGH); // vypni čerpadlo
lcd.setCursor(14, 2);
lcd.print(" ");
lcd.setCursor(14, 2);
lcd.print("Ohrev");
lcd.setCursor(14, 3);
lcd.print(" ");
lcd.setCursor(14, 3);
lcd.print("OFF");
}
}
} else {
// pokud je bazén na požadované teplotě
bazenOk();
}
// Chlazení vody
/* if((Tbazen >= 27) && (Tpanel < (vodaTemp-3))) { //pokud je teplota bazénu větší, zapne chlazení
digitalWrite(releFiltr, LOW); // zapni čerpadlo
digitalWrite(releVentil, LOW); // a uzavři ventil
lcd.setCursor(12, 2);
lcd.print("Chlazeni");
lcd.setCursor(14, 3);
lcd.print("vody");
} else {
// pokud je bazén na požadované teplotě
bazenOk();
}*/
} // konec else špatných čidel
} // konec časování čtení čidel
}
void bazenOk(){
digitalWrite(releFiltr, HIGH); // vypni čerpadlo
digitalWrite(releVentil, HIGH); // otevři ventil
lcd.setCursor(14, 2);
lcd.print(" ");
lcd.setCursor(14, 2);
lcd.print("Voda");
lcd.setCursor(14, 3);
lcd.print(" ");
lcd.setCursor(14, 3);
lcd.print("OK");
}
// ---------- TEPLOTA BAZÉNU -----------
void bazenTemp(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillisTemp > interval) {
previousMillisTemp = currentMillis;
//načtení teploty z čidla
sensors.requestTemperatures();
Tbazen = sensors.getTempC(BAZEN);
if(Tbazen == -127){
lcd.setCursor(0, 2);
lcd.print("Error00");
} else {
lcd.setCursor(0, 2);
lcd.print("Voda:");
lcd.print(Tbazen);
lcd.print((char)223);
lcd.print("C");
}
}
}
// ---------- TEPLOTA SOLÁRNÍHO PANELU -----------
void panelTemp(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillisTempP > interval) {
previousMillisTempP = currentMillis;
//načtení teploty z čidla
sensors.requestTemperatures();
Tpanel = sensors.getTempC(PANEL);
if(Tpanel == -127){
lcd.setCursor(0, 3);
lcd.print("Error01");
} else {
lcd.setCursor(0, 3);
lcd.print("Solar:");
lcd.print(Tpanel);
lcd.print((char)223);
lcd.print("C");
}
}
}