-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHOMELED.ino
511 lines (432 loc) · 22.3 KB
/
HOMELED.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
/*
Скетч создан на основе скетча AlexGyver
*/
#include "FastLED.h" // библиотека для работы с лентой
#include <Adafruit_CC3000.h>
#include <SPI.h>
#include "utility/debug.h"
#include "utility/socket.h"
#include <EEPROM.h>
#include "WIFI.h"
// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIVIDER); // you can change this clock speed
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY WLAN_SEC_WPA2
#define LISTEN_PORT 80 // What TCP port to listen on for connections.
// The HTTP protocol uses port 80 by default.
#define MAX_ACTION 64 // Maximum length of the HTTP action that can be parsed.
#define MAX_PATH 256 // Maximum length of the HTTP request path that can be parsed.
// There isn't much memory available so keep this short!
#define BUFFER_SIZE MAX_ACTION + MAX_PATH + 20 // Size of buffer for incoming request data.
// Since only the first line is parsed this
// needs to be as large as the maximum action
// and path plus a little for whitespace and
// HTTP version.
#define TIMEOUT_MS 200 // Amount of time in milliseconds to wait for
// an incoming request to finish. Don't set this
// too high or your server could be slow to respond.
#define LED_COUNT 135 // число светодиодов в кольце/ленте
#define LED_DT 6 // пин, куда подключен DIN ленты
int max_bright = 15; // максимальная яркость (0 - 255)
boolean adapt_light = 0; // адаптивная подсветка (1 - включить, 0 - выключить)
byte fav_modes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 15, 15, 33, 34, 15, 15, 37, 38, 39, 40, 41, 42, 43, 15, 15, 15 }; // список "любимых" режимов
byte num_modes = sizeof(fav_modes); // получить количество "любимых" режимов (они все по 1 байту..)
unsigned long change_time, last_change, last_bright;
int new_bright = 5;
volatile byte ledMode = 1;
/*
Стартовый режим
0 - все выключены
1 - все включены
3 - кольцевая радуга
888 - демо-режим
*/
// цвета мячиков для режима
byte ballColors[3][3] = {
{0xff, 0, 0},
{0xff, 0xff, 0xff},
{0 , 0 , 0xff}
};
// ---------------СЛУЖЕБНЫЕ ПЕРЕМЕННЫЕ-----------------
int BOTTOM_INDEX = 0; // светодиод начала отсчёта
int TOP_INDEX = int(LED_COUNT / 2);
int EVENODD = LED_COUNT % 2;
struct CRGB leds[LED_COUNT];
int ledsX[LED_COUNT][3]; //-ARRAY FOR COPYING WHATS IN THE LED STRIP CURRENTLY (FOR CELL-AUTOMATA, MARCH, ETC)
int thisdelay = 20; //-FX LOOPS DELAY VAR
int thisstep = 10; //-FX LOOPS DELAY VAR
int thishue = 0; //-FX LOOPS DELAY VAR
int thissat = 255; //-FX LOOPS DELAY VAR
int thisindex = 0;
int thisRED = 0;
int thisGRN = 0;
int thisBLU = 0;
int idex = 0; //-LED INDEX (0 to LED_COUNT-1
int ihue = 0; //-HUE (0-255)
int ibright = 0; //-BRIGHTNESS (0-255)
int isat = 0; //-SATURATION (0-255)
int bouncedirection = 0; //-SWITCH FOR COLOR BOUNCE (0-1)
float tcount = 0.0; //-INC VAR FOR SIN LOOPS
int lcount = 0; //-ANOTHER COUNTING VAR
boolean changeFlag;
// ---------------СЛУЖЕБНЫЕ ПЕРЕМЕННЫЕ-----------------
// ------------------СЕРВЕР----------------------------
Adafruit_CC3000_Server httpServer(LISTEN_PORT);
uint8_t buffer[BUFFER_SIZE + 1];
int bufindex = 0;
char action[MAX_ACTION + 1];
char path[MAX_PATH + 1];
String ipAddr = "192.168.1.111";
// ------------------СЕРВЕР----------------------------
void setup()
{
Serial.begin(115200); // открыть порт для связи
Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
// Initialise the module
Serial.println(F("\nInitializing..."));
if (!cc3000.begin())
{
Serial.println(F("Couldn't begin()! Check your wiring?"));
while (1);
}
Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID);
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
Serial.println(F("Failed!"));
while (1);
}
Serial.println(F("Connected!"));
Serial.println(F("Request DHCP"));
while (!cc3000.checkDHCP())
{
delay(100); // ToDo: Insert a DHCP timeout!
}
// Display the IP address DNS, Gateway, etc.
while (! displayConnectionDetails()) {
delay(1000);
}
// Start listening for connections
httpServer.begin();
Serial.println(F("Listening for connections..."));
LEDS.setBrightness(new_bright); // ограничить максимальную яркость
LEDS.addLeds<WS2812, LED_DT, GRB>(leds, LED_COUNT); // настрйоки для нашей ленты (ленты на WS2811, WS2812, WS2812B)
one_color_all(0, 0, 0); // погасить все светодиоды
LEDS.show(); // отослать команду
EEPROM.get(0, ledMode);
Serial.println("setup ready");
}
void one_color_all(int cred, int cgrn, int cblu) { //-SET ALL LEDS TO ONE COLOR
for (int i = 0 ; i < LED_COUNT; i++ ) {
leds[i].setRGB( cred, cgrn, cblu);
}
}
uint32_t myTimer1;
void loop() {
if (millis() - myTimer1 >= 100) { // таймер на 100 мс (10 раз в сек)
myTimer1 = millis(); // сброс таймера
parseClient();
return;
}
if (millis() - last_bright > 500) {
last_bright = millis(); // сброить таймер
LEDS.setBrightness(new_bright); // установить новую яркость
return;
}
/*
if (Serial.available() > 0) { // если что то прислали
ledMode = Serial.parseInt(); // парсим в тип данных int
change_mode(ledMode); // меняем режим через change_mode (там для каждого режима стоят цвета и задержки)
}
*/
switch (ledMode) {
case 2: rainbow_fade(); break; // плавная смена цветов всей ленты
case 3: rainbow_loop(); break; // крутящаяся радуга
case 4: random_burst(); break; // случайная смена цветов
case 5: color_bounce(); break; // бегающий светодиод
case 6: color_bounceFADE(); break; // бегающий паровозик светодиодов
case 7: ems_lightsONE(); break; // вращаются красный и синий
case 8: ems_lightsALL(); break; // вращается половина красных и половина синих
case 9: flicker(); break; // случайный стробоскоп
case 10: pulse_one_color_all(); break; // пульсация одним цветом
case 11: pulse_one_color_all_rev(); break; // пульсация со сменой цветов
case 12: fade_vertical(); break; // плавная смена яркости по вертикали (для кольца)
case 13: rule30(); break; // безумие красных светодиодов
case 14: random_march(); break; // безумие случайных цветов
case 15: rwb_march(); break; // белый синий красный бегут по кругу (ПАТРИОТИЗМ!)
case 16: radiation(); break; // пульсирует значок радиации
case 17: color_loop_vardelay(); break; // красный светодиод бегает по кругу
case 18: white_temps(); break; // бело синий градиент (?)
case 19: sin_bright_wave(); break; // тоже хрень какая то
case 20: pop_horizontal(); break; // красные вспышки спускаются вниз
case 21: quad_bright_curve(); break; // полумесяц
case 22: flame(); break; // эффект пламени
case 23: rainbow_vertical(); break; // радуга в вертикаьной плоскости (кольцо)
case 24: pacman(); break; // пакман
case 25: random_color_pop(); break; // безумие случайных вспышек
case 26: ems_lightsSTROBE(); break; // полицейская мигалка
case 27: rgb_propeller(); break; // RGB пропеллер
case 28: kitt(); break; // случайные вспышки красного в вертикаьной плоскости
case 29: matrix(); break; // зелёненькие бегают по кругу случайно
case 30: new_rainbow_loop(); break; // крутая плавная вращающаяся радуга
case 31: strip_march_ccw(); break; // чёт сломалось
case 32: strip_march_cw(); break; // чёт сломалось
case 33: colorWipe(0x00, 0xff, 0x00, thisdelay);
colorWipe(0x00, 0x00, 0x00, thisdelay); break; // плавное заполнение цветом
case 34: CylonBounce(0xff, 0, 0, 4, 10, thisdelay); break; // бегающие светодиоды
case 35: Fire(55, 120, thisdelay); break; // линейный огонь
case 36: NewKITT(0xff, 0, 0, 8, 10, thisdelay); break; // беготня секторов круга (не работает)
case 37: rainbowCycle(thisdelay); break; // очень плавная вращающаяся радуга
case 38: TwinkleRandom(20, thisdelay, 1); break; // случайные разноцветные включения (1 - танцуют все, 0 - случайный 1 диод)
case 39: RunningLights(0xff, 0xff, 0x00, thisdelay); break; // бегущие огни
case 40: Sparkle(0xff, 0xff, 0xff, thisdelay); break; // случайные вспышки белого цвета
case 41: SnowSparkle(0x10, 0x10, 0x10, thisdelay, random(100, 1000)); break; // случайные вспышки белого цвета на белом фоне
case 42: theaterChase(0xff, 0, 0, thisdelay); break; // бегущие каждые 3 (ЧИСЛО СВЕТОДИОДОВ ДОЛЖНО БЫТЬ КРАТНО 3)
case 43: theaterChaseRainbow(thisdelay); break; // бегущие каждые 3 радуга (ЧИСЛО СВЕТОДИОДОВ ДОЛЖНО БЫТЬ КРАТНО 3)
case 44: Strobe(0xff, 0xff, 0xff, 10, thisdelay, 1000); break; // стробоскоп
case 45: BouncingBalls(0xff, 0, 0, 3); break; // прыгающие мячики
case 46: BouncingColoredBalls(3, ballColors); break; // прыгающие мячики цветные
}
}
void change_mode(int newmode) {
thissat = 255;
switch (newmode) {
case 0: one_color_all(0, 0, 0); LEDS.show(); break; //---ALL OFF
case 1: one_color_all(255, 255, 255); LEDS.show(); break; //---ALL ON
case 2: thisdelay = 60; break; //---STRIP RAINBOW FADE
case 3: thisdelay = 20; thisstep = 10; break; //---RAINBOW LOOP
case 4: thisdelay = 20; break; //---RANDOM BURST
case 5: thisdelay = 20; thishue = 0; break; //---CYLON v1
case 6: thisdelay = 80; thishue = 0; break; //---CYLON v2
case 7: thisdelay = 40; thishue = 0; break; //---POLICE LIGHTS SINGLE
case 8: thisdelay = 40; thishue = 0; break; //---POLICE LIGHTS SOLID
case 9: thishue = 160; thissat = 50; break; //---STRIP FLICKER
case 10: thisdelay = 15; thishue = 0; break; //---PULSE COLOR BRIGHTNESS
case 11: thisdelay = 30; thishue = 0; break; //---PULSE COLOR SATURATION
case 12: thisdelay = 60; thishue = 180; break; //---VERTICAL SOMETHING
case 13: thisdelay = 100; break; //---CELL AUTO - RULE 30 (RED)
case 14: thisdelay = 80; break; //---MARCH RANDOM COLORS
case 15: thisdelay = 80; break; //---MARCH RWB COLORS
case 16: thisdelay = 60; thishue = 95; break; //---RADIATION SYMBOL
//---PLACEHOLDER FOR COLOR LOOP VAR DELAY VARS
case 19: thisdelay = 35; thishue = 180; break; //---SIN WAVE BRIGHTNESS
case 20: thisdelay = 100; thishue = 0; break; //---POP LEFT/RIGHT
case 21: thisdelay = 100; thishue = 180; break; //---QUADRATIC BRIGHTNESS CURVE
//---PLACEHOLDER FOR FLAME VARS
case 23: thisdelay = 50; thisstep = 15; break; //---VERITCAL RAINBOW
case 24: thisdelay = 50; break; //---PACMAN
case 25: thisdelay = 35; break; //---RANDOM COLOR POP
case 26: thisdelay = 25; thishue = 0; break; //---EMERGECNY STROBE
case 27: thisdelay = 100; thishue = 0; break; //---RGB PROPELLER
case 28: thisdelay = 100; thishue = 0; break; //---KITT
case 29: thisdelay = 100; thishue = 95; break; //---MATRIX RAIN
case 30: thisdelay = 15; break; //---NEW RAINBOW LOOP
case 31: thisdelay = 100; break; //---MARCH STRIP NOW CCW
case 32: thisdelay = 100; break; //---MARCH STRIP NOW CCW
case 33: thisdelay = 50; break; // colorWipe
case 34: thisdelay = 50; break; // CylonBounce
case 35: thisdelay = 15; break; // Fire
case 36: thisdelay = 50; break; // NewKITT
case 37: thisdelay = 20; break; // rainbowCycle
case 38: thisdelay = 10; break; // rainbowTwinkle
case 39: thisdelay = 50; break; // RunningLights
case 40: thisdelay = 0; break; // Sparkle
case 41: thisdelay = 30; break; // SnowSparkle
case 42: thisdelay = 50; break; // theaterChase
case 43: thisdelay = 50; break; // theaterChaseRainbow
case 44: thisdelay = 100; break; // Strobe
case 101: one_color_all(255, 0, 0); LEDS.show(); break; //---ALL RED
case 102: one_color_all(0, 255, 0); LEDS.show(); break; //---ALL GREEN
case 103: one_color_all(0, 0, 255); LEDS.show(); break; //---ALL BLUE
case 104: one_color_all(255, 255, 0); LEDS.show(); break; //---ALL COLOR X
case 105: one_color_all(0, 255, 255); LEDS.show(); break; //---ALL COLOR Y
case 106: one_color_all(255, 0, 255); LEDS.show(); break; //---ALL COLOR Z
}
bouncedirection = 0;
one_color_all(0, 0, 0);
ledMode = newmode;
}
// Return true if the buffer contains an HTTP request. Also returns the request
// path and action strings if the request was parsed. This does not attempt to
// parse any HTTP headers because there really isn't enough memory to process
// them all.
// HTTP request looks like:
// [method] [path] [version] \r\n
// Header_key_1: Header_value_1 \r\n
// ...
// Header_key_n: Header_value_n \r\n
// \r\n
bool parseRequest(uint8_t* buf, int bufSize, char* action, char* path) {
// Check if the request ends with \r\n to signal end of first line.
if (bufSize < 2)
return false;
if (buf[bufSize - 2] == '\r' && buf[bufSize - 1] == '\n') {
parseFirstLine((char*)buf, action, path);
return true;
}
return false;
}
// Parse the action and path from the first line of an HTTP request.
void parseFirstLine(char* line, char* action, char* path) {
// Parse first word up to whitespace as action.
char* lineaction = strtok(line, " ");
if (lineaction != NULL)
strncpy(action, lineaction, MAX_ACTION);
// Parse second word up to whitespace as path.
char* linepath = strtok(NULL, " /");
if (linepath != NULL) {
strncpy(path, linepath, MAX_PATH);
}
}
String ipToStr(uint32_t& ip)
{
String ipStr;
ipStr += ((ip >> 24) & 0xff);
ipStr += F(".");
ipStr += ((ip >> 16) & 0xff);
ipStr += F(".");
ipStr += ((ip >> 8) & 0xff);
ipStr += F(".");
ipStr += (ip & 0xff);
return ipStr;
}
// Tries to read the IP address and other connection details
bool displayConnectionDetails(void)
{
uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
if (!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
{
Serial.println(F("Unable to retrieve the IP Address!\r\n"));
return false;
}
else
{
ipAddr = ipToStr(ipAddress);
Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
Serial.println();
return true;
}
}
void parseClient() {
// Try to get a client which is connected.
Adafruit_CC3000_ClientRef client = httpServer.available();
if (client) {
//Serial.println(F("Client connected."));
// Process this request until it completes or times out.
// Note that this is explicitly limited to handling one request at a time!
// Clear the incoming data buffer and point to the beginning of it.
bufindex = 0;
memset(&buffer, 0, sizeof(buffer));
// Clear action and path strings.
memset(&action, 0, sizeof(action));
memset(&path, 0, sizeof(path));
// Set a timeout for reading all the incoming data.
unsigned long endtime = millis() + TIMEOUT_MS;
// Read all the incoming data until it can be parsed or the timeout expires.
bool parsed = false;
while (!parsed && (millis() < endtime) && (bufindex < BUFFER_SIZE)) {
if (client.available()) {
buffer[bufindex++] = client.read();
}
parsed = parseRequest(buffer, bufindex, action, path);
}
// Handle the request if it was parsed.
if (parsed && strcmp(path, "favicon.ico") != 0) {
Serial.println(F("Processing request"));
Serial.print(F("Action: ")); Serial.println(action);
Serial.print(F("Path: ")); Serial.println(path);
// Check the action to see if it was a GET request.
if (strcmp(action, "GET") == 0) {
// Respond with the path that was accessed.
// First send the success response code.
client.fastrprintln(F("HTTP/1.1 200 OK"));
// Then send a few headers to identify the type of data returned and that
// the connection will not be held open.
client.fastrprintln(F("Content-Type: text/html; charset=utf-8"));
client.fastrprintln(F("Connection: close"));
client.fastrprintln(F("Server: Adafruit CC3000"));
// Send an empty line to signal start of body.
client.fastrprintln(F(""));
// Now send the response data.
client.fastrprintln(F("<html>"));
client.fastrprintln(F("<style>button { margin-bottom: 4px; width: 100%; min-height: 100px; font-weight: bold; font-size: xx-large; }</style>"));
String btnOn = "";
getBtnTxt("ON", "ВКЛ", btnOn);
client.fastrprintln(btnOn.c_str());
String btnOff = "";
getBtnTxt("OFF", "ВЫКЛ", btnOff);
client.fastrprintln(btnOff.c_str());
String btnPlus = "";
getBtnTxt("PLUS", "+", btnPlus);
client.fastrprintln(btnPlus.c_str());
String btnMinus = "";
getBtnTxt("MINUS", "-", btnMinus);
client.fastrprintln(btnMinus.c_str());
for (int i = 1; i < num_modes - 2; i++) {
String href(i);
String text(i);
String btn = "";
getBtnTxt(href, text, btn);
client.fastrprintln(btn.c_str());
}
client.fastrprintln(F("</html>"));
int newMode = atoi(path);
bool needChange = false;
Serial.println(newMode);
if (strcmp(path, "PLUS") == 0 && new_bright < max_bright) {
new_bright += 5;
}
if (strcmp(path, "MINUS") == 0 && new_bright > 5) {
new_bright -= 5;
}
if (strcmp(path, "ON") == 0) {
newMode = 1;
needChange = true;
} else if (strcmp(path, "OFF") == 0) {
newMode = 0;
needChange = true;
} else {
newMode = atoi(path) + 1;
needChange = (newMode >= 2);
}
if (needChange && newMode < num_modes) {
int ledMode = fav_modes[newMode]; // получаем новый номер следующего режима
Serial.println(ledMode);
EEPROM.put(0, ledMode);
change_mode(ledMode); // меняем режим через change_mode (там для каждого режима стоят цвета и задержки)
changeFlag = true;
}
}
else {
// Unsupported action, respond with an HTTP 405 method not allowed error.
client.fastrprintln(F("HTTP/1.1 405 Method Not Allowed"));
client.fastrprintln(F(""));
}
}
// Wait a short period to make sure the response had time to send before
// the connection is closed (the CC3000 sends data asyncronously).
delay(100);
// Close the connection when done.
Serial.println(F("Client disconnected"));
client.close();
Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
}
}
void getBtnTxt(const String& href, const String& text, String& btn) {
btn += F("<br><a href=\"http://");
btn += ipAddr;
btn += F("/");
btn += href;
btn += F("\"><button>");
btn += text;
btn += F("</button></a>");
}