summaryrefslogtreecommitdiffstats
path: root/oliver/lr_stripes/src/lr_stripes.cpp
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2020-03-17 12:00:59 +0100
committermanuel <manuel@mausz.at>2020-03-17 12:00:59 +0100
commitf0ecb4d38fff522c72905a8551355ca925381fa3 (patch)
tree44df19413a3ea38b2729f2ba223b9c3be5b27af3 /oliver/lr_stripes/src/lr_stripes.cpp
parent1fe1e04f903aaedf4bcde0ae85f58f6644ccedd5 (diff)
downloadarduino-f0ecb4d38fff522c72905a8551355ca925381fa3.tar.gz
arduino-f0ecb4d38fff522c72905a8551355ca925381fa3.tar.bz2
arduino-f0ecb4d38fff522c72905a8551355ca925381fa3.zip
platform io cleanup
Diffstat (limited to 'oliver/lr_stripes/src/lr_stripes.cpp')
-rw-r--r--oliver/lr_stripes/src/lr_stripes.cpp394
1 files changed, 0 insertions, 394 deletions
diff --git a/oliver/lr_stripes/src/lr_stripes.cpp b/oliver/lr_stripes/src/lr_stripes.cpp
deleted file mode 100644
index 6ad4282..0000000
--- a/oliver/lr_stripes/src/lr_stripes.cpp
+++ /dev/null
@@ -1,394 +0,0 @@
1#include <Arduino.h>
2#include <ESP8266mDNS.h>
3#include <PubSubClient.h>
4#include <WiFiManager.h>
5#include <Bounce2.h>
6#include <ESP8266httpUpdate.h>
7#include "secrets.h"
8
9#define _STR(s) #s
10#define STR(s) _STR(s)
11
12const char* mqtt_server = "192.168.1.2"; //MQTT Server IP, your home MQTT server eg Mosquitto on RPi, or some public MQTT
13const int mqtt_port = 1883; //MQTT Server PORT, default is 1883 but can be anything.
14
15const char* mqtt_pingall_sub = "home/pingall";
16const char* mqtt_pingall_pub = "home/pingall/response";
17
18#define MQTT_BASE "home/livingroom/ledstripe"
19const char* mqtt_device_boot = MQTT_BASE "/device";
20
21enum sensor_type : uint8_t
22{
23 SENSOR_RELAY = (1u << 0),
24 SENSOR_DIMMER = (1u << 1),
25 SENSOR_BUTTON = (1u << 2),
26};
27
28struct sensor_t
29{
30 uint8_t type;
31 struct
32 {
33 uint8_t pin; // relay pin
34 const char *mqtt_sub;
35 const char *mqtt_pub;
36 } relay;
37 struct
38 {
39 uint8_t pin; // push button pin
40 Bounce bounce;
41 } button;
42 struct
43 {
44 uint8_t pin; // dimmer pin
45 uint8_t level; // current dim level (0 to 100)
46 const char *mqtt_sub;
47 const char *mqtt_pub;
48 } dimmer;
49};
50
51struct sensor_t sensors[] = {
52 {
53 .type = SENSOR_RELAY | SENSOR_BUTTON | SENSOR_DIMMER,
54 .relay = {
55 .pin = D5,
56 .mqtt_sub = MQTT_BASE,
57 .mqtt_pub = MQTT_BASE "/status"
58 },
59 .button = {
60 .pin = D0,
61 .bounce = Bounce(),
62 },
63 .dimmer = {
64 .pin = D8,
65 .level = 100,
66 .mqtt_sub = MQTT_BASE "/brightness",
67 .mqtt_pub = MQTT_BASE "/brightness/status"
68 },
69 }
70};
71
72//#define SAVE_RESTORE
73
74#define NUM(a) (sizeof(a) / sizeof(*a))
75
76#define RELAY_ON 1 // GPIO value to write to turn on attached relay
77#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
78
79#define DIMMER_FADE_DELAY 40 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
80
81WiFiClient espClient;
82PubSubClient client(espClient);
83char convBuffer[10];
84
85void callback(char* topic, byte* payload, unsigned int length);
86void blink();
87bool relayRead(struct sensor_t *sensor);
88void relayWrite(struct sensor_t *sensor, bool state, bool send_update=false);
89void flipRelay(struct sensor_t *sensor, bool send_update=false);
90void checkButtons(void);
91inline uint8_t pwmValue(uint8_t level);
92void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update=false);
93void checkFirmwareUpdate();
94
95void setup()
96{
97 Serial.begin(115200);
98 pinMode(LED_BUILTIN, OUTPUT);
99 analogWriteRange(100);
100
101 // set relay pins to output mode + restore to last known state
102 for (uint8_t i = 0; i < NUM(sensors); i++)
103 {
104 struct sensor_t *sensor = &sensors[i];
105 if (sensor->type & SENSOR_RELAY)
106 {
107 pinMode(sensor->relay.pin, OUTPUT);
108#ifdef SAVE_RESTORE
109#error "not implemented"
110#else
111 digitalWrite(sensor->relay.pin, RELAY_OFF);
112#endif
113 }
114
115 if (sensor->type & SENSOR_DIMMER)
116 {
117 pinMode(sensor->dimmer.pin, OUTPUT);
118#ifdef SAVE_RESTORE
119#error "not implemented"
120#else
121 uint8_t level = sensor->dimmer.level;
122#endif
123 if ((sensor->type & SENSOR_RELAY) && !relayRead(sensor))
124 level = 0;
125 analogWrite(sensor->dimmer.pin, pwmValue(level));
126 }
127
128 if (sensor->type & SENSOR_BUTTON)
129 {
130 pinMode(sensor->button.pin, INPUT);
131 sensor->button.bounce.attach(sensor->button.pin);
132 }
133 }
134
135 WiFiManager wifiManager;
136 wifiManager.setConfigPortalTimeout(600);
137 Serial.printf_P(PSTR("Setting up WiFi\n"));
138 if (!wifiManager.autoConnect("ESP8266_LR_STRIPES")) {
139 Serial.printf_P(PSTR("Failed to connect and hit timeout\n"));
140 delay(5000);
141 ESP.restart();
142 }
143
144 yield();
145 checkFirmwareUpdate();
146 yield();
147
148 client.setServer(mqtt_server, mqtt_port);
149 client.setCallback(callback);
150
151 digitalWrite(LED_BUILTIN, HIGH); //Turn off led as default
152}
153
154void reconnect()
155{
156 // Loop until we're reconnected
157 while (!client.connected())
158 {
159 // Create a random client ID
160 String clientId = "ESP8266Client-";
161 clientId += String(random(0xffff), HEX);
162
163 // Attempt to connect
164 if (client.connect(clientId.c_str()))
165 {
166 // Once connected, publish an announcement...
167 client.publish(mqtt_device_boot, "connected");
168 // ... and resubscribe
169 client.subscribe(mqtt_pingall_sub);
170
171 // publish states
172 for (uint8_t i = 0; i < NUM(sensors); i++)
173 {
174 struct sensor_t *sensor = &sensors[i];
175 if (sensor->type & SENSOR_RELAY)
176 {
177 Serial.println(sensor->relay.mqtt_sub);
178 client.subscribe(sensor->relay.mqtt_sub);
179 client.publish(sensor->relay.mqtt_pub, relayRead(sensor) ? "1" : "0",
180 true);
181 }
182
183 if (sensor->type & SENSOR_DIMMER)
184 {
185 Serial.println(sensor->dimmer.mqtt_sub);
186 client.subscribe(sensor->dimmer.mqtt_sub);
187 itoa(sensor->dimmer.level, convBuffer, 10);
188 client.publish(sensor->dimmer.mqtt_pub, convBuffer, true);
189 }
190 }
191 }
192 else
193 {
194 // Wait 5 seconds before retrying
195 delay(5000);
196 }
197 }
198}
199
200void callback(char* topic, byte* payload, unsigned int length)
201{
202 char c_payload[length];
203 memcpy(c_payload, payload, length);
204 c_payload[length] = '\0';
205
206 if (strcmp(topic, mqtt_pingall_sub) == 0)
207 {
208 blink();
209 client.publish(mqtt_pingall_pub,
210 "{\"livingroom_ledstrip\":\"connected\"}");
211 return;
212 }
213
214 for (uint8_t i = 0; i < NUM(sensors); i++)
215 {
216 struct sensor_t *sensor = &sensors[i];
217 if (sensor->type & SENSOR_RELAY
218 && length > 0
219 && strcmp(topic, sensor->relay.mqtt_sub) == 0)
220 {
221 blink();
222 relayWrite(sensor, payload[0] == '1', true);
223 return;
224 }
225
226 if (sensor->type & SENSOR_DIMMER
227 && length > 0
228 && strcmp(topic, sensor->dimmer.mqtt_sub) == 0)
229 {
230 blink();
231 uint8_t level = atoi((char *)payload);
232 fadeDimmer(sensor, (level > 100) ? 100 : level, true);
233 return;
234 }
235 }
236}
237
238void blink()
239{
240 //Blink on received MQTT message
241 digitalWrite(LED_BUILTIN, LOW);
242 delay(25);
243 digitalWrite(LED_BUILTIN, HIGH);
244}
245
246void loop()
247{
248 if (!client.connected())
249 reconnect();
250 client.loop();
251 checkButtons();
252}
253
254bool relayRead(struct sensor_t *sensor)
255{
256 if (sensor->type & SENSOR_RELAY)
257 return digitalRead(sensor->relay.pin) == RELAY_ON;
258 return false;
259}
260
261void relayWrite(struct sensor_t *sensor, bool state, bool send_update)
262{
263 if (!(sensor->type & SENSOR_RELAY))
264 return;
265
266 Serial.print(F("Incoming change for relay: "));
267 Serial.print(sensor->relay.pin);
268 Serial.print(F(", New state: "));
269 Serial.println(state);
270
271 digitalWrite(sensor->relay.pin, state ? RELAY_ON : RELAY_OFF);
272
273 if (sensor->type & SENSOR_DIMMER)
274 analogWrite(sensor->dimmer.pin, state ? pwmValue(sensor->dimmer.level) : 0);
275
276#ifdef SAVE_RESTORE
277#error "not implemented"
278#endif
279
280 if (send_update)
281 client.publish(sensor->relay.mqtt_pub, state ? "1" : "0", true);
282}
283
284void flipRelay(struct sensor_t *sensor, bool send_update)
285{
286 relayWrite(sensor, relayRead(sensor) ? RELAY_OFF : RELAY_ON, send_update);
287}
288
289inline void checkButtons(void)
290{
291 for (uint8_t i = 0; i < NUM(sensors); i++)
292 {
293 struct sensor_t *sensor = &sensors[i];
294 if (sensor->type & SENSOR_BUTTON)
295 {
296 sensor->button.bounce.update();
297 if (sensor->button.bounce.fell())
298 flipRelay(sensor, true);
299 }
300 }
301}
302
303const uint8_t pwmtable[101] PROGMEM = {
304 // value below 0 turns of the power supply
305 0, 10, 10, 11, 11, 11, 11, 12, 12, 12,
306 13, 13, 13, 13, 14, 14, 14, 15, 15, 15,
307 16, 16, 17, 17, 17, 18, 18, 19, 19, 19,
308 20, 20, 21, 21, 22, 22, 23, 23, 24, 25,
309 25, 26, 26, 27, 28, 28, 29, 30, 30, 31,
310 32, 32, 33, 34, 35, 35, 36, 37, 38, 39,
311 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
312 50, 51, 52, 54, 55, 56, 58, 59, 60, 62,
313 63, 65, 66, 68, 69, 71, 72, 74, 76, 78,
314 79, 81, 83, 85, 87, 89, 91, 93, 95, 98,
315 100
316};
317
318inline uint8_t pwmValue(uint8_t level)
319{
320 //uint8_t lvl = 100 - (uint8_t)pgm_read_byte(&pwmtable[level]);
321 //return (lvl < 10) 10 : lvl;
322 //level = (level > 0 && level < 10) ? 10 : level;
323 //return 100 - level;
324 return 100 - (uint8_t)pgm_read_byte(&pwmtable[level]);
325}
326
327void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update)
328{
329 if (!(sensor->type & SENSOR_DIMMER))
330 return;
331 if (level > 100)
332 level = 100;
333
334 Serial.print(F("Incoming change for dimmer: "));
335 Serial.print(sensor->dimmer.pin);
336 Serial.print(F(", New level: "));
337 Serial.println(level);
338
339 if (level > 0 && sensor->type & SENSOR_RELAY && !relayRead(sensor))
340 relayWrite(sensor, RELAY_ON, send_update);
341
342 int delta = ((int8_t)(level - sensor->dimmer.level) < 0) ? -1 : 1;
343 while (sensor->dimmer.level != level)
344 {
345 sensor->dimmer.level += delta;
346 analogWrite(sensor->dimmer.pin, pwmValue(sensor->dimmer.level));
347 delay(DIMMER_FADE_DELAY);
348 }
349
350 if (level == 0 && sensor->type & SENSOR_RELAY && relayRead(sensor))
351 relayWrite(sensor, RELAY_OFF, send_update);
352
353#ifdef SAVE_RESTORE
354#error "not implemented"
355#endif
356
357 if (send_update)
358 {
359 itoa(level, convBuffer, 10);
360 client.publish(sensor->dimmer.mqtt_pub, convBuffer, true);
361 }
362}
363
364void checkFirmwareUpdate()
365{
366 BearSSL::WiFiClientSecure update_client;
367 update_client.setInsecure();
368
369 client.publish(mqtt_device_boot, "fwupdate running");
370 ESPhttpUpdate.setLedPin(LED_BUILTIN, HIGH);
371 ESPhttpUpdate.rebootOnUpdate(true);
372 t_httpUpdate_return ret = ESPhttpUpdate.update(update_client, FIRMWARE_URL, STR(FIRMWARE_VERSION));
373 switch(ret)
374 {
375 case HTTP_UPDATE_FAILED:
376 {
377 Serial.printf_P(PSTR("HTTP_UPDATE_FAILED Error (%d): %s\n"),
378 ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
379 String tmp = String("fwupdate error: ") + ESPhttpUpdate.getLastErrorString();
380 client.publish(mqtt_device_boot, tmp.c_str());
381 }
382 break;
383
384 case HTTP_UPDATE_NO_UPDATES:
385 Serial.printf_P(PSTR("HTTP_UPDATE_NO_UPDATES\n"));
386 client.publish(mqtt_device_boot, "fwupdate noupdates");
387 break;
388
389 case HTTP_UPDATE_OK:
390 Serial.printf_P(PSTR("HTTP_UPDATE_OK\n"));
391 client.publish(mqtt_device_boot, "fwupdate ok");
392 break;
393 }
394}