소스 검색

support CCS811, serial relais.

Thomas Buck 2 년 전
부모
커밋
1684220574
8개의 변경된 파일785개의 추가작업 그리고 192개의 파일을 삭제
  1. 1
    1
      README.md
  2. 37
    18
      include/config.h
  3. 1
    2
      include/moisture.h
  4. 4
    4
      include/relais.h
  5. 63
    4
      platformio.ini
  6. 521
    99
      src/main.cpp
  7. 26
    27
      src/moisture.cpp
  8. 132
    37
      src/relais.cpp

+ 1
- 1
README.md 파일 보기

@@ -2,6 +2,6 @@
2 2
 
3 3
 Small firmware supporting different environmental sensors, as well as different microcontroller platforms.
4 4
 
5
-Supports SHT21, BME280, analog moisture sensors.
5
+Supports SHT21, BME280, CCS811, analog moisture sensors, serial or gpio relais.
6 6
 
7 7
 Runs on ESP32, ESP8266, Arduino Uno Wifi Developer Edition.

+ 37
- 18
include/config.h 파일 보기

@@ -15,33 +15,30 @@
15 15
 #define __ESP_ENV_CONFIG__
16 16
 
17 17
 // Sketch version
18
-const char* esp_env_version = "0.4.0";
18
+#define ESP_ENV_VERSION "0.5.0"
19 19
 
20 20
 // location of sensor, used in DB and hostname
21
-//const char* sensor_location = "livingroom";
22
-//const char* sensor_location = "bedroom";
23
-//const char* sensor_location = "bathroom";
24
-//const char* sensor_location = "kitchen";
25
-//const char* sensor_location = "hallway";
26
-//const char* sensor_location = "tent";
27
-//const char* sensor_location = "storage";
28
-//const char* sensor_location = "greenhouse";
29
-const char* sensor_location = "testing";
30
-
31
-#define SENSOR_HOSTNAME_PREFIX "ESP-"
21
+//#define SENSOR_LOCATION_LIVINGROOM
22
+//#define SENSOR_LOCATION_BEDROOM
23
+//#define SENSOR_LOCATION_BATHROOM
24
+//#define SENSOR_LOCATION_GREENHOUSE
25
+#define SENSOR_LOCATION_TESTING
32 26
 
33 27
 // WiFi AP settings
34
-const char* ssid = "WIFI_SSID_HERE";
35
-const char* password = "WIFI_PASSWORD_HERE";
28
+#define WIFI_SSID "WIFI_SSID_HERE"
29
+#define WIFI_PASS "WIFI_PASSWORD_HERE"
30
+
31
+// MQTT settings
32
+#define MQTT_HOST "MQTT_IP_HERE"
33
+#define MQTT_PORT 1883
34
+#define MQTT_USER "USERNAME" // undef to disable auth
35
+#define MQTT_PASS "PASSWORD" // undef to disable auth
36 36
 
37 37
 // InfluxDB settings
38 38
 #define INFLUXDB_HOST "INFLUX_IP_HERE"
39 39
 #define INFLUXDB_PORT 8086
40 40
 #define INFLUXDB_DATABASE "roomsensorsdiy"
41 41
 
42
-// feature selection
43
-#define ENABLE_INFLUXDB_LOGGING
44
-
45 42
 // all given in milliseconds
46 43
 #define SERVER_HANDLE_INTERVAL 10
47 44
 #define DB_WRITE_INTERVAL (30 * 1000)
@@ -49,6 +46,28 @@ const char* password = "WIFI_PASSWORD_HERE";
49 46
 #define LED_INIT_BLINK_INTERVAL 500
50 47
 #define LED_CONNECT_BLINK_INTERVAL 250
51 48
 #define LED_ERROR_BLINK_INTERVAL 100
49
+#define MQTT_RECONNECT_INTERVAL (5 * 1000)
52 50
 
53
-#endif // __ESP_ENV_CONFIG__
51
+#if defined(SENSOR_LOCATION_LIVINGROOM)
52
+#define SENSOR_LOCATION "livingroom"
53
+#elif defined(SENSOR_LOCATION_BEDROOM)
54
+#define SENSOR_LOCATION "bedroom"
55
+#elif defined(SENSOR_LOCATION_BATHROOM)
56
+#define SENSOR_LOCATION "bathroom"
57
+#elif defined(SENSOR_LOCATION_GREENHOUSE)
58
+#define SENSOR_LOCATION "greenhouse"
59
+#elif defined(SENSOR_LOCATION_TESTING)
60
+#define SENSOR_LOCATION "testing"
61
+#else
62
+#define SENSOR_LOCATION "unknown"
63
+#endif
54 64
 
65
+#if defined(RELAIS_SERIAL) || defined(RELAIS_GPIO)
66
+#define FEATURE_RELAIS
67
+#endif
68
+
69
+#if defined(MOISTURE_ADC_ESP32) || defined(MOISTURE_ADC_ARDUINO)
70
+#define FEATURE_MOISTURE
71
+#endif
72
+
73
+#endif // __ESP_ENV_CONFIG__

+ 1
- 2
include/moisture.h 파일 보기

@@ -14,10 +14,9 @@
14 14
 #ifndef __ESP_ADC_MOISTURE_SENSOR__
15 15
 #define __ESP_ADC_MOISTURE_SENSOR__
16 16
 
17
+void moisture_init(void);
17 18
 int moisture_count(void);
18 19
 int moisture_read(int sensor);
19 20
 int moisture_max(void);
20
-void moisture_init(void);
21 21
 
22 22
 #endif // __ESP_ADC_MOISTURE_SENSOR__
23
-

+ 4
- 4
include/relais.h 파일 보기

@@ -14,10 +14,10 @@
14 14
 #ifndef __ESP_RELAIS_ACTOR__
15 15
 #define __ESP_RELAIS_ACTOR__
16 16
 
17
-int relais_count(void);
18
-int relais_enable(int relais, unsigned long time);
19 17
 void relais_init(void);
20
-void relais_run(void);
18
+int relais_count(void);
19
+void relais_set(int relais, int state);
20
+int relais_get(int relais);
21
+String relais_name(int relais);
21 22
 
22 23
 #endif // __ESP_RELAIS_ACTOR__
23
-

+ 63
- 4
platformio.ini 파일 보기

@@ -8,34 +8,93 @@
8 8
 ; Please visit documentation for the other options and examples
9 9
 ; https://docs.platformio.org/page/projectconf.html
10 10
 
11
-[env:esp01_1m]
11
+[env:esp8266env]
12 12
 platform = espressif8266
13 13
 board = esp01_1m
14 14
 framework = arduino
15
+build_flags =
16
+  -DSENSOR_HOSTNAME_PREFIX=\"env-\"
17
+  -DENABLE_CCS811
18
+  -DENABLE_INFLUXDB_LOGGING
19
+  -DENABLE_MQTT
15 20
 lib_deps =
16 21
     Wire
17 22
     ESP8266 Influxdb
18 23
     Adafruit Unified Sensor
19 24
     Adafruit BME280 Library
25
+    https://github.com/adafruit/Adafruit_CCS811
26
+    https://github.com/knolleary/pubsubclient.git#2d228f2f862a95846c65a8518c79f48dfc8f188c
20 27
 
21
-[env:esp32dev]
22
-platform = espressif32
28
+[env:esp8266relais]
29
+platform = espressif8266
30
+board = esp01_1m
31
+framework = arduino
32
+build_flags =
33
+  -DSENSOR_HOSTNAME_PREFIX=\"relais-\"
34
+  -DRELAIS_SERIAL
35
+  -DENABLE_INFLUXDB_LOGGING
36
+  -DENABLE_MQTT
37
+lib_deps =
38
+    Wire
39
+    ESP8266 Influxdb
40
+    Adafruit Unified Sensor
41
+    Adafruit BME280 Library
42
+    https://github.com/knolleary/pubsubclient.git#2d228f2f862a95846c65a8518c79f48dfc8f188c
43
+
44
+[env:esp32env]
45
+platform = platformio/espressif32@3.5.0
46
+board = esp32dev
47
+framework = arduino
48
+upload_protocol = esptool
49
+upload_port = /dev/ttyUSB1
50
+monitor_port = /dev/ttyUSB1
51
+monitor_speed = 115200
52
+build_flags =
53
+  -DSENSOR_HOSTNAME_PREFIX=\"env-\"
54
+  -DENABLE_CCS811
55
+  -DENABLE_INFLUXDB_LOGGING
56
+  -DENABLE_MQTT
57
+lib_deps =
58
+    Wire
59
+    Adafruit Unified Sensor
60
+    Adafruit BME280 Library
61
+    https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino.git#66ed5d031caab6953cc79b407a4b49d33b1126dc
62
+    https://github.com/adafruit/Adafruit_CCS811
63
+    https://github.com/knolleary/pubsubclient.git#2d228f2f862a95846c65a8518c79f48dfc8f188c
64
+
65
+[env:esp32moisture]
66
+platform = platformio/espressif32@3.5.0
23 67
 board = esp32dev
24 68
 framework = arduino
25 69
 upload_protocol = esptool
70
+upload_port = /dev/ttyUSB1
71
+monitor_port = /dev/ttyUSB1
72
+monitor_speed = 115200
73
+build_flags =
74
+  -DSENSOR_HOSTNAME_PREFIX=\"env-\"
75
+  -DMOISTURE_ADC_ESP32
76
+  -DENABLE_CCS811
77
+  -DENABLE_INFLUXDB_LOGGING
78
+  -DENABLE_MQTT
26 79
 lib_deps =
27 80
     Wire
28 81
     Adafruit Unified Sensor
29 82
     Adafruit BME280 Library
30 83
     https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino.git#66ed5d031caab6953cc79b407a4b49d33b1126dc
84
+    https://github.com/adafruit/Adafruit_CCS811
85
+    https://github.com/knolleary/pubsubclient.git#2d228f2f862a95846c65a8518c79f48dfc8f188c
31 86
 
32
-[env:arduinowifideved]
87
+[env:arduinomoisture]
33 88
 platform = atmelavr
34 89
 board = uno
35 90
 framework = arduino
36 91
 upload_port = /dev/ttyACM0
37 92
 monitor_port = /dev/ttyACM0
38 93
 monitor_speed = 115200
94
+build_flags =
95
+  -DSENSOR_HOSTNAME_PREFIX=\"env-\"
96
+  -DMOISTURE_ADC_ARDUINO
97
+  -DENABLE_INFLUXDB_LOGGING
39 98
 lib_deps =
40 99
     Wire
41 100
     Adafruit Unified Sensor

+ 521
- 99
src/main.cpp 파일 보기

@@ -15,6 +15,10 @@
15 15
 #include <Adafruit_BME280.h>
16 16
 #include <SHT2x.h>
17 17
 
18
+#ifdef ENABLE_CCS811
19
+#include <Adafruit_CCS811.h>
20
+#endif // ENABLE_CCS811
21
+
18 22
 #if defined(ARDUINO_ARCH_ESP8266)
19 23
 
20 24
 #include <ESP8266WiFi.h>
@@ -35,6 +39,7 @@
35 39
 
36 40
 #include "config.h"
37 41
 #include "moisture.h"
42
+#include "relais.h"
38 43
 
39 44
 #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
40 45
 
@@ -46,6 +51,13 @@
46 51
 UPDATE_WEB_SERVER server(80);
47 52
 SimpleUpdater updater;
48 53
 
54
+#ifdef ENABLE_MQTT
55
+#include <PubSubClient.h>
56
+WiFiClient mqttClient;
57
+PubSubClient mqtt(mqttClient);
58
+unsigned long last_mqtt_reconnect_time = 0;
59
+#endif // ENABLE_MQTT
60
+
49 61
 #elif defined(ARDUINO_ARCH_AVR)
50 62
 
51 63
 #define ESP_PLATFORM_NAME "Uno WiFi"
@@ -69,6 +81,8 @@ int error_count = 0;
69 81
 #define SHT_I2C_ADDRESS HTDU21D_ADDRESS
70 82
 #define BME_I2C_ADDRESS_1 0x76
71 83
 #define BME_I2C_ADDRESS_2 0x77
84
+#define CCS811_ADDRESS_1 0x5A
85
+#define CCS811_ADDRESS_2 0x5B
72 86
 
73 87
 #if defined(ARDUINO_ARCH_ESP8266)
74 88
 
@@ -92,43 +106,27 @@ SHT2x sht(SHT_I2C_ADDRESS, &Wire);
92 106
 
93 107
 #endif
94 108
 
95
-//#define ENABLE_RELAIS_TEST
96
-
97 109
 Adafruit_BME280 bme1, bme2;
98 110
 
99 111
 bool found_bme1 = false;
100 112
 bool found_bme2 = false;
101 113
 bool found_sht = false;
102 114
 
115
+#ifdef ENABLE_CCS811
116
+Adafruit_CCS811 ccs1, ccs2;
117
+bool found_ccs1 = false;
118
+bool found_ccs2 = false;
119
+bool ccs1_data_valid = false;
120
+bool ccs2_data_valid = false;
121
+int ccs1_error_code = 0;
122
+int ccs2_error_code = 0;
123
+#endif // ENABLE_CCS811
124
+
103 125
 unsigned long last_server_handle_time = 0;
104 126
 unsigned long last_db_write_time = 0;
105 127
 unsigned long last_led_blink_time = 0;
106 128
 
107
-#ifdef ENABLE_RELAIS_TEST
108
-
109
-#include "relais.h"
110
-
111
-static void relaisTest() {
112
-    for (int i = 0; i < 10; i++) {
113
-        relais_enable(i, 400 + (i * 1000));
114
-        delay(100);
115
-    }
116
-}
117
-
118
-void handleRelaisTest() {
119
-    String message = F("<html><head>");
120
-    message += F("<title>" ESP_PLATFORM_NAME " Environment Sensor</title>");
121
-    message += F("</head><body>");
122
-    message += F("<p>Relais Test started!</p>");
123
-    message += F("<p><a href=\"/\">Return to Home</a></p>");
124
-    message += F("</body></html>");
125
-    
126
-    server.send(200, "text/html", message);
127
-    
128
-    relaisTest();
129
-}
130
-
131
-#endif // ENABLE_RELAIS_TEST
129
+void writeDatabase();
132 130
 
133 131
 static float bme1_temp(void) {
134 132
     while (1) {
@@ -258,10 +256,48 @@ static float sht_humid(void) {
258 256
     return 0.0;
259 257
 }
260 258
 
259
+#ifdef ENABLE_CCS811
260
+
261
+static float ccs1_eco2(void) {
262
+    return ccs1.geteCO2();
263
+}
264
+
265
+static float ccs1_tvoc(void) {
266
+    return ccs1.getTVOC();
267
+}
268
+
269
+static float ccs2_eco2(void) {
270
+    return ccs2.geteCO2();
271
+}
272
+
273
+static float ccs2_tvoc(void) {
274
+    return ccs2.getTVOC();
275
+}
276
+
277
+#endif // ENABLE_CCS811
278
+
279
+#if defined(ARDUINO_ARCH_AVR)
280
+#define ARDUINO_SEND_PARTIAL_PAGE() do { \
281
+        size_t len = message.length(), off = 0; \
282
+        while (off < len) { \
283
+            if ((len - off) >= 50) { \
284
+                client.write(message.c_str() + off, 50); \
285
+                off += 50; \
286
+            } else { \
287
+                client.write(message.c_str() + off, len - off); \
288
+                off = len; \
289
+            } \
290
+        } \
291
+        message = ""; \
292
+    } while (false);
293
+#else
294
+#define ARDUINO_SEND_PARTIAL_PAGE() while (false) { }
295
+#endif
296
+
261 297
 #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
262
-void handleRoot() {
298
+void handlePage(int mode = -1, int id = 0) {
263 299
 #else
264
-void handleRoot(WiFiClient &client) {
300
+void handlePage(WiFiClient &client, int mode = -1, int id = 0) {
265 301
 #endif
266 302
     String message;
267 303
 
@@ -271,10 +307,10 @@ void handleRoot(WiFiClient &client) {
271 307
     message += F("<h1>" ESP_PLATFORM_NAME " Environment Sensor</h1>");
272 308
     message += F("\n<p>\n");
273 309
     message += F("Version: ");
274
-    message += esp_env_version;
310
+    message += ESP_ENV_VERSION;
275 311
     message += F("\n<br>\n");
276 312
     message += F("Location: ");
277
-    message += sensor_location;
313
+    message += SENSOR_LOCATION;
278 314
 
279 315
 #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
280 316
     message += F("\n<br>\n");
@@ -284,21 +320,7 @@ void handleRoot(WiFiClient &client) {
284 320
 
285 321
     message += F("\n</p>\n");
286 322
 
287
-#if defined(ARDUINO_ARCH_AVR)
288
-    do {
289
-        size_t len = message.length(), off = 0;
290
-        while (off < len) {
291
-            if ((len - off) >= 50) {
292
-                client.write(message.c_str() + off, 50);
293
-                off += 50;
294
-            } else {
295
-                client.write(message.c_str() + off, len - off);
296
-                off = len;
297
-            }
298
-        }
299
-        message = "";
300
-    } while (false);
301
-#endif
323
+    ARDUINO_SEND_PARTIAL_PAGE();
302 324
 
303 325
 #if defined(ARDUINO_ARCH_ESP8266)
304 326
     
@@ -376,6 +398,8 @@ void handleRoot(WiFiClient &client) {
376 398
     }
377 399
     message += F("\n</p>\n");
378 400
 
401
+    ARDUINO_SEND_PARTIAL_PAGE();
402
+
379 403
     message += F("\n<p>\n");
380 404
     if (found_sht) {
381 405
         message += F("SHT21:");
@@ -390,22 +414,59 @@ void handleRoot(WiFiClient &client) {
390 414
     }
391 415
     message += F("\n</p>\n");
392 416
 
393
-#if defined(ARDUINO_ARCH_AVR)
394
-    do {
395
-        size_t len = message.length(), off = 0;
396
-        while (off < len) {
397
-            if ((len - off) >= 50) {
398
-                client.write(message.c_str() + off, 50);
399
-                off += 50;
400
-            } else {
401
-                client.write(message.c_str() + off, len - off);
402
-                off = len;
403
-            }
417
+#ifdef ENABLE_CCS811
418
+
419
+    message += F("\n<p>\n");
420
+    if (found_ccs1) {
421
+        message += F("CCS811 Low:");
422
+        message += F("\n<br>\n");
423
+        message += F("eCO2: ");
424
+        message += String(ccs1_eco2());
425
+        message += F("ppm");
426
+        message += F("\n<br>\n");
427
+        message += F("TVOC: ");
428
+        message += String(ccs1_tvoc());
429
+        message += F("ppb");
430
+
431
+        if (!ccs1_data_valid) {
432
+            message += F("\n<br>\n");
433
+            message += F("Data invalid (");
434
+            message += String(ccs1_error_code);
435
+            message += F(")!");
404 436
         }
405
-        message = "";
406
-    } while (false);
407
-#endif
437
+    } else {
438
+        message += F("CCS811 (Low) not connected!");
439
+    }
440
+    message += F("\n</p>\n");
441
+
442
+    message += F("\n<p>\n");
443
+    if (found_ccs2) {
444
+        message += F("CCS811 High:");
445
+        message += F("\n<br>\n");
446
+        message += F("eCO2: ");
447
+        message += String(ccs2_eco2());
448
+        message += F("ppm");
449
+        message += F("\n<br>\n");
450
+        message += F("TVOC: ");
451
+        message += String(ccs2_tvoc());
452
+        message += F("ppb");
453
+
454
+        if (!ccs2_data_valid) {
455
+            message += F("\n<br>\n");
456
+            message += F("Data invalid (");
457
+            message += String(ccs2_error_code);
458
+            message += F(")!");
459
+        }
460
+    } else {
461
+        message += F("CCS811 (High) not connected!");
462
+    }
463
+    message += F("\n</p>\n");
408 464
 
465
+#endif // ENABLE_CCS811
466
+
467
+    ARDUINO_SEND_PARTIAL_PAGE();
468
+
469
+#ifdef FEATURE_MOISTURE
409 470
     for (int i = 0; i < moisture_count(); i++) {
410 471
         int moisture = moisture_read(i);
411 472
         if (moisture < moisture_max()) {
@@ -427,6 +488,36 @@ void handleRoot(WiFiClient &client) {
427 488
         message += F("\n</p>\n");
428 489
     }
429 490
 
491
+    ARDUINO_SEND_PARTIAL_PAGE();
492
+#endif // FEATURE_MOISTURE
493
+
494
+#ifdef FEATURE_RELAIS
495
+    message += F("\n<p>\n");
496
+    for (int i = 0; i < relais_count(); i++) {
497
+        message += String(F("<a href=\"/on?id=")) + String(i) + String(F("\">Relais ")) + String(i) + String(F(" On (")) + relais_name(i) + String(F(")</a><br>\n"));
498
+        message += String(F("<a href=\"/off?id=")) + String(i) + String(F("\">Relais ")) + String(i) + String(F(" Off (")) + relais_name(i) + String(F(")</a><br>\n"));
499
+    }
500
+    message += String(F("<a href=\"/on?id=")) + String(relais_count()) + String(F("\">All Relais On</a><br>\n"));
501
+    message += String(F("<a href=\"/off?id=")) + String(relais_count()) + String(F("\">All Relais Off</a><br>\n"));
502
+    message += F("</p>\n");
503
+
504
+    if (mode >= 0) {
505
+        message += F("<p>");
506
+        message += F("Turned Relais ");
507
+        message += (id < relais_count()) ? String(id) : String(F("1-4"));
508
+        message += (mode ? String(F(" On")) : String(F(" Off")));
509
+        message += F("</p>\n");
510
+    }
511
+
512
+    message += F("\n<p>\n");
513
+    for (int i = 0; i < relais_count(); i++) {
514
+        message += String(F("Relais ")) + String(i) + String(F(" (")) + relais_name(i) + String(F(") = ")) + (relais_get(i) ? String(F("On")) : String(F("Off"))) + String(F("<br>\n"));
515
+    }
516
+    message += F("</p>\n");
517
+
518
+    ARDUINO_SEND_PARTIAL_PAGE();
519
+#endif // FEATURE_RELAIS
520
+
430 521
 #if ! defined(ARDUINO_ARCH_AVR)
431 522
     message += F("<p>");
432 523
     message += F("Try <a href=\"/update\">/update</a> for OTA firmware updates!");
@@ -445,37 +536,192 @@ void handleRoot(WiFiClient &client) {
445 536
     message += F("InfluxDB logging not enabled!");
446 537
 #endif
447 538
     message += F("</p>");
448
-    
449
-#ifdef ENABLE_RELAIS_TEST
450
-    message += F("<p><a href=\"/relaistest\">Relais Test</a></p>");
451
-#endif // ENABLE_RELAIS_TEST
452 539
 
453 540
     message += F("</body></html>");
454 541
 
455 542
 #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
456 543
     server.send(200, "text/html", message);
457 544
 #else
458
-    do {
459
-        size_t len = message.length(), off = 0;
460
-        while (off < len) {
461
-            if ((len - off) >= 50) {
462
-                client.write(message.c_str() + off, 50);
463
-                off += 50;
464
-            } else {
465
-                client.write(message.c_str() + off, len - off);
466
-                off = len;
467
-            }
545
+    ARDUINO_SEND_PARTIAL_PAGE();
546
+#endif
547
+}
548
+
549
+#ifdef FEATURE_RELAIS
550
+
551
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
552
+void handleOn() {
553
+#else
554
+void handleOn(WiFiClient &client) {
555
+#endif
556
+    String id_string = server.arg("id");
557
+    int id = id_string.toInt();
558
+
559
+    if ((id >= 0) && (id < relais_count())) {
560
+        relais_set(id, 1);
561
+    } else {
562
+        for (int i = 0; i < relais_count(); i++) {
563
+            relais_set(i, 1);
468 564
         }
469
-    } while (false);
565
+    }
566
+
567
+#ifdef ENABLE_INFLUXDB_LOGGING
568
+    writeDatabase();
569
+#endif // ENABLE_INFLUXDB_LOGGING
570
+
571
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
572
+    handlePage(1, id);
573
+#else
574
+    handlePage(client, 1, id);
470 575
 #endif
471 576
 }
472 577
 
578
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
579
+void handleOff() {
580
+#else
581
+void handleOff(WiFiClient &client) {
582
+#endif
583
+    String id_string = server.arg("id");
584
+    int id = id_string.toInt();
585
+
586
+    if ((id >= 0) && (id < relais_count())) {
587
+        relais_set(id, 0);
588
+    } else {
589
+        for (int i = 0; i < relais_count(); i++) {
590
+            relais_set(i, 0);
591
+        }
592
+    }
593
+
594
+#ifdef ENABLE_INFLUXDB_LOGGING
595
+    writeDatabase();
596
+#endif // ENABLE_INFLUXDB_LOGGING
597
+
598
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
599
+    handlePage(0, id);
600
+#else
601
+    handlePage(client, 0, id);
602
+#endif
603
+}
604
+
605
+#endif // FEATURE_RELAIS
606
+
607
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
608
+void handleRoot() {
609
+    handlePage();
610
+#else
611
+void handleRoot(WiFiClient &client) {
612
+    handlePage(client);
613
+#endif
614
+}
615
+
616
+#ifdef ENABLE_MQTT
617
+void writeMQTT() {
618
+    if (!mqtt.connected()) {
619
+        return;
620
+    }
621
+
622
+    if (found_bme1) {
623
+        mqtt.publish(SENSOR_LOCATION "/temperature", String(bme1_temp()).c_str());
624
+        mqtt.publish(SENSOR_LOCATION "/humidity", String(bme1_humid()).c_str());
625
+        mqtt.publish(SENSOR_LOCATION "/pressure", String(bme1_pressure()).c_str());
626
+    } else if (found_bme2) {
627
+        mqtt.publish(SENSOR_LOCATION "/temperature", String(bme2_temp()).c_str());
628
+        mqtt.publish(SENSOR_LOCATION "/humidity", String(bme2_humid()).c_str());
629
+        mqtt.publish(SENSOR_LOCATION "/pressure", String(bme2_pressure()).c_str());
630
+    } else if (found_sht) {
631
+        mqtt.publish(SENSOR_LOCATION "/temperature", String(sht_temp()).c_str());
632
+        mqtt.publish(SENSOR_LOCATION "/humidity", String(sht_humid()).c_str());
633
+    }
634
+
635
+#ifdef ENABLE_CCS811
636
+    if (found_ccs1) {
637
+        mqtt.publish(SENSOR_LOCATION "/eco2", String(ccs1_eco2()).c_str());
638
+        mqtt.publish(SENSOR_LOCATION "/tvoc", String(ccs1_tvoc()).c_str());
639
+    } else if (found_ccs2) {
640
+        mqtt.publish(SENSOR_LOCATION "/eco2", String(ccs2_eco2()).c_str());
641
+        mqtt.publish(SENSOR_LOCATION "/tvoc", String(ccs2_tvoc()).c_str());
642
+    }
643
+#endif // ENABLE_CCS811
644
+}
645
+
646
+void mqttCallback(char* topic, byte* payload, unsigned int length) {
647
+#ifdef FEATURE_RELAIS
648
+    int state = 0;
649
+    int id = -1;
650
+
651
+    String ts(topic), ps((char *)payload);
652
+
653
+    String our_topic(SENSOR_LOCATION);
654
+    our_topic += "/";
655
+
656
+    if (!ts.startsWith(our_topic)) {
657
+        Serial.print(F("Unknown MQTT room "));
658
+        Serial.println(ts);
659
+        return;
660
+    }
661
+
662
+    String ids = ts.substring(our_topic.length());
663
+    for (int i = 0; i < relais_count(); i++) {
664
+        if (ids == relais_name(i)) {
665
+            id = i;
666
+            break;
667
+        }
668
+    }
669
+
670
+    if (id < 0) {
671
+        Serial.print(F("Unknown MQTT topic "));
672
+        Serial.println(ts);
673
+        return;
674
+    }
675
+
676
+    if (ps.indexOf("on") != -1) {
677
+        state = 1;
678
+    } else if (ps.indexOf("off") != -1) {
679
+        state = 0;
680
+    } else {
681
+        return;
682
+    }
683
+
684
+    if ((id >= 0) && (id < relais_count())) {
685
+        relais_set(id, state);
686
+
687
+#ifdef ENABLE_INFLUXDB_LOGGING
688
+        writeDatabase();
689
+#endif // ENABLE_INFLUXDB_LOGGING
690
+    }
691
+#endif // FEATURE_RELAIS
692
+}
693
+
694
+void mqttReconnect() {
695
+    // Create a random client ID
696
+    String clientId = F("ESP-" SENSOR_LOCATION "-");
697
+    clientId += String(random(0xffff), HEX);
698
+
699
+    // Attempt to connect
700
+#if defined(MQTT_USER) && defined(MQTT_PASS)
701
+    if (mqtt.connect(clientId.c_str(), MQTT_USER, MQTT_PASS)) {
702
+#else
703
+    if (mqtt.connect(clientId.c_str())) {
704
+#endif
705
+        // Once connected, publish an announcement...
706
+        mqtt.publish(SENSOR_LOCATION, "sensor online");
707
+
708
+        // ... and resubscribe
709
+#ifdef FEATURE_RELAIS
710
+        mqtt.subscribe(SENSOR_LOCATION);
711
+        for (int i = 0; i < relais_count(); i++) {
712
+            String topic(SENSOR_LOCATION);
713
+            topic += String("/") + relais_name(i);
714
+            mqtt.subscribe(topic.c_str());
715
+        }
716
+#endif // FEATURE_RELAIS
717
+    }
718
+}
719
+#endif // ENABLE_MQTT
720
+
473 721
 void setup() {
474 722
     pinMode(BUILTIN_LED_PIN, OUTPUT);
475 723
     
476
-#ifdef ENABLE_RELAIS_TEST
477
-    relais_init();
478
-#endif // ENABLE_RELAIS_TEST
724
+    Serial.begin(115200);
479 725
 
480 726
     // Blink LED for init
481 727
     for (int i = 0; i < 2; i++) {
@@ -484,45 +730,78 @@ void setup() {
484 730
         digitalWrite(BUILTIN_LED_PIN, HIGH); // LED off
485 731
         delay(LED_INIT_BLINK_INTERVAL);
486 732
     }
733
+
734
+    Serial.print(F("Relais"));
735
+    relais_init();
487 736
     
737
+    Serial.print(F("Moisture"));
488 738
     moisture_init();
489 739
 
490 740
     // Init I2C and try to connect to sensors
491 741
 #if defined(ARDUINO_ARCH_ESP8266)
492 742
 
743
+    Serial.print(F("Wire2"));
493 744
     Wire2.begin(I2C_SDA_PIN, I2C_SCL_PIN);
745
+
746
+    Serial.print(F("BME"));
494 747
     found_bme1 = (!bme1.begin(BME_I2C_ADDRESS_1, &Wire2)) ? false : true;
495 748
     found_bme2 = (!bme2.begin(BME_I2C_ADDRESS_2, &Wire2)) ? false : true;
496 749
 
750
+#ifdef ENABLE_CCS811
751
+    Serial.print(F("CCS"));
752
+    found_ccs1 = ccs1.begin(CCS811_ADDRESS_1, &Wire2);
753
+    found_ccs2 = ccs2.begin(CCS811_ADDRESS_2, &Wire2);
754
+#endif // ENABLE_CCS811
755
+
497 756
 #elif defined(ARDUINO_ARCH_ESP32)
498 757
 
758
+    Serial.print(F("Wire"));
499 759
     Wire.begin();
760
+
761
+    Serial.print(F("BME"));
500 762
     found_bme1 = (!bme1.begin(BME_I2C_ADDRESS_1, &Wire)) ? false : true;
501 763
     found_bme2 = (!bme2.begin(BME_I2C_ADDRESS_2, &Wire)) ? false : true;
502 764
 
765
+#ifdef ENABLE_CCS811
766
+    Serial.print(F("CCS"));
767
+    found_ccs1 = ccs1.begin(CCS811_ADDRESS_1, &Wire);
768
+    found_ccs2 = ccs2.begin(CCS811_ADDRESS_2, &Wire);
769
+#endif // ENABLE_CCS811
770
+
503 771
 #elif defined(ARDUINO_ARCH_AVR)
504 772
 
773
+    Serial.print(F("BME"));
505 774
     found_bme1 = (!bme1.begin(BME_I2C_ADDRESS_1, &Wire)) ? false : true;
506 775
     found_bme2 = (!bme2.begin(BME_I2C_ADDRESS_2, &Wire)) ? false : true;
507 776
 
777
+#ifdef ENABLE_CCS811
778
+    Serial.print(F("CCS"));
779
+    found_ccs1 = ccs1.begin(CCS811_ADDRESS_1, &Wire);
780
+    found_ccs2 = ccs2.begin(CCS811_ADDRESS_2, &Wire);
781
+#endif // ENABLE_CCS811
782
+
508 783
 #endif
509 784
 
785
+    Serial.print(F("SHT"));
510 786
     found_sht = sht.GetAlive();
511 787
 
512 788
     // Build hostname string
513 789
     String hostname = SENSOR_HOSTNAME_PREFIX;
514
-    hostname += sensor_location;
790
+    hostname += SENSOR_LOCATION;
515 791
 
516 792
 #if defined(ARDUINO_ARCH_ESP8266)
517 793
 
518 794
     // Connect to WiFi AP
795
+    Serial.print(F("Connecting WiFi"));
519 796
     WiFi.hostname(hostname);
520 797
     WiFi.mode(WIFI_STA);
521
-    WiFi.begin(ssid, password);
798
+    WiFi.begin(WIFI_SSID, WIFI_PASS);
522 799
     while (WiFi.status() != WL_CONNECTED) {
523 800
         delay(LED_CONNECT_BLINK_INTERVAL);
524 801
         digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
802
+        Serial.print(F("."));
525 803
     }
804
+    Serial.println(F("\nWiFi connected!"));
526 805
     
527 806
 #elif defined(ARDUINO_ARCH_ESP32)
528 807
 
@@ -541,25 +820,27 @@ void setup() {
541 820
     }, WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
542 821
 
543 822
     // Connect to WiFi AP
823
+    Serial.print(F("Connecting WiFi"));
544 824
     WiFi.mode(WIFI_STA);
545
-    WiFi.begin(ssid, password);
825
+    WiFi.begin(WIFI_SSID, WIFI_PASS);
546 826
     while (WiFi.status() != WL_CONNECTED) {
547 827
         delay(LED_CONNECT_BLINK_INTERVAL);
548 828
         digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
829
+        Serial.print(F("."));
549 830
     }
831
+    Serial.println(F("\nWiFi connected!"));
550 832
     
551 833
     // Set hostname workaround
552 834
     WiFi.setHostname(hostname.c_str());
553 835
 
554 836
 #elif defined(ARDUINO_ARCH_AVR)
555 837
 
556
-    Serial.begin(115200);
557 838
     Serial1.begin(115200);
558 839
 
559 840
     WiFi.init(&Serial1);
560 841
 
561 842
     Serial.print(F("Connecting WiFi"));
562
-    WiFi.begin(ssid, password);
843
+    WiFi.begin(WIFI_SSID, WIFI_PASS);
563 844
     while (WiFi.status() != WL_CONNECTED) {
564 845
         delay(LED_CONNECT_BLINK_INTERVAL);
565 846
         digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
@@ -569,20 +850,31 @@ void setup() {
569 850
 
570 851
 #endif
571 852
 
853
+    Serial.println(F("Seeding"));
854
+    randomSeed(micros());
855
+
856
+#ifdef ENABLE_MQTT
857
+    Serial.println(F("MQTT"));
858
+    mqtt.setServer(MQTT_HOST, MQTT_PORT);
859
+    mqtt.setCallback(mqttCallback);
860
+#endif // ENABLE_MQTT
861
+
572 862
 #ifdef ENABLE_INFLUXDB_LOGGING
573
-    // Setup InfluxDB Client
863
+    Serial.println(F("Influx"));
574 864
     influx.setDb(INFLUXDB_DATABASE);
575 865
 #endif // ENABLE_INFLUXDB_LOGGING
576 866
 
577 867
 #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
578 868
     // Setup HTTP Server
869
+    Serial.println(F("HTTP"));
579 870
     MDNS.begin(hostname.c_str());
580 871
     updater.setup(&server);
581 872
     server.on("/", handleRoot);
582 873
 
583
-#ifdef ENABLE_RELAIS_TEST
584
-    server.on("/relaistest", handleRelaisTest);
585
-#endif
874
+#ifdef FEATURE_RELAIS
875
+    server.on("/on", handleOn);
876
+    server.on("/off", handleOff);
877
+#endif // FEATURE_RELAIS
586 878
 
587 879
     MDNS.addService("http", "tcp", 80);
588 880
 #endif
@@ -614,7 +906,10 @@ void http_server() {
614 906
                     client.println(F("Content-Type: text/html"));
615 907
                     client.println(F("Connection: close"));
616 908
                     client.println();
909
+
910
+                    // TODO parse path and handle different pages
617 911
                     handleRoot(client);
912
+
618 913
                     break;
619 914
                 }
620 915
 
@@ -680,7 +975,7 @@ void writeDatabase() {
680 975
         InfluxData measurement("environment");
681 976
 #endif
682 977
 
683
-        measurement.addTag("location", sensor_location);
978
+        measurement.addTag("location", SENSOR_LOCATION);
684 979
         measurement.addTag("placement", "1");
685 980
         measurement.addTag("sensor", "bme280");
686 981
 
@@ -705,7 +1000,7 @@ void writeDatabase() {
705 1000
         InfluxData measurement("environment");
706 1001
 #endif
707 1002
 
708
-        measurement.addTag("location", sensor_location);
1003
+        measurement.addTag("location", SENSOR_LOCATION);
709 1004
         measurement.addTag("placement", "2");
710 1005
         measurement.addTag("sensor", "bme280");
711 1006
 
@@ -730,7 +1025,7 @@ void writeDatabase() {
730 1025
         InfluxData measurement("environment");
731 1026
 #endif
732 1027
 
733
-        measurement.addTag("location", sensor_location);
1028
+        measurement.addTag("location", SENSOR_LOCATION);
734 1029
         measurement.addTag("sensor", "sht21");
735 1030
 
736 1031
 #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
@@ -744,7 +1039,66 @@ void writeDatabase() {
744 1039
         writeMeasurement(measurement);
745 1040
         Serial.println(F("Done!"));
746 1041
     }
747
-    
1042
+
1043
+#ifdef ENABLE_CCS811
1044
+
1045
+    if (found_ccs1) {
1046
+#if defined(ARDUINO_ARCH_AVR)
1047
+        measurement.clear();
1048
+        measurement.setName("environment");
1049
+#else
1050
+        InfluxData measurement("environment");
1051
+#endif
1052
+
1053
+        measurement.addTag("location", SENSOR_LOCATION);
1054
+        measurement.addTag("placement", "1");
1055
+        measurement.addTag("sensor", "ccs811");
1056
+
1057
+        String err(ccs1_error_code);
1058
+        measurement.addTag("error", err);
1059
+
1060
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
1061
+        measurement.addTag("device", WiFi.macAddress());
1062
+#endif
1063
+
1064
+        measurement.addValue("eco2", ccs1_eco2());
1065
+        measurement.addValue("tvoc", ccs1_tvoc());
1066
+
1067
+        Serial.println(F("Writing ccs1"));
1068
+        writeMeasurement(measurement);
1069
+        Serial.println(F("Done!"));
1070
+    }
1071
+
1072
+    if (found_ccs2) {
1073
+#if defined(ARDUINO_ARCH_AVR)
1074
+        measurement.clear();
1075
+        measurement.setName("environment");
1076
+#else
1077
+        InfluxData measurement("environment");
1078
+#endif
1079
+
1080
+        measurement.addTag("location", SENSOR_LOCATION);
1081
+        measurement.addTag("placement", "2");
1082
+        measurement.addTag("sensor", "ccs811");
1083
+
1084
+        String err(ccs2_error_code);
1085
+        measurement.addTag("error", err);
1086
+
1087
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
1088
+        measurement.addTag("device", WiFi.macAddress());
1089
+#endif
1090
+
1091
+        measurement.addValue("eco2", ccs2_eco2());
1092
+        measurement.addValue("tvoc", ccs2_tvoc());
1093
+
1094
+        Serial.println(F("Writing ccs2"));
1095
+        writeMeasurement(measurement);
1096
+        Serial.println(F("Done!"));
1097
+    }
1098
+
1099
+#endif // ENABLE_CCS811
1100
+
1101
+#ifdef FEATURE_MOISTURE
748 1102
     for (int i = 0; i < moisture_count(); i++) {
749 1103
         int moisture = moisture_read(i);
750 1104
         if (moisture < moisture_max()) {
@@ -755,7 +1109,7 @@ void writeDatabase() {
755 1109
             InfluxData measurement("moisture");
756 1110
 #endif
757 1111
 
758
-            measurement.addTag("location", sensor_location);
1112
+            measurement.addTag("location", SENSOR_LOCATION);
759 1113
             String sensor(i + 1, DEC);
760 1114
             measurement.addTag("sensor", sensor);
761 1115
 
@@ -772,29 +1126,89 @@ void writeDatabase() {
772 1126
             Serial.println(F("Done!"));
773 1127
         }
774 1128
     }
1129
+#endif // FEATURE_MOISTURE
1130
+
1131
+#ifdef FEATURE_RELAIS
1132
+    for (int i = 0; i < relais_count(); i++) {
1133
+        InfluxData measurement("relais");
1134
+        measurement.addTag("location", SENSOR_LOCATION);
1135
+        measurement.addTag("id", String(i));
1136
+        measurement.addTag("name", relais_name(i));
1137
+
1138
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
1139
+        measurement.addTag("device", WiFi.macAddress());
1140
+#endif
1141
+
1142
+        measurement.addValue("state", relais_get(i));
1143
+        writeMeasurement(measurement);
1144
+    }
1145
+#endif // FEATURE_RELAIS
775 1146
 
776 1147
     Serial.println(F("All Done!"));
777 1148
 }
778 1149
 #endif // ENABLE_INFLUXDB_LOGGING
779 1150
 
1151
+#ifdef ENABLE_CCS811
1152
+void ccs_update() {
1153
+    if (found_ccs1) {
1154
+        if (ccs1.available()) {
1155
+            ccs1_error_code = ccs1.readData();
1156
+            ccs1_data_valid = (ccs1_error_code == 0);
1157
+
1158
+            if (found_bme1) {
1159
+                ccs1.setEnvironmentalData(bme1_humid(), bme1_temp());
1160
+            } else if (found_bme2) {
1161
+                ccs1.setEnvironmentalData(bme2_humid(), bme2_temp());
1162
+            } else if (found_sht) {
1163
+                ccs1.setEnvironmentalData(sht_humid(), sht_temp());
1164
+            }
1165
+        }
1166
+    }
1167
+
1168
+    if (found_ccs2) {
1169
+        if (ccs2.available()) {
1170
+            ccs2_error_code = ccs2.readData();
1171
+            ccs2_data_valid = (ccs2_error_code == 0);
1172
+
1173
+            if (found_bme1) {
1174
+                ccs2.setEnvironmentalData(bme1_humid(), bme1_temp());
1175
+            } else if (found_bme2) {
1176
+                ccs2.setEnvironmentalData(bme2_humid(), bme2_temp());
1177
+            } else if (found_sht) {
1178
+                ccs2.setEnvironmentalData(sht_humid(), sht_temp());
1179
+            }
1180
+        }
1181
+    }
1182
+}
1183
+#endif // ENABLE_CCS811
1184
+
780 1185
 void loop() {
781 1186
     unsigned long time = millis();
782 1187
     
783
-#ifdef ENABLE_RELAIS_TEST
784
-    relais_run();
785
-#endif // ENABLE_RELAIS_TEST
1188
+#ifdef ENABLE_CCS811
1189
+    if (found_ccs1 || found_ccs2) {
1190
+        ccs_update();
1191
+    }
1192
+#endif // ENABLE_CCS811
786 1193
 
787 1194
     if ((time - last_server_handle_time) >= SERVER_HANDLE_INTERVAL) {
788 1195
         last_server_handle_time = time;
789 1196
         handleServers();
790 1197
     }
791 1198
 
792
-#ifdef ENABLE_INFLUXDB_LOGGING
793 1199
     if ((time - last_db_write_time) >= DB_WRITE_INTERVAL) {
794 1200
         last_db_write_time = time;
1201
+
1202
+#ifdef ENABLE_INFLUXDB_LOGGING
795 1203
         writeDatabase();
1204
+#endif // ENABLE_INFLUXDB_LOGGING
1205
+
1206
+#ifdef ENABLE_MQTT
1207
+        writeMQTT();
1208
+#endif // ENABLE_MQTT
796 1209
     }
797 1210
     
1211
+#ifdef ENABLE_INFLUXDB_LOGGING
798 1212
 #ifdef INFLUX_MAX_ERRORS_RESET
799 1213
     if (error_count >= INFLUX_MAX_ERRORS_RESET) {
800 1214
 #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
@@ -804,6 +1218,15 @@ void loop() {
804 1218
 #endif // INFLUX_MAX_ERRORS_RESET
805 1219
 #endif // ENABLE_INFLUXDB_LOGGING
806 1220
 
1221
+#ifdef ENABLE_MQTT
1222
+    if (!mqtt.connected() && ((millis() - last_mqtt_reconnect_time) >= MQTT_RECONNECT_INTERVAL)) {
1223
+        last_mqtt_reconnect_time = millis();
1224
+        mqttReconnect();
1225
+    }
1226
+
1227
+    mqtt.loop();
1228
+#endif // ENABLE_MQTT
1229
+
807 1230
     // blink heartbeat LED
808 1231
     if ((time - last_led_blink_time) >= LED_BLINK_INTERVAL) {
809 1232
         last_led_blink_time = time;
@@ -811,10 +1234,9 @@ void loop() {
811 1234
     }
812 1235
     
813 1236
 #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
814
-    // reset ESP every 6h to be safe
815
-    if (time >= (6 * 60 * 60 * 1000)) {
1237
+    // reset ESP every 3d to be safe
1238
+    if (time >= (3UL * 24UL * 60UL * 60UL * 1000UL)) {
816 1239
         ESP.restart();
817 1240
     }
818 1241
 #endif
819 1242
 }
820
-

+ 26
- 27
src/moisture.cpp 파일 보기

@@ -14,23 +14,7 @@
14 14
 #include <Arduino.h>
15 15
 #include "moisture.h"
16 16
 
17
-#if defined(ARDUINO_ARCH_ESP8266)
18
-
19
-int moisture_count(void) {
20
-    return 0;
21
-}
22
-
23
-int moisture_read(int sensor) {
24
-    return 0;
25
-}
26
-
27
-int moisture_max(void) {
28
-    return 0;
29
-}
30
-
31
-void moisture_init(void) { }
32
-
33
-#elif defined(ARDUINO_ARCH_ESP32)
17
+#if defined(MOISTURE_ADC_ESP32)
34 18
 
35 19
 #include <driver/adc.h>
36 20
 
@@ -56,6 +40,13 @@ static int adc_read_oversampled(adc1_channel_t pin) {
56 40
     return sample_sum / ADC_OVERSAMPLE;
57 41
 }
58 42
 
43
+void moisture_init(void) {
44
+    adc1_config_width(ADC_BITS);
45
+    for (int i = 0; i < SENSOR_COUNT; i++) {
46
+        adc1_config_channel_atten(sensor_pin[i], ADC_ATTENUATION);
47
+    }
48
+}
49
+
59 50
 int moisture_count(void) {
60 51
     return SENSOR_COUNT;
61 52
 }
@@ -72,14 +63,7 @@ int moisture_max(void) {
72 63
     return (1 << ADC_BITWIDTH) - 1;
73 64
 }
74 65
 
75
-void moisture_init(void) {
76
-    adc1_config_width(ADC_BITS);
77
-    for (int i = 0; i < SENSOR_COUNT; i++) {
78
-        adc1_config_channel_atten(sensor_pin[i], ADC_ATTENUATION);
79
-    }
80
-}
81
-
82
-#elif defined(ARDUINO_ARCH_AVR)
66
+#elif defined(MOISTURE_ADC_ARDUINO)
83 67
 
84 68
 // Hardware I2C pins A4 and A5 not usable on Arduino Uno Wifi Dev. Ed.
85 69
 #define SENSOR_COUNT 6
@@ -87,6 +71,10 @@ uint8_t sensor_pins[SENSOR_COUNT] = { A0, A1, A1, A2, A3, A3 };
87 71
 
88 72
 #define OVERSAMPLE_COUNT 3
89 73
 
74
+void moisture_init(void) {
75
+
76
+}
77
+
90 78
 int moisture_count(void) {
91 79
     return SENSOR_COUNT;
92 80
 }
@@ -105,9 +93,20 @@ int moisture_max(void) {
105 93
     return 4095;
106 94
 }
107 95
 
108
-void moisture_init(void) {
96
+#else
97
+
98
+void moisture_init(void) { }
109 99
 
100
+int moisture_count(void) {
101
+    return 0;
110 102
 }
111 103
 
112
-#endif
104
+int moisture_read(int sensor) {
105
+    return 0;
106
+}
113 107
 
108
+int moisture_max(void) {
109
+    return 0;
110
+}
111
+
112
+#endif

+ 132
- 37
src/relais.cpp 파일 보기

@@ -13,71 +13,166 @@
13 13
 
14 14
 #include <Arduino.h>
15 15
 #include "relais.h"
16
+#include "config.h"
16 17
 
17
-#if defined(ARDUINO_ARCH_ESP8266)
18
+#if defined(RELAIS_SERIAL)
19
+
20
+#define SERIAL_RELAIS_COUNT 4
21
+
22
+/*
23
+Turn OFF the first relay  : A0 01 00 A1
24
+Turn ON the first relay   : A0 01 01 A2
25
+Turn OFF the second relay : A0 02 00 A2
26
+Turn ON the second relay  : A0 02 01 A3
27
+Turn OFF the third relay  : A0 03 00 A3
28
+Turn ON the third relay   : A0 03 01 A4
29
+Turn OFF the fourth relay : A0 04 00 A4
30
+Turn ON the fourth relay  : A0 04 01 A5
31
+*/
32
+
33
+static int states[SERIAL_RELAIS_COUNT];
34
+
35
+static String names[SERIAL_RELAIS_COUNT] = {
36
+#if defined(SENSOR_LOCATION_BATHROOM)
37
+    String("light_small"),
38
+    String("light_big"),
39
+    String("relais_2"),
40
+    String("fan")
41
+#else
42
+    String("relais_0"),
43
+    String("relais_1"),
44
+    String("relais_2"),
45
+    String("relais_3")
46
+#endif
47
+};
48
+
49
+static int initial_values[SERIAL_RELAIS_COUNT] = {
50
+#if defined(SENSOR_LOCATION_BATHROOM)
51
+    1, 0, 0, 1
52
+#else
53
+    0, 0, 0, 0
54
+#endif
55
+};
56
+
57
+void relais_init(void) {
58
+    Serial.begin(115200);
59
+
60
+    for (int i = 0; i < SERIAL_RELAIS_COUNT; i++) {
61
+        relais_set(i, initial_values[i]);
62
+    }
63
+}
18 64
 
19 65
 int relais_count(void) {
20
-    return 0;
66
+    return SERIAL_RELAIS_COUNT;
21 67
 }
22 68
 
23
-int relais_enable(int relais, unsigned long time) {
24
-    return 0;
69
+void relais_set(int relais, int state) {
70
+    if ((relais < 0) || (relais >= SERIAL_RELAIS_COUNT)) {
71
+        return;
72
+    }
73
+
74
+    states[relais] = state;
75
+
76
+    int cmd[4];
77
+    cmd[0] = 0xA0; // command
78
+
79
+    cmd[1] = relais + 1; // relais id, 1-4
80
+    cmd[2] = state ? 1 : 0; // relais state
81
+
82
+    cmd[3] = 0; // checksum
83
+    for (int i = 0; i < 3; i++) {
84
+        cmd[3] += cmd[i];
85
+    }
86
+
87
+    for (int i = 0; i < 4; i++) {
88
+        Serial.write(cmd[i]);
89
+    }
90
+
91
+    delay(100);
25 92
 }
26 93
 
27
-void relais_init(void) { }
28
-void relais_run(void) { }
94
+int relais_get(int relais) {
95
+    if ((relais < 0) || (relais >= SERIAL_RELAIS_COUNT)) {
96
+        return 0;
97
+    }
29 98
 
30
-#elif defined(ARDUINO_ARCH_ESP32)
99
+    return states[relais];
100
+}
31 101
 
32
-#define RELAIS_COUNT 10
102
+String relais_name(int relais) {
103
+    if ((relais < 0) || (relais >= SERIAL_RELAIS_COUNT)) {
104
+        return String(F("Unknown"));
105
+    }
33 106
 
34
-struct relais_state {
35
-    unsigned long turn_off;
36
-};
107
+    return names[relais];
108
+}
109
+
110
+#elif defined(RELAIS_GPIO)
111
+
112
+#define GPIO_RELAIS_COUNT 10
37 113
 
38
-static struct relais_state state[RELAIS_COUNT];
39
-static int gpios[RELAIS_COUNT] = {
114
+static int gpios[GPIO_RELAIS_COUNT] = {
40 115
     0, 15, 2, 4,
41 116
     16, 17, 5, 18,
42 117
     19, 23
43 118
 };
44 119
 
45
-static void relais_set(int relais, int state) {
46
-    digitalWrite(gpios[relais], state ? LOW : HIGH);
120
+static int states[GPIO_RELAIS_COUNT];
121
+
122
+static String names[GPIO_RELAIS_COUNT] = {
123
+    String(F("relais_0")),
124
+    String(F("relais_1")),
125
+    String(F("relais_2")),
126
+    String(F("relais_3")),
127
+    String(F("relais_4")),
128
+    String(F("relais_5")),
129
+    String(F("relais_6")),
130
+    String(F("relais_7")),
131
+    String(F("relais_8")),
132
+    String(F("relais_9"))
133
+};
134
+
135
+void relais_init(void) {
136
+    for (int i = 0; i < GPIO_RELAIS_COUNT; i++) {
137
+        pinMode(gpios[i], OUTPUT);
138
+        relais_set(i, 0);
139
+    }
47 140
 }
48 141
 
49 142
 int relais_count(void) {
50
-    return RELAIS_COUNT;
143
+    return GPIO_RELAIS_COUNT;
51 144
 }
52 145
 
53
-int relais_enable(int relais, unsigned long time) {
54
-    if ((relais < 0) || (relais >= RELAIS_COUNT)) {
55
-        return -1;
146
+void relais_set(int relais, int state) {
147
+    if ((relais < 0) || (relais >= GPIO_RELAIS_COUNT)) {
148
+        return;
56 149
     }
57
-    
58
-    relais_set(relais, 1);
59
-    state[relais].turn_off = millis() + time;
60
-    return 0;
150
+
151
+    states[relais] = state;
152
+    digitalWrite(gpios[relais], state ? LOW : HIGH);
61 153
 }
62 154
 
63
-void relais_init(void) {
64
-    for (int i = 0; i < RELAIS_COUNT; i++) {
65
-        pinMode(gpios[i], OUTPUT);
66
-        relais_set(i, 0);
67
-        
68
-        state[i].turn_off = 0;
155
+int relais_get(int relais) {
156
+    if ((relais < 0) || (relais >= GPIO_RELAIS_COUNT)) {
157
+        return 0;
69 158
     }
159
+
160
+    return states[relais];
70 161
 }
71 162
 
72
-void relais_run(void) {
73
-    for (int i = 0; i < RELAIS_COUNT; i++) {
74
-        if (state[i].turn_off > 0) {
75
-            if (millis() >= state[i].turn_off) {
76
-                relais_set(i, 0);
77
-            }
78
-        }
163
+String relais_name(int relais) {
164
+    if ((relais < 0) || (relais >= GPIO_RELAIS_COUNT)) {
165
+        return String(F("Unknown"));
79 166
     }
167
+
168
+    return names[relais];
80 169
 }
81 170
 
82
-#endif
171
+#else
83 172
 
173
+void relais_init(void) { }
174
+int relais_count(void) { return 0; }
175
+void relais_set(int relais, int state) { }
176
+int relais_get(int relais) { return 0; }
177
+
178
+#endif

Loading…
취소
저장