Browse Source

Add ClimateControl code

master
Steven Haigh 4 months ago
parent
commit
ec35fdfd4b
39 changed files with 3117 additions and 0 deletions
  1. 39
    0
      .gitignore
  2. 36
    0
      ClimateControl/lib/DHTStable_ID1337/.library.json
  3. 180
    0
      ClimateControl/lib/DHTStable_ID1337/dht.cpp
  4. 72
    0
      ClimateControl/lib/DHTStable_ID1337/dht.h
  5. 56
    0
      ClimateControl/lib/DHTStable_ID1337/examples/dht11_test/dht11_test.ino
  6. 56
    0
      ClimateControl/lib/DHTStable_ID1337/examples/dht12_test/dht12_test.ino
  7. 105
    0
      ClimateControl/lib/DHTStable_ID1337/examples/dht22_test/dht22_test.ino
  8. 2
    0
      ClimateControl/lib/DHTStable_ID1337/examples/readme.txt
  9. 37
    0
      ClimateControl/lib/DHTStable_ID1337/keywords.txt
  10. 24
    0
      ClimateControl/lib/DHTStable_ID1337/library.json
  11. 9
    0
      ClimateControl/lib/DHTStable_ID1337/library.properties
  12. 13
    0
      ClimateControl/lib/DHTStable_ID1337/readme.md
  13. 1
    0
      ClimateControl/lib/PubSubClient_ID89/.gitignore
  14. 35
    0
      ClimateControl/lib/PubSubClient_ID89/.library.json
  15. 7
    0
      ClimateControl/lib/PubSubClient_ID89/.travis.yml
  16. 76
    0
      ClimateControl/lib/PubSubClient_ID89/CHANGES.txt
  17. 20
    0
      ClimateControl/lib/PubSubClient_ID89/LICENSE.txt
  18. 48
    0
      ClimateControl/lib/PubSubClient_ID89/README.md
  19. 43
    0
      ClimateControl/lib/PubSubClient_ID89/examples/mqtt_auth/mqtt_auth.ino
  20. 77
    0
      ClimateControl/lib/PubSubClient_ID89/examples/mqtt_basic/mqtt_basic.ino
  21. 132
    0
      ClimateControl/lib/PubSubClient_ID89/examples/mqtt_esp8266/mqtt_esp8266.ino
  22. 179
    0
      ClimateControl/lib/PubSubClient_ID89/examples/mqtt_large_message/mqtt_large_message.ino
  23. 60
    0
      ClimateControl/lib/PubSubClient_ID89/examples/mqtt_publish_in_callback/mqtt_publish_in_callback.ino
  24. 67
    0
      ClimateControl/lib/PubSubClient_ID89/examples/mqtt_reconnect_nonblocking/mqtt_reconnect_nonblocking.ino
  25. 57
    0
      ClimateControl/lib/PubSubClient_ID89/examples/mqtt_stream/mqtt_stream.ino
  26. 33
    0
      ClimateControl/lib/PubSubClient_ID89/keywords.txt
  27. 17
    0
      ClimateControl/lib/PubSubClient_ID89/library.json
  28. 9
    0
      ClimateControl/lib/PubSubClient_ID89/library.properties
  29. 653
    0
      ClimateControl/lib/PubSubClient_ID89/src/PubSubClient.cpp
  30. 173
    0
      ClimateControl/lib/PubSubClient_ID89/src/PubSubClient.h
  31. 0
    0
      ClimateControl/lib/SimpleTimer_ID419/.gitignore
  32. 27
    0
      ClimateControl/lib/SimpleTimer_ID419/.library.json
  33. 2
    0
      ClimateControl/lib/SimpleTimer_ID419/README
  34. 241
    0
      ClimateControl/lib/SimpleTimer_ID419/SimpleTimer.cpp
  35. 124
    0
      ClimateControl/lib/SimpleTimer_ID419/SimpleTimer.h
  36. 12
    0
      ClimateControl/lib/SimpleTimer_ID419/library.json
  37. 41
    0
      ClimateControl/lib/readme.txt
  38. 31
    0
      ClimateControl/platformio.ini
  39. 323
    0
      ClimateControl/src/ClimateControl.ino

+ 39
- 0
.gitignore View File

@@ -0,0 +1,39 @@
1
+**/.pioenvs
2
+**/.piolibdeps
3
+**/*.bin
4
+**/flash
5
+**/build
6
+
7
+## Templated .gitignore for C++ projects:
8
+# Prerequisites
9
+*.d
10
+
11
+# Compiled Object files
12
+*.slo
13
+*.lo
14
+*.o
15
+*.obj
16
+
17
+# Precompiled Headers
18
+*.gch
19
+*.pch
20
+
21
+# Compiled Dynamic libraries
22
+*.so
23
+*.dylib
24
+*.dll
25
+
26
+# Fortran module files
27
+*.mod
28
+*.smod
29
+
30
+# Compiled Static libraries
31
+*.lai
32
+*.la
33
+*.a
34
+*.lib
35
+
36
+# Executables
37
+*.exe
38
+*.out
39
+*.app

+ 36
- 0
ClimateControl/lib/DHTStable_ID1337/.library.json View File

@@ -0,0 +1,36 @@
1
+{
2
+    "name": "DHTStable", 
3
+    "keywords": [
4
+        "dht11", 
5
+        "dht22", 
6
+        "dht33", 
7
+        "dht44", 
8
+        "am2301", 
9
+        "am2302", 
10
+        "am2303"
11
+    ], 
12
+    "description": "Stable version of the library for DHT Temperature & Humidity Sensor.", 
13
+    "authors": [
14
+        {
15
+            "email": "Rob.Tillaart@gmail.com", 
16
+            "url": null, 
17
+            "maintainer": true, 
18
+            "name": "Rob Tillaart"
19
+        }
20
+    ], 
21
+    "repository": {
22
+        "type": "git", 
23
+        "url": "https://github.com/RobTillaart/Arduino.git"
24
+    }, 
25
+    "version": "0.2.4", 
26
+    "frameworks": [
27
+        "arduino"
28
+    ], 
29
+    "platforms": [
30
+        "atmelavr"
31
+    ], 
32
+    "export": {
33
+        "include": "libraries/DHTstable"
34
+    }, 
35
+    "id": 1337
36
+}

+ 180
- 0
ClimateControl/lib/DHTStable_ID1337/dht.cpp View File

@@ -0,0 +1,180 @@
1
+//
2
+//    FILE: dht.cpp
3
+//  AUTHOR: Rob Tillaart
4
+// VERSION: 0.2.4
5
+// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
6
+//     URL: https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable
7
+//
8
+// HISTORY:
9
+// 0.2.4  2018-04-03 add get-/setDisableIRQ(bool b)
10
+// 0.2.3  2018-02-21 change #defines in const int to enforce return types.
11
+//                   https://github.com/RobTillaart/Arduino/issues/94
12
+// 0.2.2  2017-12-12 add support for AM23XX types more explicitly
13
+// 0.2.1  2017-09-20 fix https://github.com/RobTillaart/Arduino/issues/80
14
+// 0.2.0  2017-07-24 fix https://github.com/RobTillaart/Arduino/issues/31 + 33
15
+// 0.1.13 fix negative temperature
16
+// 0.1.12 support DHT33 and DHT44 initial version
17
+// 0.1.11 renamed DHTLIB_TIMEOUT
18
+// 0.1.10 optimized faster WAKEUP + TIMEOUT
19
+// 0.1.09 optimize size: timeout check + use of mask
20
+// 0.1.08 added formula for timeout based upon clockspeed
21
+// 0.1.07 added support for DHT21
22
+// 0.1.06 minimize footprint (2012-12-27)
23
+// 0.1.05 fixed negative temperature bug (thanks to Roseman)
24
+// 0.1.04 improved readability of code using DHTLIB_OK in code
25
+// 0.1.03 added error values for temp and humidity when read failed
26
+// 0.1.02 added error codes
27
+// 0.1.01 added support for Arduino 1.0, fixed typos (31/12/2011)
28
+// 0.1.0 by Rob Tillaart (01/04/2011)
29
+//
30
+// inspired by DHT11 library
31
+//
32
+// Released to the public domain
33
+//
34
+
35
+#include "dht.h"
36
+
37
+/////////////////////////////////////////////////////
38
+//
39
+// PUBLIC
40
+//
41
+
42
+// return values:
43
+// DHTLIB_OK
44
+// DHTLIB_ERROR_CHECKSUM
45
+// DHTLIB_ERROR_TIMEOUT
46
+int dht::read11(uint8_t pin)
47
+{
48
+    // READ VALUES
49
+    if (_disableIRQ) noInterrupts();
50
+    int rv = _readSensor(pin, DHTLIB_DHT11_WAKEUP);
51
+    if (_disableIRQ) interrupts();
52
+    if (rv != DHTLIB_OK)
53
+    {
54
+        humidity    = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
55
+        temperature = DHTLIB_INVALID_VALUE; // invalid value
56
+        return rv;
57
+    }
58
+
59
+    // CONVERT AND STORE
60
+    humidity = bits[0] + bits[1] * 0.1;
61
+    temperature = (bits[2] & 0x7F) + bits[3] * 0.1;
62
+    if (bits[2] & 0x80)  // negative temperature
63
+    {
64
+        temperature = -temperature;
65
+    }
66
+
67
+    // TEST CHECKSUM
68
+    uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];
69
+    if (bits[4] != sum)
70
+    {
71
+      return DHTLIB_ERROR_CHECKSUM;
72
+    }
73
+    return DHTLIB_OK;
74
+}
75
+
76
+// return values:
77
+// DHTLIB_OK
78
+// DHTLIB_ERROR_CHECKSUM
79
+// DHTLIB_ERROR_TIMEOUT
80
+int dht::read(uint8_t pin)
81
+{
82
+    // READ VALUES
83
+    if (_disableIRQ) noInterrupts();
84
+    int rv = _readSensor(pin, DHTLIB_DHT_WAKEUP);
85
+    if (_disableIRQ) interrupts();
86
+    if (rv != DHTLIB_OK)
87
+    {
88
+        humidity    = DHTLIB_INVALID_VALUE;  // NaN prefered?
89
+        temperature = DHTLIB_INVALID_VALUE;  // NaN prefered?
90
+        return rv; // propagate error value
91
+    }
92
+
93
+    // CONVERT AND STORE
94
+    humidity = word(bits[0], bits[1]) * 0.1;
95
+    temperature = word(bits[2] & 0x7F, bits[3]) * 0.1;
96
+    if (bits[2] & 0x80)  // negative temperature
97
+    {
98
+        temperature = -temperature;
99
+    }
100
+
101
+    // TEST CHECKSUM
102
+    uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];
103
+    if (bits[4] != sum)
104
+    {
105
+        return DHTLIB_ERROR_CHECKSUM;
106
+    }
107
+    return DHTLIB_OK;
108
+}
109
+
110
+/////////////////////////////////////////////////////
111
+//
112
+// PRIVATE
113
+//
114
+
115
+// return values:
116
+// DHTLIB_OK
117
+// DHTLIB_ERROR_TIMEOUT
118
+int dht::_readSensor(uint8_t pin, uint8_t wakeupDelay)
119
+{
120
+    // INIT BUFFERVAR TO RECEIVE DATA
121
+    uint8_t mask = 128;
122
+    uint8_t idx = 0;
123
+
124
+    // EMPTY BUFFER
125
+    for (uint8_t i = 0; i < 5; i++) bits[i] = 0;
126
+
127
+    // REQUEST SAMPLE
128
+    pinMode(pin, OUTPUT);
129
+    digitalWrite(pin, LOW);
130
+    delay(wakeupDelay);
131
+    pinMode(pin, INPUT);
132
+    delayMicroseconds(40);
133
+
134
+    // GET ACKNOWLEDGE or TIMEOUT
135
+    uint16_t loopCnt = DHTLIB_TIMEOUT;
136
+    while(digitalRead(pin) == LOW)
137
+    {
138
+        if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;
139
+    }
140
+
141
+    loopCnt = DHTLIB_TIMEOUT;
142
+    while(digitalRead(pin) == HIGH)
143
+    {
144
+        if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;
145
+    }
146
+
147
+    // READ THE OUTPUT - 40 BITS => 5 BYTES
148
+    for (uint8_t i = 40; i != 0; i--)
149
+    {
150
+        loopCnt = DHTLIB_TIMEOUT;
151
+        while(digitalRead(pin) == LOW)
152
+        {
153
+            if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;
154
+        }
155
+
156
+        uint32_t t = micros();
157
+
158
+        loopCnt = DHTLIB_TIMEOUT;
159
+        while(digitalRead(pin) == HIGH)
160
+        {
161
+            if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;
162
+        }
163
+
164
+        if ((micros() - t) > 40)
165
+        {
166
+            bits[idx] |= mask;
167
+        }
168
+        mask >>= 1;
169
+        if (mask == 0)   // next byte?
170
+        {
171
+            mask = 128;
172
+            idx++;
173
+        }
174
+    }
175
+
176
+    return DHTLIB_OK;
177
+}
178
+//
179
+// END OF FILE
180
+//

+ 72
- 0
ClimateControl/lib/DHTStable_ID1337/dht.h View File

@@ -0,0 +1,72 @@
1
+//
2
+//    FILE: dht.h
3
+//  AUTHOR: Rob Tillaart
4
+// VERSION: 0.2.4
5
+// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
6
+//     URL: https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable
7
+//
8
+// HISTORY:
9
+// see dht.cpp file
10
+//
11
+
12
+#ifndef dht_h
13
+#define dht_h
14
+
15
+#if ARDUINO < 100
16
+#include <WProgram.h>
17
+#else
18
+#include <Arduino.h>
19
+#endif
20
+
21
+#define DHT_LIB_VERSION "0.2.3 - dhtstable"
22
+
23
+const int DHTLIB_OK              = 0;
24
+const int DHTLIB_ERROR_CHECKSUM  = -1;
25
+const int DHTLIB_ERROR_TIMEOUT   = -2;
26
+const int DHTLIB_INVALID_VALUE   = -999;
27
+
28
+const int DHTLIB_DHT11_WAKEUP    = 18;
29
+const int DHTLIB_DHT_WAKEUP      = 1;
30
+
31
+// max timeout is 100usec.
32
+// For a 16Mhz proc that is max 1600 clock cycles
33
+// loops using TIMEOUT use at least 4 clock cycli
34
+// so 100 us takes max 400 loops
35
+// so by dividing F_CPU by 40000 we "fail" as fast as possible
36
+const int DHTLIB_TIMEOUT = (F_CPU/40000);
37
+
38
+class dht
39
+{
40
+public:
41
+    // return values:
42
+    // DHTLIB_OK
43
+    // DHTLIB_ERROR_CHECKSUM
44
+    // DHTLIB_ERROR_TIMEOUT
45
+    int read11(uint8_t pin);      // DHT11 & DHT12
46
+    int read(uint8_t pin);        // DHT22
47
+
48
+    inline int read12(uint8_t pin)   { return read11(pin); }; // ok
49
+    inline int read21(uint8_t pin)   { return read(pin); };   // ok
50
+    inline int read22(uint8_t pin)   { return read(pin); };   // ok
51
+    inline int read33(uint8_t pin)   { return read(pin); };   // ok
52
+    inline int read44(uint8_t pin)   { return read(pin); };   // ok
53
+    inline int read2301(uint8_t pin) { return read(pin); };   // ok
54
+    inline int read2302(uint8_t pin) { return read(pin); };   // ok
55
+    inline int read2320(uint8_t pin) { return read(pin); };   //.ok
56
+    inline int read2322(uint8_t pin) { return read(pin); };   // ok
57
+
58
+    float humidity;
59
+    float temperature;
60
+
61
+    bool getDisableIRQ()              { return _disableIRQ; };
62
+    void setDisableIRQ(bool b )       { _disableIRQ = b; };
63
+
64
+private:
65
+    uint8_t bits[5];  // buffer to receive data
66
+    int     _readSensor(uint8_t pin, uint8_t wakeupDelay);
67
+    bool    _disableIRQ = false;
68
+};
69
+#endif
70
+//
71
+// END OF FILE
72
+//

+ 56
- 0
ClimateControl/lib/DHTStable_ID1337/examples/dht11_test/dht11_test.ino View File

@@ -0,0 +1,56 @@
1
+//
2
+//    FILE: dht11_test.ino
3
+//  AUTHOR: Rob Tillaart
4
+// VERSION: 0.1.01
5
+// PURPOSE: DHT library test sketch for DHT11 && Arduino
6
+//     URL:
7
+//
8
+// Released to the public domain
9
+//
10
+
11
+#include <dht.h>
12
+
13
+dht DHT;
14
+
15
+#define DHT11_PIN 5
16
+
17
+void setup()
18
+{
19
+  Serial.begin(115200);
20
+  Serial.println("DHT TEST PROGRAM ");
21
+  Serial.print("LIBRARY VERSION: ");
22
+  Serial.println(DHT_LIB_VERSION);
23
+  Serial.println();
24
+  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
25
+}
26
+
27
+void loop()
28
+{
29
+  // READ DATA
30
+  Serial.print("DHT11, \t");
31
+  int chk = DHT.read11(DHT11_PIN);
32
+  switch (chk)
33
+  {
34
+    case DHTLIB_OK:  
35
+		Serial.print("OK,\t"); 
36
+		break;
37
+    case DHTLIB_ERROR_CHECKSUM: 
38
+		Serial.print("Checksum error,\t"); 
39
+		break;
40
+    case DHTLIB_ERROR_TIMEOUT: 
41
+		Serial.print("Time out error,\t"); 
42
+		break;
43
+    default: 
44
+		Serial.print("Unknown error,\t"); 
45
+		break;
46
+  }
47
+  // DISPLAY DATA
48
+  Serial.print(DHT.humidity, 1);
49
+  Serial.print(",\t");
50
+  Serial.println(DHT.temperature, 1);
51
+
52
+  delay(2000);
53
+}
54
+//
55
+// END OF FILE
56
+//

+ 56
- 0
ClimateControl/lib/DHTStable_ID1337/examples/dht12_test/dht12_test.ino View File

@@ -0,0 +1,56 @@
1
+//
2
+//    FILE: dht12_test.ino
3
+//  AUTHOR: Rob Tillaart
4
+// VERSION: 0.1.0
5
+// PURPOSE: DHT library test sketch for DHT12 && Arduino
6
+//     URL:
7
+//
8
+// Released to the public domain
9
+//
10
+
11
+#include <dht.h>
12
+
13
+dht DHT;
14
+
15
+#define DHT12_PIN 5
16
+
17
+void setup()
18
+{
19
+  Serial.begin(115200);
20
+  Serial.println("DHT TEST PROGRAM ");
21
+  Serial.print("LIBRARY VERSION: ");
22
+  Serial.println(DHT_LIB_VERSION);
23
+  Serial.println();
24
+  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
25
+}
26
+
27
+void loop()
28
+{
29
+  // READ DATA
30
+  Serial.print("DHT12, \t");
31
+  int chk = DHT.read12(DHT12_PIN);
32
+  switch (chk)
33
+  {
34
+    case DHTLIB_OK:  
35
+		Serial.print("OK,\t"); 
36
+		break;
37
+    case DHTLIB_ERROR_CHECKSUM: 
38
+		Serial.print("Checksum error,\t"); 
39
+		break;
40
+    case DHTLIB_ERROR_TIMEOUT: 
41
+		Serial.print("Time out error,\t"); 
42
+		break;
43
+    default: 
44
+		Serial.print("Unknown error,\t"); 
45
+		break;
46
+  }
47
+  // DISPLAY DATA
48
+  Serial.print(DHT.humidity, 1);
49
+  Serial.print(",\t");
50
+  Serial.println(DHT.temperature, 1);
51
+
52
+  delay(2000);
53
+}
54
+//
55
+// END OF FILE
56
+//

+ 105
- 0
ClimateControl/lib/DHTStable_ID1337/examples/dht22_test/dht22_test.ino View File

@@ -0,0 +1,105 @@
1
+//
2
+//    FILE: dht22_test.ino
3
+//  AUTHOR: Rob Tillaart
4
+// VERSION: 0.1.03
5
+// PURPOSE: DHT library test sketch for DHT22 && Arduino
6
+//     URL:
7
+// HISTORY:
8
+// 0.1.03 extended stats for all errors
9
+// 0.1.02 added counters for error-regression testing.
10
+// 0.1.01
11
+// 0.1.00 initial version
12
+//
13
+// Released to the public domain
14
+//
15
+
16
+#include <dht.h>
17
+
18
+dht DHT;
19
+
20
+#define DHT22_PIN 5
21
+
22
+struct
23
+{
24
+    uint32_t total;
25
+    uint32_t ok;
26
+    uint32_t crc_error;
27
+    uint32_t time_out;
28
+    uint32_t connect;
29
+    uint32_t ack_l;
30
+    uint32_t ack_h;
31
+    uint32_t unknown;
32
+} stat = { 0,0,0,0,0,0,0,0};
33
+
34
+void setup()
35
+{
36
+    Serial.begin(115200);
37
+    Serial.println("dht22_test.ino");
38
+    Serial.print("LIBRARY VERSION: ");
39
+    Serial.println(DHT_LIB_VERSION);
40
+    Serial.println();
41
+    Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)\tTime (us)");
42
+}
43
+
44
+void loop()
45
+{
46
+    // READ DATA
47
+    Serial.print("DHT22, \t");
48
+
49
+    uint32_t start = micros();
50
+    int chk = DHT.read22(DHT22_PIN);
51
+    uint32_t stop = micros();
52
+
53
+    stat.total++;
54
+    switch (chk)
55
+    {
56
+    case DHTLIB_OK:
57
+        stat.ok++;
58
+        Serial.print("OK,\t");
59
+        break;
60
+    case DHTLIB_ERROR_CHECKSUM:
61
+        stat.crc_error++;
62
+        Serial.print("Checksum error,\t");
63
+        break;
64
+    case DHTLIB_ERROR_TIMEOUT:
65
+        stat.time_out++;
66
+        Serial.print("Time out error,\t");
67
+        break;
68
+    default:
69
+        stat.unknown++;
70
+        Serial.print("Unknown error,\t");
71
+        break;
72
+    }
73
+    // DISPLAY DATA
74
+    Serial.print(DHT.humidity, 1);
75
+    Serial.print(",\t");
76
+    Serial.print(DHT.temperature, 1);
77
+    Serial.print(",\t");
78
+    Serial.print(stop - start);
79
+    Serial.println();
80
+
81
+    if (stat.total % 20 == 0)
82
+    {
83
+        Serial.println("\nTOT\tOK\tCRC\tTO\tUNK");
84
+        Serial.print(stat.total);
85
+        Serial.print("\t");
86
+        Serial.print(stat.ok);
87
+        Serial.print("\t");
88
+        Serial.print(stat.crc_error);
89
+        Serial.print("\t");
90
+        Serial.print(stat.time_out);
91
+        Serial.print("\t");
92
+        Serial.print(stat.connect);
93
+        Serial.print("\t");
94
+        Serial.print(stat.ack_l);
95
+        Serial.print("\t");
96
+        Serial.print(stat.ack_h);
97
+        Serial.print("\t");
98
+        Serial.print(stat.unknown);
99
+        Serial.println("\n");
100
+    }
101
+    delay(2000);
102
+}
103
+//
104
+// END OF FILE
105
+//

+ 2
- 0
ClimateControl/lib/DHTStable_ID1337/examples/readme.txt View File

@@ -0,0 +1,2 @@
1
+2015-08-20 these examples are retrofitted from version 0.1.20 which supports more errors.
2
+

+ 37
- 0
ClimateControl/lib/DHTStable_ID1337/keywords.txt View File

@@ -0,0 +1,37 @@
1
+#######################################
2
+# Syntax Coloring Map For DHT
3
+#######################################
4
+
5
+#######################################
6
+# Datatypes (KEYWORD1)
7
+#######################################
8
+
9
+DHT	KEYWORD1
10
+
11
+#######################################
12
+# Methods and Functions (KEYWORD2)
13
+#######################################
14
+
15
+read	KEYWORD2
16
+read11	KEYWORD2
17
+read12	KEYWORD2
18
+read21	KEYWORD2
19
+read22	KEYWORD2
20
+read33	KEYWORD2
21
+read44	KEYWORD2
22
+read2301	KEYWORD2
23
+read2302	KEYWORD2
24
+read2320	KEYWORD2
25
+read2322	KEYWORD2
26
+humidity	KEYWORD2
27
+temperature	KEYWORD2
28
+
29
+#######################################
30
+# Instances (KEYWORD2)
31
+#######################################
32
+
33
+
34
+#######################################
35
+# Constants (LITERAL1)
36
+#######################################
37
+

+ 24
- 0
ClimateControl/lib/DHTStable_ID1337/library.json View File

@@ -0,0 +1,24 @@
1
+{
2
+  "name": "DHTStable",
3
+  "keywords": "DHT11,DHT22,DHT33,DHT44,AM2301,AM2302,AM2303",
4
+  "description": "Stable version of the library for DHT Temperature & Humidity Sensor.",
5
+  "authors":
6
+  [
7
+    {
8
+      "name": "Rob Tillaart",
9
+      "email": "Rob.Tillaart@gmail.com",
10
+      "maintainer": true
11
+    }
12
+  ],
13
+  "repository":
14
+  {
15
+    "type": "git",
16
+    "url": "https://github.com/RobTillaart/Arduino.git"
17
+  },
18
+  "version":"0.2.4",
19
+  "frameworks": "arduino",
20
+  "platforms": "atmelavr",
21
+  "export": {
22
+    "include": "libraries/DHTstable"
23
+  }
24
+}

+ 9
- 0
ClimateControl/lib/DHTStable_ID1337/library.properties View File

@@ -0,0 +1,9 @@
1
+name=DHTStable
2
+version=0.2.4
3
+author=Rob Tillaart <rob.tillaart@gmail.com>
4
+maintainer=Rob Tillaart <rob.tillaart@gmail.com>
5
+sentence=Stable version of library for DHT Temperature & Humidity Sensor 
6
+paragraph= 
7
+category=Sensors
8
+url=https://github.com/RobTillaart/Arduino/tree/master/libraries/
9
+architectures=*

+ 13
- 0
ClimateControl/lib/DHTStable_ID1337/readme.md View File

@@ -0,0 +1,13 @@
1
+
2
+This is the 0.2.3 version of the DHTlib.
3
+This version is stable for both ARM and AVR.
4
+
5
+You can use most examples from https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib/examples
6
+
7
+update 2015-10-12:
8
+For multithreading environments for Arduino one could replace
9
+    delay(wakeupDelay);
10
+with
11
+    delayMicroseconds(wakeupDelay * 1000UL);
12
+see also - https://github.com/RobTillaart/Arduino/pull/25 -
13
+

+ 1
- 0
ClimateControl/lib/PubSubClient_ID89/.gitignore View File

@@ -0,0 +1 @@
1
+tests/bin

+ 35
- 0
ClimateControl/lib/PubSubClient_ID89/.library.json View File

@@ -0,0 +1,35 @@
1
+{
2
+    "name": "PubSubClient", 
3
+    "keywords": [
4
+        "ethernet", 
5
+        "mqtt", 
6
+        "m2m", 
7
+        "iot"
8
+    ], 
9
+    "description": "A client library for MQTT messaging. MQTT is a lightweight messaging protocol ideal for small devices. This library allows you to send and receive MQTT messages. It supports the latest MQTT 3.1.1 protocol and can be configured to use the older MQTT 3.1 if needed. It supports all Arduino Ethernet Client compatible hardware, including the Intel Galileo/Edison, ESP8266 and TI CC3000.", 
10
+    "repository": {
11
+        "type": "git", 
12
+        "url": "https://github.com/knolleary/pubsubclient.git"
13
+    }, 
14
+    "version": "2.7", 
15
+    "examples": "examples/*/*.ino", 
16
+    "frameworks": [
17
+        "arduino"
18
+    ], 
19
+    "platforms": [
20
+        "atmelavr", 
21
+        "espressif8266"
22
+    ], 
23
+    "export": {
24
+        "exclude": "tests"
25
+    }, 
26
+    "authors": [
27
+        {
28
+            "email": "nick.oleary@gmail.com", 
29
+            "url": "https://github.com/knolleary", 
30
+            "maintainer": false, 
31
+            "name": "Nick O'Leary"
32
+        }
33
+    ], 
34
+    "id": 89
35
+}

+ 7
- 0
ClimateControl/lib/PubSubClient_ID89/.travis.yml View File

@@ -0,0 +1,7 @@
1
+sudo: false
2
+language: cpp
3
+compiler:
4
+  - g++
5
+script: cd tests && make && make test
6
+os:
7
+  - linux

+ 76
- 0
ClimateControl/lib/PubSubClient_ID89/CHANGES.txt View File

@@ -0,0 +1,76 @@
1
+2.7
2
+   * Fix remaining-length handling to prevent buffer overrun
3
+   * Add large-payload API - beginPublish/write/publish/endPublish
4
+   * Add yield call to improve reliability on ESP
5
+   * Add Clean Session flag to connect options
6
+   * Add ESP32 support for functional callback signature
7
+   * Various other fixes
8
+
9
+2.4
10
+   * Add MQTT_SOCKET_TIMEOUT to prevent it blocking indefinitely
11
+     whilst waiting for inbound data
12
+   * Fixed return code when publishing >256 bytes
13
+
14
+2.3
15
+   * Add publish(topic,payload,retained) function
16
+
17
+2.2
18
+   * Change code layout to match Arduino Library reqs
19
+
20
+2.1
21
+   * Add MAX_TRANSFER_SIZE def to chunk messages if needed
22
+   * Reject topic/payloads that exceed MQTT_MAX_PACKET_SIZE
23
+
24
+2.0
25
+   * Add (and default to) MQTT 3.1.1 support
26
+   * Fix PROGMEM handling for Intel Galileo/ESP8266
27
+   * Add overloaded constructors for convenience
28
+   * Add chainable setters for server/callback/client/stream
29
+   * Add state function to return connack return code
30
+
31
+1.9
32
+   * Do not split MQTT packets over multiple calls to _client->write()
33
+   * API change: All constructors now require an instance of Client
34
+      to be passed in.
35
+   * Fixed example to match 1.8 api changes - dpslwk
36
+   * Added username/password support - WilHall
37
+   * Added publish_P - publishes messages from PROGMEM - jobytaffey
38
+
39
+1.8
40
+    * KeepAlive interval is configurable in PubSubClient.h
41
+    * Maximum packet size is configurable in PubSubClient.h
42
+    * API change: Return boolean rather than int from various functions
43
+    * API change: Length parameter in message callback changed
44
+       from int to unsigned int
45
+    * Various internal tidy-ups around types
46
+1.7
47
+    * Improved keepalive handling
48
+    * Updated to the Arduino-1.0 API
49
+1.6
50
+    * Added the ability to publish a retained message
51
+
52
+1.5
53
+    * Added default constructor
54
+    * Fixed compile error when used with arduino-0021 or later
55
+
56
+1.4
57
+    * Fixed connection lost handling
58
+
59
+1.3
60
+    * Fixed packet reading bug in PubSubClient.readPacket
61
+
62
+1.2
63
+    * Fixed compile error when used with arduino-0016 or later
64
+
65
+
66
+1.1
67
+    * Reduced size of library
68
+    * Added support for Will messages
69
+    * Clarified licensing - see LICENSE.txt
70
+
71
+
72
+1.0
73
+    * Only Quality of Service (QOS) 0 messaging is supported
74
+    * The maximum message size, including header, is 128 bytes
75
+    * The keepalive interval is set to 30 seconds
76
+    * No support for Will messages

+ 20
- 0
ClimateControl/lib/PubSubClient_ID89/LICENSE.txt View File

@@ -0,0 +1,20 @@
1
+Copyright (c) 2008-2015 Nicholas O'Leary
2
+
3
+Permission is hereby granted, free of charge, to any person obtaining
4
+a copy of this software and associated documentation files (the
5
+"Software"), to deal in the Software without restriction, including
6
+without limitation the rights to use, copy, modify, merge, publish,
7
+distribute, sublicense, and/or sell copies of the Software, and to
8
+permit persons to whom the Software is furnished to do so, subject to
9
+the following conditions:
10
+
11
+The above copyright notice and this permission notice shall be
12
+included in all copies or substantial portions of the Software.
13
+
14
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 48
- 0
ClimateControl/lib/PubSubClient_ID89/README.md View File

@@ -0,0 +1,48 @@
1
+# Arduino Client for MQTT
2
+
3
+This library provides a client for doing simple publish/subscribe messaging with
4
+a server that supports MQTT.
5
+
6
+## Examples
7
+
8
+The library comes with a number of example sketches. See File > Examples > PubSubClient
9
+within the Arduino application.
10
+
11
+Full API documentation is available here: https://pubsubclient.knolleary.net
12
+
13
+## Limitations
14
+
15
+ - It can only publish QoS 0 messages. It can subscribe at QoS 0 or QoS 1.
16
+ - The maximum message size, including header, is **128 bytes** by default. This
17
+   is configurable via `MQTT_MAX_PACKET_SIZE` in `PubSubClient.h`.
18
+ - The keepalive interval is set to 15 seconds by default. This is configurable
19
+   via `MQTT_KEEPALIVE` in `PubSubClient.h`.
20
+ - The client uses MQTT 3.1.1 by default. It can be changed to use MQTT 3.1 by
21
+   changing value of `MQTT_VERSION` in `PubSubClient.h`.
22
+
23
+
24
+## Compatible Hardware
25
+
26
+The library uses the Arduino Ethernet Client api for interacting with the
27
+underlying network hardware. This means it Just Works with a growing number of
28
+boards and shields, including:
29
+
30
+ - Arduino Ethernet
31
+ - Arduino Ethernet Shield
32
+ - Arduino YUN โ€“ use the included `YunClient` in place of `EthernetClient`, and
33
+   be sure to do a `Bridge.begin()` first
34
+ - Arduino WiFi Shield - if you want to send packets > 90 bytes with this shield,
35
+   enable the `MQTT_MAX_TRANSFER_SIZE` define in `PubSubClient.h`.
36
+ - Sparkfun WiFly Shield โ€“ [library](https://github.com/dpslwk/WiFly)
37
+ - TI CC3000 WiFi - [library](https://github.com/sparkfun/SFE_CC3000_Library)
38
+ - Intel Galileo/Edison
39
+ - ESP8266
40
+ - ESP32
41
+
42
+The library cannot currently be used with hardware based on the ENC28J60 chip โ€“
43
+such as the Nanode or the Nuelectronics Ethernet Shield. For those, there is an
44
+[alternative library](https://github.com/njh/NanodeMQTT) available.
45
+
46
+## License
47
+
48
+This code is released under the MIT License.

+ 43
- 0
ClimateControl/lib/PubSubClient_ID89/examples/mqtt_auth/mqtt_auth.ino View File

@@ -0,0 +1,43 @@
1
+/*
2
+ Basic MQTT example with Authentication
3
+
4
+  - connects to an MQTT server, providing username
5
+    and password
6
+  - publishes "hello world" to the topic "outTopic"
7
+  - subscribes to the topic "inTopic"
8
+*/
9
+
10
+#include <SPI.h>
11
+#include <Ethernet.h>
12
+#include <PubSubClient.h>
13
+
14
+// Update these with values suitable for your network.
15
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
16
+IPAddress ip(172, 16, 0, 100);
17
+IPAddress server(172, 16, 0, 2);
18
+
19
+void callback(char* topic, byte* payload, unsigned int length) {
20
+  // handle message arrived
21
+}
22
+
23
+EthernetClient ethClient;
24
+PubSubClient client(server, 1883, callback, ethClient);
25
+
26
+void setup()
27
+{
28
+  Ethernet.begin(mac, ip);
29
+  // Note - the default maximum packet size is 128 bytes. If the
30
+  // combined length of clientId, username and password exceed this,
31
+  // you will need to increase the value of MQTT_MAX_PACKET_SIZE in
32
+  // PubSubClient.h
33
+  
34
+  if (client.connect("arduinoClient", "testuser", "testpass")) {
35
+    client.publish("outTopic","hello world");
36
+    client.subscribe("inTopic");
37
+  }
38
+}
39
+
40
+void loop()
41
+{
42
+  client.loop();
43
+}

+ 77
- 0
ClimateControl/lib/PubSubClient_ID89/examples/mqtt_basic/mqtt_basic.ino View File

@@ -0,0 +1,77 @@
1
+/*
2
+ Basic MQTT example
3
+
4
+ This sketch demonstrates the basic capabilities of the library.
5
+ It connects to an MQTT server then:
6
+  - publishes "hello world" to the topic "outTopic"
7
+  - subscribes to the topic "inTopic", printing out any messages
8
+    it receives. NB - it assumes the received payloads are strings not binary
9
+
10
+ It will reconnect to the server if the connection is lost using a blocking
11
+ reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
12
+ achieve the same result without blocking the main loop.
13
+ 
14
+*/
15
+
16
+#include <SPI.h>
17
+#include <Ethernet.h>
18
+#include <PubSubClient.h>
19
+
20
+// Update these with values suitable for your network.
21
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
22
+IPAddress ip(172, 16, 0, 100);
23
+IPAddress server(172, 16, 0, 2);
24
+
25
+void callback(char* topic, byte* payload, unsigned int length) {
26
+  Serial.print("Message arrived [");
27
+  Serial.print(topic);
28
+  Serial.print("] ");
29
+  for (int i=0;i<length;i++) {
30
+    Serial.print((char)payload[i]);
31
+  }
32
+  Serial.println();
33
+}
34
+
35
+EthernetClient ethClient;
36
+PubSubClient client(ethClient);
37
+
38
+void reconnect() {
39
+  // Loop until we're reconnected
40
+  while (!client.connected()) {
41
+    Serial.print("Attempting MQTT connection...");
42
+    // Attempt to connect
43
+    if (client.connect("arduinoClient")) {
44
+      Serial.println("connected");
45
+      // Once connected, publish an announcement...
46
+      client.publish("outTopic","hello world");
47
+      // ... and resubscribe
48
+      client.subscribe("inTopic");
49
+    } else {
50
+      Serial.print("failed, rc=");
51
+      Serial.print(client.state());
52
+      Serial.println(" try again in 5 seconds");
53
+      // Wait 5 seconds before retrying
54
+      delay(5000);
55
+    }
56
+  }
57
+}
58
+
59
+void setup()
60
+{
61
+  Serial.begin(57600);
62
+
63
+  client.setServer(server, 1883);
64
+  client.setCallback(callback);
65
+
66
+  Ethernet.begin(mac, ip);
67
+  // Allow the hardware to sort itself out
68
+  delay(1500);
69
+}
70
+
71
+void loop()
72
+{
73
+  if (!client.connected()) {
74
+    reconnect();
75
+  }
76
+  client.loop();
77
+}

+ 132
- 0
ClimateControl/lib/PubSubClient_ID89/examples/mqtt_esp8266/mqtt_esp8266.ino View File

@@ -0,0 +1,132 @@
1
+/*
2
+ Basic ESP8266 MQTT example
3
+
4
+ This sketch demonstrates the capabilities of the pubsub library in combination
5
+ with the ESP8266 board/library.
6
+
7
+ It connects to an MQTT server then:
8
+  - publishes "hello world" to the topic "outTopic" every two seconds
9
+  - subscribes to the topic "inTopic", printing out any messages
10
+    it receives. NB - it assumes the received payloads are strings not binary
11
+  - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
12
+    else switch it off
13
+
14
+ It will reconnect to the server if the connection is lost using a blocking
15
+ reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
16
+ achieve the same result without blocking the main loop.
17
+
18
+ To install the ESP8266 board, (using Arduino 1.6.4+):
19
+  - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
20
+       http://arduino.esp8266.com/stable/package_esp8266com_index.json
21
+  - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
22
+  - Select your ESP8266 in "Tools -> Board"
23
+
24
+*/
25
+
26
+#include <ESP8266WiFi.h>
27
+#include <PubSubClient.h>
28
+
29
+// Update these with values suitable for your network.
30
+
31
+const char* ssid = "........";
32
+const char* password = "........";
33
+const char* mqtt_server = "broker.mqtt-dashboard.com";
34
+
35
+WiFiClient espClient;
36
+PubSubClient client(espClient);
37
+long lastMsg = 0;
38
+char msg[50];
39
+int value = 0;
40
+
41
+void setup_wifi() {
42
+
43
+  delay(10);
44
+  // We start by connecting to a WiFi network
45
+  Serial.println();
46
+  Serial.print("Connecting to ");
47
+  Serial.println(ssid);
48
+
49
+  WiFi.begin(ssid, password);
50
+
51
+  while (WiFi.status() != WL_CONNECTED) {
52
+    delay(500);
53
+    Serial.print(".");
54
+  }
55
+
56
+  randomSeed(micros());
57
+
58
+  Serial.println("");
59
+  Serial.println("WiFi connected");
60
+  Serial.println("IP address: ");
61
+  Serial.println(WiFi.localIP());
62
+}
63
+
64
+void callback(char* topic, byte* payload, unsigned int length) {
65
+  Serial.print("Message arrived [");
66
+  Serial.print(topic);
67
+  Serial.print("] ");
68
+  for (int i = 0; i < length; i++) {
69
+    Serial.print((char)payload[i]);
70
+  }
71
+  Serial.println();
72
+
73
+  // Switch on the LED if an 1 was received as first character
74
+  if ((char)payload[0] == '1') {
75
+    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
76
+    // but actually the LED is on; this is because
77
+    // it is active low on the ESP-01)
78
+  } else {
79
+    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
80
+  }
81
+
82
+}
83
+
84
+void reconnect() {
85
+  // Loop until we're reconnected
86
+  while (!client.connected()) {
87
+    Serial.print("Attempting MQTT connection...");
88
+    // Create a random client ID
89
+    String clientId = "ESP8266Client-";
90
+    clientId += String(random(0xffff), HEX);
91
+    // Attempt to connect
92
+    if (client.connect(clientId.c_str())) {
93
+      Serial.println("connected");
94
+      // Once connected, publish an announcement...
95
+      client.publish("outTopic", "hello world");
96
+      // ... and resubscribe
97
+      client.subscribe("inTopic");
98
+    } else {
99
+      Serial.print("failed, rc=");
100
+      Serial.print(client.state());
101
+      Serial.println(" try again in 5 seconds");
102
+      // Wait 5 seconds before retrying
103
+      delay(5000);
104
+    }
105
+  }
106
+}
107
+
108
+void setup() {
109
+  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
110
+  Serial.begin(115200);
111
+  setup_wifi();
112
+  client.setServer(mqtt_server, 1883);
113
+  client.setCallback(callback);
114
+}
115
+
116
+void loop() {
117
+
118
+  if (!client.connected()) {
119
+    reconnect();
120
+  }
121
+  client.loop();
122
+
123
+  long now = millis();
124
+  if (now - lastMsg > 2000) {
125
+    lastMsg = now;
126
+    ++value;
127
+    snprintf (msg, 50, "hello world #%ld", value);
128
+    Serial.print("Publish message: ");
129
+    Serial.println(msg);
130
+    client.publish("outTopic", msg);
131
+  }
132
+}

+ 179
- 0
ClimateControl/lib/PubSubClient_ID89/examples/mqtt_large_message/mqtt_large_message.ino View File

@@ -0,0 +1,179 @@
1
+/*
2
+ Long message ESP8266 MQTT example
3
+
4
+ This sketch demonstrates sending arbitrarily large messages in combination
5
+ with the ESP8266 board/library.
6
+
7
+ It connects to an MQTT server then:
8
+  - publishes "hello world" to the topic "outTopic"
9
+  - subscribes to the topic "greenBottles/#", printing out any messages
10
+    it receives. NB - it assumes the received payloads are strings not binary
11
+  - If the sub-topic is a number, it publishes a "greenBottles/lyrics" message
12
+    with a payload consisting of the lyrics to "10 green bottles", replacing
13
+    10 with the number given in the sub-topic.
14
+
15
+ It will reconnect to the server if the connection is lost using a blocking
16
+ reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
17
+ achieve the same result without blocking the main loop.
18
+
19
+ To install the ESP8266 board, (using Arduino 1.6.4+):
20
+  - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
21
+       http://arduino.esp8266.com/stable/package_esp8266com_index.json
22
+  - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
23
+  - Select your ESP8266 in "Tools -> Board"
24
+
25
+*/
26
+
27
+#include <ESP8266WiFi.h>
28
+#include <PubSubClient.h>
29
+
30
+// Update these with values suitable for your network.
31
+
32
+const char* ssid = "........";
33
+const char* password = "........";
34
+const char* mqtt_server = "broker.mqtt-dashboard.com";
35
+
36
+WiFiClient espClient;
37
+PubSubClient client(espClient);
38
+long lastMsg = 0;
39
+char msg[50];
40
+int value = 0;
41
+
42
+void setup_wifi() {
43
+
44
+  delay(10);
45
+  // We start by connecting to a WiFi network
46
+  Serial.println();
47
+  Serial.print("Connecting to ");
48
+  Serial.println(ssid);
49
+
50
+  WiFi.begin(ssid, password);
51
+
52
+  while (WiFi.status() != WL_CONNECTED) {
53
+    delay(500);
54
+    Serial.print(".");
55
+  }
56
+
57
+  randomSeed(micros());
58
+
59
+  Serial.println("");
60
+  Serial.println("WiFi connected");
61
+  Serial.println("IP address: ");
62
+  Serial.println(WiFi.localIP());
63
+}
64
+
65
+void callback(char* topic, byte* payload, unsigned int length) {
66
+  Serial.print("Message arrived [");
67
+  Serial.print(topic);
68
+  Serial.print("] ");
69
+  for (int i = 0; i < length; i++) {
70
+    Serial.print((char)payload[i]);
71
+  }
72
+  Serial.println();
73
+
74
+  // Find out how many bottles we should generate lyrics for
75
+  String topicStr(topic);
76
+  int bottleCount = 0; // assume no bottles unless we correctly parse a value from the topic
77
+  if (topicStr.indexOf('/') >= 0) {
78
+    // The topic includes a '/', we'll try to read the number of bottles from just after that
79
+    topicStr.remove(0, topicStr.indexOf('/')+1);
80
+    // Now see if there's a number of bottles after the '/'
81
+    bottleCount = topicStr.toInt();
82
+  }
83
+
84
+  if (bottleCount > 0) {
85
+    // Work out how big our resulting message will be
86
+    int msgLen = 0;
87
+    for (int i = bottleCount; i > 0; i--) {
88
+      String numBottles(i);
89
+      msgLen += 2*numBottles.length();
90
+      if (i == 1) {
91
+        msgLen += 2*String(" green bottle, standing on the wall\n").length();
92
+      } else {
93
+        msgLen += 2*String(" green bottles, standing on the wall\n").length();
94
+      }
95
+      msgLen += String("And if one green bottle should accidentally fall\nThere'll be ").length();
96
+      switch (i) {
97
+      case 1:
98
+        msgLen += String("no green bottles, standing on the wall\n\n").length();
99
+        break;
100
+      case 2:
101
+        msgLen += String("1 green bottle, standing on the wall\n\n").length();
102
+        break;
103
+      default:
104
+        numBottles = i-1;
105
+        msgLen += numBottles.length();
106
+        msgLen += String(" green bottles, standing on the wall\n\n").length();
107
+        break;
108
+      };
109
+    }
110
+  
111
+    // Now we can start to publish the message
112
+    client.beginPublish("greenBottles/lyrics", msgLen, false);
113
+    for (int i = bottleCount; i > 0; i--) {
114
+      for (int j = 0; j < 2; j++) {
115
+        client.print(i);
116
+        if (i == 1) {
117
+          client.print(" green bottle, standing on the wall\n");
118
+        } else {
119
+          client.print(" green bottles, standing on the wall\n");
120
+        }
121
+      }
122
+      client.print("And if one green bottle should accidentally fall\nThere'll be ");
123
+      switch (i) {
124
+      case 1:
125
+        client.print("no green bottles, standing on the wall\n\n");
126
+        break;
127
+      case 2:
128
+        client.print("1 green bottle, standing on the wall\n\n");
129
+        break;
130
+      default:
131
+        client.print(i-1);
132
+        client.print(" green bottles, standing on the wall\n\n");
133
+        break;
134
+      };
135
+    }
136
+    // Now we're done!
137
+    client.endPublish();
138
+  }
139
+}
140
+
141
+void reconnect() {
142
+  // Loop until we're reconnected
143
+  while (!client.connected()) {
144
+    Serial.print("Attempting MQTT connection...");
145
+    // Create a random client ID
146
+    String clientId = "ESP8266Client-";
147
+    clientId += String(random(0xffff), HEX);
148
+    // Attempt to connect
149
+    if (client.connect(clientId.c_str())) {
150
+      Serial.println("connected");
151
+      // Once connected, publish an announcement...
152
+      client.publish("outTopic", "hello world");
153
+      // ... and resubscribe
154
+      client.subscribe("greenBottles/#");
155
+    } else {
156
+      Serial.print("failed, rc=");
157
+      Serial.print(client.state());
158
+      Serial.println(" try again in 5 seconds");
159
+      // Wait 5 seconds before retrying
160
+      delay(5000);
161
+    }
162
+  }
163
+}
164
+
165
+void setup() {
166
+  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
167
+  Serial.begin(115200);
168
+  setup_wifi();
169
+  client.setServer(mqtt_server, 1883);
170
+  client.setCallback(callback);
171
+}
172
+
173
+void loop() {
174
+
175
+  if (!client.connected()) {
176
+    reconnect();
177
+  }
178
+  client.loop();
179
+}

+ 60
- 0
ClimateControl/lib/PubSubClient_ID89/examples/mqtt_publish_in_callback/mqtt_publish_in_callback.ino View File

@@ -0,0 +1,60 @@
1
+/*
2
+ Publishing in the callback
3
+
4
+  - connects to an MQTT server
5
+  - subscribes to the topic "inTopic"
6
+  - when a message is received, republishes it to "outTopic"
7
+
8
+  This example shows how to publish messages within the
9
+  callback function. The callback function header needs to
10
+  be declared before the PubSubClient constructor and the
11
+  actual callback defined afterwards.
12
+  This ensures the client reference in the callback function
13
+  is valid.
14
+
15
+*/
16
+
17
+#include <SPI.h>
18
+#include <Ethernet.h>
19
+#include <PubSubClient.h>
20
+
21
+// Update these with values suitable for your network.
22
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
23
+IPAddress ip(172, 16, 0, 100);
24
+IPAddress server(172, 16, 0, 2);
25
+
26
+// Callback function header
27
+void callback(char* topic, byte* payload, unsigned int length);
28
+
29
+EthernetClient ethClient;
30
+PubSubClient client(server, 1883, callback, ethClient);
31
+
32
+// Callback function
33
+void callback(char* topic, byte* payload, unsigned int length) {
34
+  // In order to republish this payload, a copy must be made
35
+  // as the orignal payload buffer will be overwritten whilst
36
+  // constructing the PUBLISH packet.
37
+
38
+  // Allocate the correct amount of memory for the payload copy
39
+  byte* p = (byte*)malloc(length);
40
+  // Copy the payload to the new buffer
41
+  memcpy(p,payload,length);
42
+  client.publish("outTopic", p, length);
43
+  // Free the memory
44
+  free(p);
45
+}
46
+
47
+void setup()
48
+{
49
+
50
+  Ethernet.begin(mac, ip);
51
+  if (client.connect("arduinoClient")) {
52
+    client.publish("outTopic","hello world");
53
+    client.subscribe("inTopic");
54
+  }
55
+}
56
+
57
+void loop()
58
+{
59
+  client.loop();
60
+}

+ 67
- 0
ClimateControl/lib/PubSubClient_ID89/examples/mqtt_reconnect_nonblocking/mqtt_reconnect_nonblocking.ino View File

@@ -0,0 +1,67 @@
1
+/*
2
+ Reconnecting MQTT example - non-blocking
3
+
4
+ This sketch demonstrates how to keep the client connected
5
+ using a non-blocking reconnect function. If the client loses
6
+ its connection, it attempts to reconnect every 5 seconds
7
+ without blocking the main loop.
8
+
9
+*/
10
+
11
+#include <SPI.h>
12
+#include <Ethernet.h>
13
+#include <PubSubClient.h>
14
+
15
+// Update these with values suitable for your hardware/network.
16
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
17
+IPAddress ip(172, 16, 0, 100);
18
+IPAddress server(172, 16, 0, 2);
19
+
20
+void callback(char* topic, byte* payload, unsigned int length) {
21
+  // handle message arrived
22
+}
23
+
24
+EthernetClient ethClient;
25
+PubSubClient client(ethClient);
26
+
27
+long lastReconnectAttempt = 0;
28
+
29
+boolean reconnect() {
30
+  if (client.connect("arduinoClient")) {
31
+    // Once connected, publish an announcement...
32
+    client.publish("outTopic","hello world");
33
+    // ... and resubscribe
34
+    client.subscribe("inTopic");
35
+  }
36
+  return client.connected();
37
+}
38
+
39
+void setup()
40
+{
41
+  client.setServer(server, 1883);
42
+  client.setCallback(callback);
43
+
44
+  Ethernet.begin(mac, ip);
45
+  delay(1500);
46
+  lastReconnectAttempt = 0;
47
+}
48
+
49
+
50
+void loop()
51
+{
52
+  if (!client.connected()) {
53
+    long now = millis();
54
+    if (now - lastReconnectAttempt > 5000) {
55
+      lastReconnectAttempt = now;
56
+      // Attempt to reconnect
57
+      if (reconnect()) {
58
+        lastReconnectAttempt = 0;
59
+      }
60
+    }
61
+  } else {
62
+    // Client connected
63
+
64
+    client.loop();
65
+  }
66
+
67
+}

+ 57
- 0
ClimateControl/lib/PubSubClient_ID89/examples/mqtt_stream/mqtt_stream.ino View File

@@ -0,0 +1,57 @@
1
+/*
2
+ Example of using a Stream object to store the message payload
3
+
4
+ Uses SRAM library: https://github.com/ennui2342/arduino-sram
5
+ but could use any Stream based class such as SD
6
+
7
+  - connects to an MQTT server
8
+  - publishes "hello world" to the topic "outTopic"
9
+  - subscribes to the topic "inTopic"
10
+*/
11
+
12
+#include <SPI.h>
13
+#include <Ethernet.h>
14
+#include <PubSubClient.h>
15
+#include <SRAM.h>
16
+
17
+// Update these with values suitable for your network.
18
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
19
+IPAddress ip(172, 16, 0, 100);
20
+IPAddress server(172, 16, 0, 2);
21
+
22
+SRAM sram(4, SRAM_1024);
23
+
24
+void callback(char* topic, byte* payload, unsigned int length) {
25
+  sram.seek(1);
26
+
27
+  // do something with the message
28
+  for(uint8_t i=0; i<length; i++) {
29
+    Serial.write(sram.read());
30
+  }
31
+  Serial.println();
32
+
33
+  // Reset position for the next message to be stored
34
+  sram.seek(1);
35
+}
36
+
37
+EthernetClient ethClient;
38
+PubSubClient client(server, 1883, callback, ethClient, sram);
39
+
40
+void setup()
41
+{
42
+  Ethernet.begin(mac, ip);
43
+  if (client.connect("arduinoClient")) {
44
+    client.publish("outTopic","hello world");
45
+    client.subscribe("inTopic");
46
+  }
47
+
48
+  sram.begin();
49
+  sram.seek(1);
50
+
51
+  Serial.begin(9600);
52
+}
53
+
54
+void loop()
55
+{
56
+  client.loop();
57
+}

+ 33
- 0
ClimateControl/lib/PubSubClient_ID89/keywords.txt View File

@@ -0,0 +1,33 @@
1
+#######################################
2
+# Syntax Coloring Map For PubSubClient
3
+#######################################
4
+
5
+#######################################
6
+# Datatypes (KEYWORD1)
7
+#######################################
8
+
9
+PubSubClient	KEYWORD1
10
+
11
+#######################################
12
+# Methods and Functions (KEYWORD2)
13
+#######################################
14
+
15
+connect 	KEYWORD2
16
+disconnect 	KEYWORD2
17
+publish 	KEYWORD2
18
+publish_P 	KEYWORD2
19
+beginPublish 	KEYWORD2
20
+endPublish 	KEYWORD2
21
+write	 	KEYWORD2
22
+subscribe 	KEYWORD2
23
+unsubscribe 	KEYWORD2
24
+loop 	KEYWORD2
25
+connected 	KEYWORD2
26
+setServer	KEYWORD2
27
+setCallback	KEYWORD2
28
+setClient	KEYWORD2
29
+setStream	KEYWORD2
30
+
31
+#######################################
32
+# Constants (LITERAL1)
33
+#######################################

+ 17
- 0
ClimateControl/lib/PubSubClient_ID89/library.json View File

@@ -0,0 +1,17 @@
1
+{
2
+    "name": "PubSubClient",
3
+    "keywords": "ethernet, mqtt, m2m, iot",
4
+    "description": "A client library for MQTT messaging. MQTT is a lightweight messaging protocol ideal for small devices. This library allows you to send and receive MQTT messages. It supports the latest MQTT 3.1.1 protocol and can be configured to use the older MQTT 3.1 if needed. It supports all Arduino Ethernet Client compatible hardware, including the Intel Galileo/Edison, ESP8266 and TI CC3000.",
5
+    "repository": {
6
+        "type": "git",
7
+        "url": "https://github.com/knolleary/pubsubclient.git"
8
+    },
9
+    "version": "2.7",
10
+    "exclude": "tests",
11
+    "examples": "examples/*/*.ino",
12
+    "frameworks": "arduino",
13
+    "platforms": [
14
+        "atmelavr",
15
+        "espressif"
16
+    ]
17
+}

+ 9
- 0
ClimateControl/lib/PubSubClient_ID89/library.properties View File

@@ -0,0 +1,9 @@
1
+name=PubSubClient
2
+version=2.7
3
+author=Nick O'Leary <nick.oleary@gmail.com>
4
+maintainer=Nick O'Leary <nick.oleary@gmail.com>
5
+sentence=A client library for MQTT messaging.
6
+paragraph=MQTT is a lightweight messaging protocol ideal for small devices. This library allows you to send and receive MQTT messages. It supports the latest MQTT 3.1.1 protocol and can be configured to use the older MQTT 3.1 if needed. It supports all Arduino Ethernet Client compatible hardware, including the Intel Galileo/Edison, ESP8266 and TI CC3000.
7
+category=Communication
8
+url=http://pubsubclient.knolleary.net
9
+architectures=*

+ 653
- 0
ClimateControl/lib/PubSubClient_ID89/src/PubSubClient.cpp View File

@@ -0,0 +1,653 @@
1
+/*
2
+  PubSubClient.cpp - A simple client for MQTT.
3
+  Nick O'Leary
4
+  http://knolleary.net
5
+*/
6
+
7
+#include "PubSubClient.h"
8
+#include "Arduino.h"
9
+
10
+PubSubClient::PubSubClient() {
11
+    this->_state = MQTT_DISCONNECTED;
12
+    this->_client = NULL;
13
+    this->stream = NULL;
14
+    setCallback(NULL);
15
+}
16
+
17
+PubSubClient::PubSubClient(Client& client) {
18
+    this->_state = MQTT_DISCONNECTED;
19
+    setClient(client);
20
+    this->stream = NULL;
21
+}
22
+
23
+PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) {
24
+    this->_state = MQTT_DISCONNECTED;
25
+    setServer(addr, port);
26
+    setClient(client);
27
+    this->stream = NULL;
28
+}
29
+PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client, Stream& stream) {
30
+    this->_state = MQTT_DISCONNECTED;
31
+    setServer(addr,port);
32
+    setClient(client);
33
+    setStream(stream);
34
+}
35
+PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
36
+    this->_state = MQTT_DISCONNECTED;
37
+    setServer(addr, port);
38
+    setCallback(callback);
39
+    setClient(client);
40
+    this->stream = NULL;
41
+}
42
+PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
43
+    this->_state = MQTT_DISCONNECTED;
44
+    setServer(addr,port);
45
+    setCallback(callback);
46
+    setClient(client);
47
+    setStream(stream);
48
+}
49
+
50
+PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) {
51
+    this->_state = MQTT_DISCONNECTED;
52
+    setServer(ip, port);
53
+    setClient(client);
54
+    this->stream = NULL;
55
+}
56
+PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client, Stream& stream) {
57
+    this->_state = MQTT_DISCONNECTED;
58
+    setServer(ip,port);
59
+    setClient(client);
60
+    setStream(stream);
61
+}
62
+PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
63
+    this->_state = MQTT_DISCONNECTED;
64
+    setServer(ip, port);
65
+    setCallback(callback);
66
+    setClient(client);
67
+    this->stream = NULL;
68
+}
69
+PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
70
+    this->_state = MQTT_DISCONNECTED;
71
+    setServer(ip,port);
72
+    setCallback(callback);
73
+    setClient(client);
74
+    setStream(stream);
75
+}
76
+
77
+PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) {
78
+    this->_state = MQTT_DISCONNECTED;
79
+    setServer(domain,port);
80
+    setClient(client);
81
+    this->stream = NULL;
82
+}
83
+PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client, Stream& stream) {
84
+    this->_state = MQTT_DISCONNECTED;
85
+    setServer(domain,port);
86
+    setClient(client);
87
+    setStream(stream);
88
+}
89
+PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
90
+    this->_state = MQTT_DISCONNECTED;
91
+    setServer(domain,port);
92
+    setCallback(callback);
93
+    setClient(client);
94
+    this->stream = NULL;
95
+}
96
+PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
97
+    this->_state = MQTT_DISCONNECTED;
98
+    setServer(domain,port);
99
+    setCallback(callback);
100
+    setClient(client);
101
+    setStream(stream);
102
+}
103
+
104
+boolean PubSubClient::connect(const char *id) {
105
+    return connect(id,NULL,NULL,0,0,0,0,1);
106
+}
107
+
108
+boolean PubSubClient::connect(const char *id, const char *user, const char *pass) {
109
+    return connect(id,user,pass,0,0,0,0,1);
110
+}
111
+
112
+boolean PubSubClient::connect(const char *id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) {
113
+    return connect(id,NULL,NULL,willTopic,willQos,willRetain,willMessage,1);
114
+}
115
+
116
+boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) {
117
+    return connect(id,user,pass,willTopic,willQos,willRetain,willMessage,1);
118
+}
119
+
120
+boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage, boolean cleanSession) {
121
+    if (!connected()) {
122
+        int result = 0;
123
+
124
+        if (domain != NULL) {
125
+            result = _client->connect(this->domain, this->port);
126
+        } else {
127
+            result = _client->connect(this->ip, this->port);
128
+        }
129
+        if (result == 1) {
130
+            nextMsgId = 1;
131
+            // Leave room in the buffer for header and variable length field
132
+            uint16_t length = MQTT_MAX_HEADER_SIZE;
133
+            unsigned int j;
134
+
135
+#if MQTT_VERSION == MQTT_VERSION_3_1
136
+            uint8_t d[9] = {0x00,0x06,'M','Q','I','s','d','p', MQTT_VERSION};
137
+#define MQTT_HEADER_VERSION_LENGTH 9
138
+#elif MQTT_VERSION == MQTT_VERSION_3_1_1
139
+            uint8_t d[7] = {0x00,0x04,'M','Q','T','T',MQTT_VERSION};
140
+#define MQTT_HEADER_VERSION_LENGTH 7
141
+#endif
142
+            for (j = 0;j<MQTT_HEADER_VERSION_LENGTH;j++) {
143
+                buffer[length++] = d[j];
144
+            }
145
+
146
+            uint8_t v;
147
+            if (willTopic) {
148
+                v = 0x04|(willQos<<3)|(willRetain<<5);
149
+            } else {
150
+                v = 0x00;
151
+            }
152
+            if (cleanSession) {
153
+                v = v|0x02;
154
+            }
155
+
156
+            if(user != NULL) {
157
+                v = v|0x80;
158
+
159
+                if(pass != NULL) {
160
+                    v = v|(0x80>>1);
161
+                }
162
+            }
163
+
164
+            buffer[length++] = v;
165
+
166
+            buffer[length++] = ((MQTT_KEEPALIVE) >> 8);
167
+            buffer[length++] = ((MQTT_KEEPALIVE) & 0xFF);
168
+
169
+            CHECK_STRING_LENGTH(length,id)
170
+            length = writeString(id,buffer,length);
171
+            if (willTopic) {
172
+                CHECK_STRING_LENGTH(length,willTopic)
173
+                length = writeString(willTopic,buffer,length);
174
+                CHECK_STRING_LENGTH(length,willMessage)
175
+                length = writeString(willMessage,buffer,length);
176
+            }
177
+
178
+            if(user != NULL) {
179
+                CHECK_STRING_LENGTH(length,user)
180
+                length = writeString(user,buffer,length);
181
+                if(pass != NULL) {
182
+                    CHECK_STRING_LENGTH(length,pass)
183
+                    length = writeString(pass,buffer,length);
184
+                }
185
+            }
186
+
187
+            write(MQTTCONNECT,buffer,length-MQTT_MAX_HEADER_SIZE);
188
+
189
+            lastInActivity = lastOutActivity = millis();
190
+
191
+            while (!_client->available()) {
192
+                unsigned long t = millis();
193
+                if (t-lastInActivity >= ((int32_t) MQTT_SOCKET_TIMEOUT*1000UL)) {
194
+                    _state = MQTT_CONNECTION_TIMEOUT;
195
+                    _client->stop();
196
+                    return false;
197
+                }
198
+            }
199
+            uint8_t llen;
200
+            uint16_t len = readPacket(&llen);
201
+
202
+            if (len == 4) {
203
+                if (buffer[3] == 0) {
204
+                    lastInActivity = millis();
205
+                    pingOutstanding = false;
206
+                    _state = MQTT_CONNECTED;
207
+                    return true;
208
+                } else {
209
+                    _state = buffer[3];
210
+                }
211
+            }
212
+            _client->stop();
213
+        } else {
214
+            _state = MQTT_CONNECT_FAILED;
215
+        }
216
+        return false;
217
+    }
218
+    return true;
219
+}
220
+
221
+// reads a byte into result
222
+boolean PubSubClient::readByte(uint8_t * result) {
223
+   uint32_t previousMillis = millis();
224
+   while(!_client->available()) {
225
+     yield();
226
+     uint32_t currentMillis = millis();
227
+     if(currentMillis - previousMillis >= ((int32_t) MQTT_SOCKET_TIMEOUT * 1000)){
228
+       return false;
229
+     }
230
+   }
231
+   *result = _client->read();
232
+   return true;
233
+}
234
+
235
+// reads a byte into result[*index] and increments index
236
+boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){
237
+  uint16_t current_index = *index;
238
+  uint8_t * write_address = &(result[current_index]);
239
+  if(readByte(write_address)){
240
+    *index = current_index + 1;
241
+    return true;
242
+  }
243
+  return false;
244
+}
245
+
246
+uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
247
+    uint16_t len = 0;
248
+    if(!readByte(buffer, &len)) return 0;
249
+    bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH;
250
+    uint32_t multiplier = 1;
251
+    uint16_t length = 0;
252
+    uint8_t digit = 0;
253
+    uint16_t skip = 0;
254
+    uint8_t start = 0;
255
+
256
+    do {
257
+        if (len == 5) {
258
+            // Invalid remaining length encoding - kill the connection
259
+            _state = MQTT_DISCONNECTED;
260
+            _client->stop();
261
+            return 0;
262
+        }
263
+        if(!readByte(&digit)) return 0;
264
+        buffer[len++] = digit;
265
+        length += (digit & 127) * multiplier;
266
+        multiplier *= 128;
267
+    } while ((digit & 128) != 0);
268
+    *lengthLength = len-1;
269
+
270
+    if (isPublish) {
271
+        // Read in topic length to calculate bytes to skip over for Stream writing
272
+        if(!readByte(buffer, &len)) return 0;
273
+        if(!readByte(buffer, &len)) return 0;
274
+        skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2];
275
+        start = 2;
276
+        if (buffer[0]&MQTTQOS1) {
277
+            // skip message id
278
+            skip += 2;
279
+        }
280
+    }
281
+
282
+    for (uint16_t i = start;i<length;i++) {
283
+        if(!readByte(&digit)) return 0;
284
+        if (this->stream) {
285
+            if (isPublish && len-*lengthLength-2>skip) {
286
+                this->stream->write(digit);
287
+            }
288
+        }
289
+        if (len < MQTT_MAX_PACKET_SIZE) {
290
+            buffer[len] = digit;
291
+        }
292
+        len++;
293
+    }
294
+
295
+    if (!this->stream && len > MQTT_MAX_PACKET_SIZE) {
296
+        len = 0; // This will cause the packet to be ignored.
297
+    }
298
+
299
+    return len;
300
+}
301
+
302
+boolean PubSubClient::loop() {
303
+    if (connected()) {
304
+        unsigned long t = millis();
305
+        if ((t - lastInActivity > MQTT_KEEPALIVE*1000UL) || (t - lastOutActivity > MQTT_KEEPALIVE*1000UL)) {
306
+            if (pingOutstanding) {
307
+                this->_state = MQTT_CONNECTION_TIMEOUT;
308
+                _client->stop();
309
+                return false;
310
+            } else {
311
+                buffer[0] = MQTTPINGREQ;
312
+                buffer[1] = 0;
313
+                _client->write(buffer,2);
314
+                lastOutActivity = t;
315
+                lastInActivity = t;
316
+                pingOutstanding = true;
317
+            }
318
+        }
319
+        if (_client->available()) {
320
+            uint8_t llen;
321
+            uint16_t len = readPacket(&llen);
322
+            uint16_t msgId = 0;
323
+            uint8_t *payload;
324
+            if (len > 0) {
325
+                lastInActivity = t;
326
+                uint8_t type = buffer[0]&0xF0;
327
+                if (type == MQTTPUBLISH) {
328
+                    if (callback) {
329
+                        uint16_t tl = (buffer[llen+1]<<8)+buffer[llen+2]; /* topic length in bytes */
330
+                        memmove(buffer+llen+2,buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */
331
+                        buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */
332
+                        char *topic = (char*) buffer+llen+2;
333
+                        // msgId only present for QOS>0
334
+                        if ((buffer[0]&0x06) == MQTTQOS1) {
335
+                            msgId = (buffer[llen+3+tl]<<8)+buffer[llen+3+tl+1];
336
+                            payload = buffer+llen+3+tl+2;
337
+                            callback(topic,payload,len-llen-3-tl-2);
338
+
339
+                            buffer[0] = MQTTPUBACK;
340
+                            buffer[1] = 2;
341
+                            buffer[2] = (msgId >> 8);
342
+                            buffer[3] = (msgId & 0xFF);
343
+                            _client->write(buffer,4);
344
+                            lastOutActivity = t;
345
+
346
+                        } else {
347
+                            payload = buffer+llen+3+tl;
348
+                            callback(topic,payload,len-llen-3-tl);
349
+                        }
350
+                    }
351
+                } else if (type == MQTTPINGREQ) {
352
+                    buffer[0] = MQTTPINGRESP;
353
+                    buffer[1] = 0;
354
+                    _client->write(buffer,2);
355
+                } else if (type == MQTTPINGRESP) {
356
+                    pingOutstanding = false;
357
+                }
358
+            } else if (!connected()) {
359
+                // readPacket has closed the connection
360
+                return false;
361
+            }
362
+        }
363
+        return true;
364
+    }
365
+    return false;
366
+}
367
+
368
+boolean PubSubClient::publish(const char* topic, const char* payload) {
369
+    return publish(topic,(const uint8_t*)payload,strlen(payload),false);
370
+}
371
+
372
+boolean PubSubClient::publish(const char* topic, const char* payload, boolean retained) {
373
+    return publish(topic,(const uint8_t*)payload,strlen(payload),retained);
374
+}
375
+
376
+boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength) {
377
+    return publish(topic, payload, plength, false);
378
+}
379
+
380
+boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
381
+    if (connected()) {
382
+        if (MQTT_MAX_PACKET_SIZE < MQTT_MAX_HEADER_SIZE + 2+strlen(topic) + plength) {
383
+            // Too long
384
+            return false;
385
+        }
386
+        // Leave room in the buffer for header and variable length field
387
+        uint16_t length = MQTT_MAX_HEADER_SIZE;
388
+        length = writeString(topic,buffer,length);
389
+        uint16_t i;
390
+        for (i=0;i<plength;i++) {
391
+            buffer[length++] = payload[i];
392
+        }
393
+        uint8_t header = MQTTPUBLISH;
394
+        if (retained) {
395
+            header |= 1;
396
+        }
397
+        return write(header,buffer,length-MQTT_MAX_HEADER_SIZE);
398
+    }
399
+    return false;
400
+}
401
+
402
+boolean PubSubClient::publish_P(const char* topic, const char* payload, boolean retained) {
403
+    return publish_P(topic, (const uint8_t*)payload, strlen(payload), retained);
404
+}
405
+
406
+boolean PubSubClient::publish_P(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
407
+    uint8_t llen = 0;
408
+    uint8_t digit;
409
+    unsigned int rc = 0;
410
+    uint16_t tlen;
411
+    unsigned int pos = 0;
412
+    unsigned int i;
413
+    uint8_t header;
414
+    unsigned int len;
415
+
416
+    if (!connected()) {
417
+        return false;
418
+    }
419
+
420
+    tlen = strlen(topic);
421
+
422
+    header = MQTTPUBLISH;
423
+    if (retained) {
424
+        header |= 1;
425
+    }
426
+    buffer[pos++] = header;
427
+    len = plength + 2 + tlen;
428
+    do {
429
+        digit = len % 128;
430
+        len = len / 128;
431
+        if (len > 0) {
432
+            digit |= 0x80;
433
+        }
434
+        buffer[pos++] = digit;
435
+        llen++;
436
+    } while(len>0);
437
+
438
+    pos = writeString(topic,buffer,pos);
439
+
440
+    rc += _client->write(buffer,pos);
441
+
442
+    for (i=0;i<plength;i++) {
443
+        rc += _client->write((char)pgm_read_byte_near(payload + i));
444
+    }
445
+
446
+    lastOutActivity = millis();
447
+
448
+    return rc == tlen + 4 + plength;
449
+}
450
+
451
+boolean PubSubClient::beginPublish(const char* topic, unsigned int plength, boolean retained) {
452
+    if (connected()) {
453
+        // Send the header and variable length field
454
+        uint16_t length = MQTT_MAX_HEADER_SIZE;
455
+        length = writeString(topic,buffer,length);
456
+        uint16_t i;
457
+        uint8_t header = MQTTPUBLISH;
458
+        if (retained) {
459
+            header |= 1;
460
+        }
461
+        size_t hlen = buildHeader(header, buffer, plength+length-MQTT_MAX_HEADER_SIZE);
462
+        uint16_t rc = _client->write(buffer+(MQTT_MAX_HEADER_SIZE-hlen),length-(MQTT_MAX_HEADER_SIZE-hlen));
463
+        lastOutActivity = millis();
464
+        return (rc == (length-(MQTT_MAX_HEADER_SIZE-hlen)));
465
+    }
466
+    return false;
467
+}
468
+
469
+int PubSubClient::endPublish() {
470
+ return 1;
471
+}
472
+
473
+size_t PubSubClient::write(uint8_t data) {
474
+    lastOutActivity = millis();
475
+    return _client->write(data);
476
+}
477
+
478
+size_t PubSubClient::write(const uint8_t *buffer, size_t size) {
479
+    lastOutActivity = millis();
480
+    return _client->write(buffer,size);
481
+}
482
+
483
+size_t PubSubClient::buildHeader(uint8_t header, uint8_t* buf, uint16_t length) {
484
+    uint8_t lenBuf[4];
485
+    uint8_t llen = 0;
486
+    uint8_t digit;
487
+    uint8_t pos = 0;
488
+    uint16_t len = length;
489
+    do {
490
+        digit = len % 128;
491
+        len = len / 128;
492
+        if (len > 0) {
493
+            digit |= 0x80;
494
+        }
495
+        lenBuf[pos++] = digit;
496
+        llen++;
497
+    } while(len>0);
498
+
499
+    buf[4-llen] = header;
500
+    for (int i=0;i<llen;i++) {
501
+        buf[MQTT_MAX_HEADER_SIZE-llen+i] = lenBuf[i];
502
+    }
503
+    return llen+1; // Full header size is variable length bit plus the 1-byte fixed header
504
+}
505
+
506
+boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
507
+    uint16_t rc;
508
+    uint8_t hlen = buildHeader(header, buf, length);
509
+
510
+#ifdef MQTT_MAX_TRANSFER_SIZE
511
+    uint8_t* writeBuf = buf+(MQTT_MAX_HEADER_SIZE-hlen);
512
+    uint16_t bytesRemaining = length+hlen;  //Match the length type
513
+    uint8_t bytesToWrite;
514
+    boolean result = true;
515
+    while((bytesRemaining > 0) && result) {
516
+        bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining;
517
+        rc = _client->write(writeBuf,bytesToWrite);
518
+        result = (rc == bytesToWrite);
519
+        bytesRemaining -= rc;
520
+        writeBuf += rc;
521
+    }
522
+    return result;
523
+#else
524
+    rc = _client->write(buf+(MQTT_MAX_HEADER_SIZE-hlen),length+hlen);
525
+    lastOutActivity = millis();
526
+    return (rc == hlen+length);
527
+#endif
528
+}
529
+
530
+boolean PubSubClient::subscribe(const char* topic) {
531
+    return subscribe(topic, 0);
532
+}
533
+
534
+boolean PubSubClient::subscribe(const char* topic, uint8_t qos) {
535
+    if (qos > 1) {
536
+        return false;
537
+    }
538
+    if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) {
539
+        // Too long
540
+        return false;
541
+    }
542
+    if (connected()) {
543
+        // Leave room in the buffer for header and variable length field
544
+        uint16_t length = MQTT_MAX_HEADER_SIZE;
545
+        nextMsgId++;
546
+        if (nextMsgId == 0) {
547
+            nextMsgId = 1;
548
+        }
549
+        buffer[length++] = (nextMsgId >> 8);
550
+        buffer[length++] = (nextMsgId & 0xFF);
551
+        length = writeString((char*)topic, buffer,length);
552
+        buffer[length++] = qos;
553
+        return write(MQTTSUBSCRIBE|MQTTQOS1,buffer,length-MQTT_MAX_HEADER_SIZE);
554
+    }
555
+    return false;
556
+}
557
+
558
+boolean PubSubClient::unsubscribe(const char* topic) {
559
+    if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) {
560
+        // Too long
561
+        return false;
562
+    }
563
+    if (connected()) {
564
+        uint16_t length = MQTT_MAX_HEADER_SIZE;
565
+        nextMsgId++;
566
+        if (nextMsgId == 0) {
567
+            nextMsgId = 1;
568
+        }
569
+        buffer[length++] = (nextMsgId >> 8);
570
+        buffer[length++] = (nextMsgId & 0xFF);
571
+        length = writeString(topic, buffer,length);
572
+        return write(MQTTUNSUBSCRIBE|MQTTQOS1,buffer,length-MQTT_MAX_HEADER_SIZE);
573
+    }
574
+    return false;
575
+}
576
+
577
+void PubSubClient::disconnect() {
578
+    buffer[0] = MQTTDISCONNECT;
579
+    buffer[1] = 0;
580
+    _client->write(buffer,2);
581
+    _state = MQTT_DISCONNECTED;
582
+    _client->flush();
583
+    _client->stop();
584
+    lastInActivity = lastOutActivity = millis();
585
+}
586
+
587
+uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t pos) {
588
+    const char* idp = string;
589
+    uint16_t i = 0;
590
+    pos += 2;
591
+    while (*idp) {
592
+        buf[pos++] = *idp++;
593
+        i++;
594
+    }
595
+    buf[pos-i-2] = (i >> 8);
596
+    buf[pos-i-1] = (i & 0xFF);
597
+    return pos;
598
+}
599
+
600
+
601
+boolean PubSubClient::connected() {
602
+    boolean rc;
603
+    if (_client == NULL ) {
604
+        rc = false;
605
+    } else {
606
+        rc = (int)_client->connected();
607
+        if (!rc) {
608
+            if (this->_state == MQTT_CONNECTED) {
609
+                this->_state = MQTT_CONNECTION_LOST;
610
+                _client->flush();
611
+                _client->stop();
612
+            }
613
+        }
614
+    }
615
+    return rc;
616
+}
617
+
618
+PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) {
619
+    IPAddress addr(ip[0],ip[1],ip[2],ip[3]);
620
+    return setServer(addr,port);
621
+}
622
+
623
+PubSubClient& PubSubClient::setServer(IPAddress ip, uint16_t port) {
624
+    this->ip = ip;
625
+    this->port = port;
626
+    this->domain = NULL;
627
+    return *this;
628
+}
629
+
630
+PubSubClient& PubSubClient::setServer(const char * domain, uint16_t port) {
631
+    this->domain = domain;
632
+    this->port = port;
633
+    return *this;
634
+}
635
+
636
+PubSubClient& PubSubClient::setCallback(MQTT_CALLBACK_SIGNATURE) {
637
+    this->callback = callback;
638
+    return *this;
639
+}
640
+
641
+PubSubClient& PubSubClient::setClient(Client& client){
642
+    this->_client = &client;
643
+    return *this;
644
+}
645
+
646
+PubSubClient& PubSubClient::setStream(Stream& stream){
647
+    this->stream = &stream;
648
+    return *this;
649
+}
650
+
651
+int PubSubClient::state() {
652
+    return this->_state;
653
+}

+ 173
- 0
ClimateControl/lib/PubSubClient_ID89/src/PubSubClient.h View File

@@ -0,0 +1,173 @@
1
+/*
2
+ PubSubClient.h - A simple client for MQTT.
3
+  Nick O'Leary
4
+  http://knolleary.net
5
+*/
6
+
7
+#ifndef PubSubClient_h
8
+#define PubSubClient_h
9
+
10
+#include <Arduino.h>
11
+#include "IPAddress.h"
12
+#include "Client.h"
13
+#include "Stream.h"
14
+
15
+#define MQTT_VERSION_3_1      3
16
+#define MQTT_VERSION_3_1_1    4
17
+
18
+// MQTT_VERSION : Pick the version
19
+//#define MQTT_VERSION MQTT_VERSION_3_1
20
+#ifndef MQTT_VERSION
21
+#define MQTT_VERSION MQTT_VERSION_3_1_1
22
+#endif
23
+
24
+// MQTT_MAX_PACKET_SIZE : Maximum packet size
25
+#ifndef MQTT_MAX_PACKET_SIZE
26
+#define MQTT_MAX_PACKET_SIZE 128
27
+#endif
28
+
29
+// MQTT_KEEPALIVE : keepAlive interval in Seconds
30
+#ifndef MQTT_KEEPALIVE
31
+#define MQTT_KEEPALIVE 15
32
+#endif
33
+
34
+// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds
35
+#ifndef MQTT_SOCKET_TIMEOUT
36
+#define MQTT_SOCKET_TIMEOUT 15
37
+#endif
38
+
39
+// MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client
40
+//  in each write call. Needed for the Arduino Wifi Shield. Leave undefined to
41
+//  pass the entire MQTT packet in each write call.
42
+//#define MQTT_MAX_TRANSFER_SIZE 80
43
+
44
+// Possible values for client.state()
45
+#define MQTT_CONNECTION_TIMEOUT     -4
46
+#define MQTT_CONNECTION_LOST        -3
47
+#define MQTT_CONNECT_FAILED         -2
48
+#define MQTT_DISCONNECTED           -1
49
+#define MQTT_CONNECTED               0
50
+#define MQTT_CONNECT_BAD_PROTOCOL    1
51
+#define MQTT_CONNECT_BAD_CLIENT_ID   2
52
+#define MQTT_CONNECT_UNAVAILABLE     3
53
+#define MQTT_CONNECT_BAD_CREDENTIALS 4
54
+#define MQTT_CONNECT_UNAUTHORIZED    5
55
+
56
+#define MQTTCONNECT     1 << 4  // Client request to connect to Server
57
+#define MQTTCONNACK     2 << 4  // Connect Acknowledgment
58
+#define MQTTPUBLISH     3 << 4  // Publish message
59
+#define MQTTPUBACK      4 << 4  // Publish Acknowledgment
60
+#define MQTTPUBREC      5 << 4  // Publish Received (assured delivery part 1)
61
+#define MQTTPUBREL      6 << 4  // Publish Release (assured delivery part 2)
62
+#define MQTTPUBCOMP     7 << 4  // Publish Complete (assured delivery part 3)
63
+#define MQTTSUBSCRIBE   8 << 4  // Client Subscribe request
64
+#define MQTTSUBACK      9 << 4  // Subscribe Acknowledgment
65
+#define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request
66
+#define MQTTUNSUBACK    11 << 4 // Unsubscribe Acknowledgment
67
+#define MQTTPINGREQ     12 << 4 // PING Request
68
+#define MQTTPINGRESP    13 << 4 // PING Response
69
+#define MQTTDISCONNECT  14 << 4 // Client is Disconnecting
70
+#define MQTTReserved    15 << 4 // Reserved
71
+
72
+#define MQTTQOS0        (0 << 1)
73
+#define MQTTQOS1        (1 << 1)
74
+#define MQTTQOS2        (2 << 1)
75
+
76
+// Maximum size of fixed header and variable length size header
77
+#define MQTT_MAX_HEADER_SIZE 5
78
+
79
+#if defined(ESP8266) || defined(ESP32)
80
+#include <functional>
81
+#define MQTT_CALLBACK_SIGNATURE std::function<void(char*, uint8_t*, unsigned int)> callback
82
+#else
83
+#define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int)
84
+#endif
85
+
86
+#define CHECK_STRING_LENGTH(l,s) if (l+2+strlen(s) > MQTT_MAX_PACKET_SIZE) {_client->stop();return false;}
87
+
88
+class PubSubClient : public Print {
89
+private:
90
+   Client* _client;
91
+   uint8_t buffer[MQTT_MAX_PACKET_SIZE];
92
+   uint16_t nextMsgId;
93
+   unsigned long lastOutActivity;
94
+   unsigned long lastInActivity;
95
+   bool pingOutstanding;
96
+   MQTT_CALLBACK_SIGNATURE;
97
+   uint16_t readPacket(uint8_t*);
98
+   boolean readByte(uint8_t * result);
99
+   boolean readByte(uint8_t * result, uint16_t * index);
100
+   boolean write(uint8_t header, uint8_t* buf, uint16_t length);
101
+   uint16_t writeString(const char* string, uint8_t* buf, uint16_t pos);
102
+   // Build up the header ready to send
103
+   // Returns the size of the header
104
+   // Note: the header is built at the end of the first MQTT_MAX_HEADER_SIZE bytes, so will start
105
+   //       (MQTT_MAX_HEADER_SIZE - <returned size>) bytes into the buffer
106
+   size_t buildHeader(uint8_t header, uint8_t* buf, uint16_t length);
107
+   IPAddress ip;
108
+   const char* domain;
109
+   uint16_t port;
110
+   Stream* stream;
111
+   int _state;
112
+public:
113
+   PubSubClient();
114
+   PubSubClient(Client& client);
115
+   PubSubClient(IPAddress, uint16_t, Client& client);
116
+   PubSubClient(IPAddress, uint16_t, Client& client, Stream&);
117
+   PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
118
+   PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
119
+   PubSubClient(uint8_t *, uint16_t, Client& client);
120
+   PubSubClient(uint8_t *, uint16_t, Client& client, Stream&);
121
+   PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
122
+   PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
123
+   PubSubClient(const char*, uint16_t, Client& client);
124
+   PubSubClient(const char*, uint16_t, Client& client, Stream&);
125
+   PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
126
+   PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
127
+
128
+   PubSubClient& setServer(IPAddress ip, uint16_t port);
129
+   PubSubClient& setServer(uint8_t * ip, uint16_t port);
130
+   PubSubClient& setServer(const char * domain, uint16_t port);
131
+   PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE);
132
+   PubSubClient& setClient(Client& client);
133
+   PubSubClient& setStream(Stream& stream);
134
+
135
+   boolean connect(const char* id);
136
+   boolean connect(const char* id, const char* user, const char* pass);
137
+   boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
138
+   boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
139
+   boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage, boolean cleanSession);
140
+   void disconnect();
141
+   boolean publish(const char* topic, const char* payload);
142
+   boolean publish(const char* topic, const char* payload, boolean retained);
143
+   boolean publish(const char* topic, const uint8_t * payload, unsigned int plength);
144
+   boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
145
+   boolean publish_P(const char* topic, const char* payload, boolean retained);
146
+   boolean publish_P(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
147
+   // Start to publish a message.
148
+   // This API:
149
+   //   beginPublish(...)
150
+   //   one or more calls to write(...)
151
+   //   endPublish()
152
+   // Allows for arbitrarily large payloads to be sent without them having to be copied into
153
+   // a new buffer and held in memory at one time
154
+   // Returns 1 if the message was started successfully, 0 if there was an error
155
+   boolean beginPublish(const char* topic, unsigned int plength, boolean retained);
156
+   // Finish off this publish message (started with beginPublish)
157
+   // Returns 1 if the packet was sent successfully, 0 if there was an error
158
+   int endPublish();
159
+   // Write a single byte of payload (only to be used with beginPublish/endPublish)
160
+   virtual size_t write(uint8_t);
161
+   // Write size bytes from buffer into the payload (only to be used with beginPublish/endPublish)
162
+   // Returns the number of bytes written
163
+   virtual size_t write(const uint8_t *buffer, size_t size);
164
+   boolean subscribe(const char* topic);
165
+   boolean subscribe(const char* topic, uint8_t qos);
166
+   boolean unsubscribe(const char* topic);
167
+   boolean loop();
168
+   boolean connected();
169
+   int state();
170
+};
171
+
172
+
173
+#endif

+ 0
- 0
ClimateControl/lib/SimpleTimer_ID419/.gitignore View File


+ 27
- 0
ClimateControl/lib/SimpleTimer_ID419/.library.json View File

@@ -0,0 +1,27 @@
1
+{
2
+    "name": "SimpleTimer", 
3
+    "repository": {
4
+        "url": "https://github.com/jfturcot/SimpleTimer.git", 
5
+        "type": "git"
6
+    }, 
7
+    "platforms": [
8
+        "atmelavr"
9
+    ], 
10
+    "frameworks": [
11
+        "arduino"
12
+    ], 
13
+    "version": "b30890b8f7", 
14
+    "authors": [
15
+        {
16
+            "maintainer": false, 
17
+            "name": "Jean-Francois Turcot", 
18
+            "url": "https://github.com/jfturcot", 
19
+            "email": "jf.turcot@gmail.com"
20
+        }
21
+    ], 
22
+    "keywords": [
23
+        "timer"
24
+    ], 
25
+    "id": 419, 
26
+    "description": "SimpleTimer Library for Arduino"
27
+}

+ 2
- 0
ClimateControl/lib/SimpleTimer_ID419/README View File

@@ -0,0 +1,2 @@
1
+Visit this page for more information:
2
+http://playground.arduino.cc/Code/SimpleTimer

+ 241
- 0
ClimateControl/lib/SimpleTimer_ID419/SimpleTimer.cpp View File

@@ -0,0 +1,241 @@
1
+/*
2
+ * SimpleTimer.cpp
3
+ *
4
+ * SimpleTimer - A timer library for Arduino.
5
+ * Author: mromani@ottotecnica.com
6
+ * Copyright (c) 2010 OTTOTECNICA Italy
7
+ *
8
+ * This library is free software; you can redistribute it
9
+ * and/or modify it under the terms of the GNU Lesser
10
+ * General Public License as published by the Free Software
11
+ * Foundation; either version 2.1 of the License, or (at
12
+ * your option) any later version.
13
+ *
14
+ * This library is distributed in the hope that it will
15
+ * be useful, but WITHOUT ANY WARRANTY; without even the
16
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A
17
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public
18
+ * License for more details.
19
+ *
20
+ * You should have received a copy of the GNU Lesser
21
+ * General Public License along with this library; if not,
22
+ * write to the Free Software Foundation, Inc.,
23
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
+ */
25
+
26
+
27
+#include "SimpleTimer.h"
28
+
29
+
30
+// Select time function:
31
+//static inline unsigned long elapsed() { return micros(); }
32
+static inline unsigned long elapsed() { return millis(); }
33
+
34
+
35
+SimpleTimer::SimpleTimer() {
36
+    unsigned long current_millis = elapsed();
37
+
38
+    for (int i = 0; i < MAX_TIMERS; i++) {
39
+        enabled[i] = false;
40
+        callbacks[i] = 0;                   // if the callback pointer is zero, the slot is free, i.e. doesn't "contain" any timer
41
+        prev_millis[i] = current_millis;
42
+        numRuns[i] = 0;
43
+    }
44
+
45
+    numTimers = 0;
46
+}
47
+
48
+
49
+void SimpleTimer::run() {
50
+    int i;
51
+    unsigned long current_millis;
52
+
53
+    // get current time
54
+    current_millis = elapsed();
55
+
56
+    for (i = 0; i < MAX_TIMERS; i++) {
57
+
58
+        toBeCalled[i] = DEFCALL_DONTRUN;
59
+
60
+        // no callback == no timer, i.e. jump over empty slots
61
+        if (callbacks[i]) {
62
+
63
+            // is it time to process this timer ?
64
+            // see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592
65
+
66
+            if (current_millis - prev_millis[i] >= delays[i]) {
67
+
68
+                // update time
69
+                //prev_millis[i] = current_millis;
70
+                prev_millis[i] += delays[i];
71
+
72
+                // check if the timer callback has to be executed
73
+                if (enabled[i]) {
74
+
75
+                    // "run forever" timers must always be executed
76
+                    if (maxNumRuns[i] == RUN_FOREVER) {
77
+                        toBeCalled[i] = DEFCALL_RUNONLY;
78
+                    }
79
+                    // other timers get executed the specified number of times
80
+                    else if (numRuns[i] < maxNumRuns[i]) {
81
+                        toBeCalled[i] = DEFCALL_RUNONLY;
82
+                        numRuns[i]++;
83
+
84
+                        // after the last run, delete the timer
85
+                        if (numRuns[i] >= maxNumRuns[i]) {
86
+                            toBeCalled[i] = DEFCALL_RUNANDDEL;
87
+                        }
88
+                    }
89
+                }
90
+            }
91
+        }
92
+    }
93
+
94
+    for (i = 0; i < MAX_TIMERS; i++) {
95
+        switch(toBeCalled[i]) {
96
+            case DEFCALL_DONTRUN:
97
+                break;
98
+
99
+            case DEFCALL_RUNONLY:
100
+                (*callbacks[i])();
101
+                break;
102
+
103
+            case DEFCALL_RUNANDDEL:
104
+                (*callbacks[i])();
105
+                deleteTimer(i);
106
+                break;
107
+        }
108
+    }
109
+}
110
+
111
+
112
+// find the first available slot
113
+// return -1 if none found
114
+int SimpleTimer::findFirstFreeSlot() {
115
+    int i;
116
+
117
+    // all slots are used
118
+    if (numTimers >= MAX_TIMERS) {
119
+        return -1;
120
+    }
121
+
122
+    // return the first slot with no callback (i.e. free)
123
+    for (i = 0; i < MAX_TIMERS; i++) {
124
+        if (callbacks[i] == 0) {
125
+            return i;
126
+        }
127
+    }
128
+
129
+    // no free slots found
130
+    return -1;
131
+}
132
+
133
+
134
+int SimpleTimer::setTimer(long d, timer_callback f, int n) {
135
+    int freeTimer;
136
+
137
+    freeTimer = findFirstFreeSlot();
138
+    if (freeTimer < 0) {
139
+        return -1;
140
+    }
141
+
142
+    if (f == NULL) {
143
+        return -1;
144
+    }
145
+
146
+    delays[freeTimer] = d;
147
+    callbacks[freeTimer] = f;
148
+    maxNumRuns[freeTimer] = n;
149
+    enabled[freeTimer] = true;
150
+    prev_millis[freeTimer] = elapsed();
151
+
152
+    numTimers++;
153
+
154
+    return freeTimer;
155
+}
156
+
157
+
158
+int SimpleTimer::setInterval(long d, timer_callback f) {
159
+    return setTimer(d, f, RUN_FOREVER);
160
+}
161
+
162
+
163
+int SimpleTimer::setTimeout(long d, timer_callback f) {
164
+    return setTimer(d, f, RUN_ONCE);
165
+}
166
+
167
+
168
+void SimpleTimer::deleteTimer(int timerId) {
169
+    if (timerId >= MAX_TIMERS) {
170
+        return;
171
+    }
172
+
173
+    // nothing to delete if no timers are in use
174
+    if (numTimers == 0) {
175
+        return;
176
+    }
177
+
178
+    // don't decrease the number of timers if the
179
+    // specified slot is already empty
180
+    if (callbacks[timerId] != NULL) {
181
+        callbacks[timerId] = 0;
182
+        enabled[timerId] = false;
183
+        toBeCalled[timerId] = DEFCALL_DONTRUN;
184
+        delays[timerId] = 0;
185
+        numRuns[timerId] = 0;
186
+
187
+        // update number of timers
188
+        numTimers--;
189
+    }
190
+}
191
+
192
+
193
+// function contributed by code@rowansimms.com
194
+void SimpleTimer::restartTimer(int numTimer) {