Czołem majsterkowicze!
Dzisiaj chciałbym Wam pokazać jak zrobiłem internetowy sterownik do taśm LEDowyh.
Wstępu słów kilka…
Ostatnimi czasy nabyłem drogą kupna taśmę LEDową. Zamontowałem ją na szafkach i po pierwszym tygodniu użytkowania stwierdziłem występowanie dwóch problemów, chodzi o sposób sterowania kolorami taśmy. Sterownik, który umieściłem pod szafką nie zawsze wyłapuje polecenia wydawane pilotem, przez co często trzeba się nagimnastykować, żeby np. wyłączyć taśmę. Będąc przy temacie pilota to on jest drugim problemem. Zazwyczaj, gdy jest mi potrzebny leży gdzieś w drugim końcu pokoju przykryty książkami.
Postanowiłem coś z tym zrobić. Zainspirowany artykułem Łukasza o analogowym liczniku majsterkowiczów, wyciągnąłem z szuflady ESP-8266, które kiedyś dawno temu kupiłem żeby zobaczyć jego możliwości (z resztą takim sposobem uzbierała się cała skrzynia modułów do Arduino). Założenia były proste. Postawić na ESP-8266 stronę, która by sterowała LEDami.
A więc , co wykorzystałem?
- NodeMCU czyli ESP-8266 z programatorem (równie dobrze się nada to czy to)
- dioda IR
- przetwornica 12V na 3.3V lub 12V na 5V (ładowarka samochodowa USB)
- gniazdo dc, wtyczka dc, rezystor
- pudełko po dużych Tic Tac’ach
Część 1: Projekt i testy
Krok 1
Sprawdziłem, czy NodeMCU nie ma problemów z wysyłaniem kodów za pomocą podczerwieni. Z tego co kojarzę oryginalna biblioteka IRremote z Arduino nie działała poprawnie. Na szczęście jakiś mądry człowiek przygotował wersję kompatybilną z ESP-8266, jest tutaj.
Krok 2
Sprawdziłem w jaki sposób można wydawać polecenia do mikrokontrolera za pomocą strony oraz czy NodeMCU nie ma problemów z hostowaniem stron HTML + CSS. Co do drugiej części ostatniego zdania, to nie mam zapisanych żadnych szkiców, którymi to sprawdziłem. Musicie mi uwierzyć na słowo, że działa. A wracając do tego wydawania poleceń to tutaj jest odpowiedni przykład (pozwolę sobie wkleić kod, który pochodzi z tej strony).
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 |
/********* Rui Santos Complete project details at http://randomnerdtutorials.com *********/ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> MDNSResponder mdns; // Replace with your network credentials const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASSWORD"; ESP8266WebServer server(80); String webPage = ""; int gpio0_pin = 0; int gpio2_pin = 2; void setup(void){ webPage += "<h1>ESP8266 Web Server</h1><p>Socket #1 <a href=\"socket1On\"><button>ON</button></a> <a href=\"socket1Off\"><button>OFF</button></a></p>"; webPage += "<p>Socket #2 <a href=\"socket2On\"><button>ON</button></a> <a href=\"socket2Off\"><button>OFF</button></a></p>"; // preparing GPIOs pinMode(gpio0_pin, OUTPUT); digitalWrite(gpio0_pin, LOW); pinMode(gpio2_pin, OUTPUT); digitalWrite(gpio2_pin, LOW); delay(1000); Serial.begin(115200); WiFi.begin(ssid, password); Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); if (mdns.begin("esp8266", WiFi.localIP())) { Serial.println("MDNS responder started"); } server.on("/", [](){ server.send(200, "text/html", webPage); }); server.on("/socket1On", [](){ server.send(200, "text/html", webPage); digitalWrite(gpio0_pin, HIGH); delay(1000); }); server.on("/socket1Off", [](){ server.send(200, "text/html", webPage); digitalWrite(gpio0_pin, LOW); delay(1000); }); server.on("/socket2On", [](){ server.send(200, "text/html", webPage); digitalWrite(gpio2_pin, HIGH); delay(1000); }); server.on("/socket2Off", [](){ server.send(200, "text/html", webPage); digitalWrite(gpio2_pin, LOW); delay(1000); }); server.begin(); Serial.println("HTTP server started"); } void loop(void){ server.handleClient(); } |
To jest kod na którym budowałem swój projekt.
Chciałbym wyjaśnić jak okodować sterowanie Arduino za pomocą strony www. Poniższy przykład prezentuje dokładnie tę samą zasadę działania co kod wyżej, różni się nazwami zmiennych.
Powiedzmy że mamy kod HTML’a
1 |
<a href="/klikniety"><button>Wciśnij mnie</button></a> |
Tworzy on przycisk z napisem “Wciśnij mnie”. Po jego kliknięciu przenosimy się do podstrony /klikniety
Od strony Arduino mechanikę witryny kodujemy dla każdej podstrony osobno dla /klikniety będzie to wyglądało tak:
1 2 3 |
server.on("/klikniety", [](){ server.send(200, "text/plain", "kliknąłeś przycisk"); }); |
W wypadku naciśnięcia przycisku zostaniemy przeniesieni na podstronę /klikniety, która zawiera napis “kliknąłeś przycisk”.
Krok 3
Przygotowałem stronę, która służy do sterowania LEDami. Zamysł był taki, żeby wyglądała prawie jak oryginalny pilot do tej taśmy. Może to nie jest odwzorowanie 1:1, ale uważam że nie jest źle.
Tak prezentuje się jej kod
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 |
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>LED CONTROLLER</title> <link href="https://fonts.googleapis.com/css?family=Lato:400,900&subset=latin-ext" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <style> button { float: left; width: 60px; height: 60px; font-size: 15px; margin: 5px; border-radius: 30px; -webkit-transition-duration: 0.4s; /* Safari */ transition-duration: 0.2s; cursor: pointer; text-align: center; font-family: 'Lato', sans-serif; font-weight: bold; outline:none; border: none; color:white; } #container { max-width: 280px; margin: auto; margin-top: 50px; background-color: #BDB7AA; border: 2px solid #AAB0BD; border-radius: 15px; padding: 5px; padding-top: 20px; padding-bottom: 20px; margin-top: 20px; } .power { background-color: white; color: black; } .power:hover { border: 2px solid black; color: black; } #off { background-color: black; color: white; } #off:hover { background-color: white; border: 2px solid black; color: black; } #on { background-color: red; color: white; } #on:hover { background-color: white; border: 2px solid red; color: black; } #red { background-color: #FF191B; } #red:hover { background-color: white; border: 2px solid #FF191B; color: black; } #red1 { background-color: #FF5319; } #red1:hover { background-color: white; border: 2px solid #FF5319; } #red2 { background-color: #FF6A5E; } #red2:hover { background-color: white; border: 2px solid #FF6A5E; } #red3 { background-color: #FF926B; } #red3:hover { background-color: white; border: 2px solid #FF926B; } #red4 { background-color: #F3F62F; } #red4:hover { background-color: white; border: 2px solid #F3F62F; } #green { background-color: #288F00; } #green:hover { background-color: white; border: 2px solid #288F00; color: black; } #green1 { background-color: #3CD45F; } #green1:hover { background-color: white; border: 2px solid #3CD45F; color: black; } #green2 { background-color: #47E3C6; } #green2:hover { background-color: white; border: 2px solid #47E3C6; color: black; } #green3 { background-color: #44C5DE; } #green3:hover { background-color: white; border: 2px solid #44C5DE; } #green4 { background-color: #289AE3; } #green4:hover { background-color: white; border: 2px solid #289AE3; color: black; } #blue { background-color: #122B9C; } #blue:hover { background-color: white; border: 2px solid #122B9C; color: black; } #blue1 { background-color: #6C6CD4; } #blue1:hover { background-color: white; border: 2px solid #6C6CD4; color: black; } #blue2 { background-color: #5D2AE3; } #blue2:hover { background-color: white; border: 2px solid #5D2AE3; color: black; } #blue3 { background-color: #9025DE; } #blue3:hover { background-color: white; border: 2px solid #9025DE; color: black; } #blue4 { background-color: #BE11E3; } #blue4:hover { background-color: white; border: 2px solid #BE11E3; color: black; } #white { background-color: white; color: black; } #white:hover { background-color: white; border: 2px solid black; color: black; } .function { background-color: #5A6170; font-size: 10px; } .function:hover { background-color: white; border: 2px solid #5A6170; color: black; font-size: 10px; } </style> </head> <body> <div id="container"> <a href="lightup"><button class="power"><i class="material-icons">brightness_5</i></button></a> <a href="lightdown"><button class="power"><i class="material-icons">brightness_3</i></button></a> <a href="off"><button id="off"><i class="material-icons">lightbulb_outline</i></button></a> <a href="on"><button id="on"><i class="material-icons">wb_incandescent</i></button></a> <div style="clear : both"></div> <a href="red"><button id="red">R</button></a> <a href="green"><button id="green">G</button></a> <a href="blue"><button id="blue">B</button></a> <a href="white"><button id="white">W</button></a> <div style="clear : both"></div> <a href="red1"><button id="red1"></button></a> <a href="green1"><button id="green1"></button></a> <a href="blue1"><button id="blue1"></button></a> <a href="flash"><button class="function">FLASH</button></a> <div style="clear : both"></div> <a href="red2"><button id="red2"></button></a> <a href="green2"><button id="green2"></button></a> <a href="blue2"><button id="blue2"></button></a> <a href="strobe"><button class="function">STROBE</button></a> <div style="clear : both"></div> <a href="red3"><button id="red3"></button></a> <a href="green3"><button id="green3"></button></a> <a href="blue3"><button id="blue3"></button></a> <a href="fade"><button class="function">FADE</button></a> <div style="clear : both"></div> <a href="red4"><button id="red4"></button></a> <a href="green4"><button id="green4"></button></a> <a href="blue4"><button id="blue4"></button></a> <a href="smooth"><button class="function">SMOOTH</button></a> <div style="clear : both"></div> </div> </body> </html> |
a tak sama strona po załadowaniu w przeglądarce.
Krok 4
Teraz trzeba zorganizować kody IR pasujące do sterownika. Po szybkim googlowaniu przed zabraniem się do jakiejkolwiek pracy związanej z tym projektem znalazłem tę stronę. Jakiś bardzo dobry ludek wstawił na nią odczytane kody z pilota. Tak one wyglądają (idealnie przygotowane do wrzucenia do Arduino).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#define IR_BPLUS 0xF700FF // #define IR_BMINUS 0xF7807F // #define IR_OFF 0xF740BF // #define IR_ON 0xF7C03F // #define IR_R 0xF720DF // #define IR_G 0xF7A05F // #define IR_B 0xF7609F // #define IR_W 0xF7E01F // #define IR_B1 0xF710EF // #define IR_B2 0xF7906F // #define IR_B3 0xF750AF // #define IR_FLASH 0xF7D02F // #define IR_B4 0xF730CF // #define IR_B5 0xF7B04F // #define IR_B6 0xF7708F // #define IR_STROBE 0xF7F00F // #define IR_B7 0xF708F7 // #define IR_B8 0xF78877 // #define IR_B9 0xF748B7 // #define IR_FADE 0xF7C837 // #define IR_B10 0xF728D7 // #define IR_B11 0xF7A857 // #define IR_B12 0xF76897 // #define IR_SMOOTH 0xF7E817 // |
Aby nadać je z poziomu ESP-8266 trzeba mieć odpowiednią wersję biblioteki IRremote. W celu nadania któryś z kodów należy użyć takiego zapisu (może to nie jest prawda, że należy. Ja takiego użyłem. Jak jest jakiś inny sposób to korzystajcie z którego chcecie ;) )
1 |
irsend.sendNEC(IR_BPLUS, 32); |
Zapis “IR_BPLUS” możemy oczywiście zmienić na inny z listy wrzuconej wyżej. Oczywiście potrzebny jest cały szkic, żeby to zadziałało, a tak się składa, że mam takowy zapisany. Taki jakby “Blink” tylko na taśmie LEDowej ;)
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 |
#define IR_BPLUS 0xF700FF #define IR_BMINUS 0xF7807F #define IR_OFF 0xF740BF #define IR_ON 0xF7C03F #define IR_R 0xF720DF #define IR_G 0xF7A05F #define IR_B 0xF7609F #define IR_W 0xF7E01F #define IR_B1 0xF710EF #define IR_B2 0xF7906F #define IR_B3 0xF750AF #define IR_FLASH 0xF7D02F #define IR_B4 0xF730CF #define IR_B5 0xF7B04F #define IR_B6 0xF7708F #define IR_STROBE 0xF7F00F #define IR_B7 0xF708F7 #define IR_B8 0xF78877 #define IR_B9 0xF748B7 #define IR_FADE 0xF7C837 #define IR_B10 0xF728D7 #define IR_B11 0xF7A857 #define IR_B12 0xF76897 #define IR_SMOOTH 0xF7E817 #include <IRremoteESP8266.h> IRsend irsend(4); void setup() { irsend.begin(); } void loop() { irsend.sendNEC(IR_ON, 32); delay(5000); irsend.sendNEC(IR_OFF, 32); delay(5000); } |
Zapomniałem, że jeszcze trzeba podłączyć diodę IR. Tutaj jest łopatologiczny “schemat”.
Krok 5
Zostało tylko złożenie tych kodów “do kupy” i wszystko powinno śmigać. Tak wygląda napisany przeze mnie kod. Są przy nim ładne komentarze, więc myślę, że nie muszę się rozpisywać.
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 |
/********* Oprogramowanie napisane przez: Mateusz Jaros Szczegły projektu na www.majsterkowo.pl, wyszukaj Kontroler LED WiFi *********/ /* Biblioteki */ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <IRremoteESP8266.h> /* Piny */ const int irPin = 4; // To jest 'GPIO4' (D2 na NodeMCU) /* Objekty */ MDNSResponder mdns; ESP8266WebServer server(80); IRsend irsend(irPin); /* Ustawienia sieciowe */ const char* ssid = "*********"; const char* password = "*********"; const char* device_name = "led"; // mozesz dostać sie na strone za pomoca np. http://led.local/ /* Strona internetowa Jezeli wrzucisz zawartosc strony do kodu tak: String webPage = R"=====(content of web page )====="; to nie musisz bac sie o tego typu znaki: ' " # < > / \ */ String webPage = R"=====( <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>LED CONTROLLER</title> <link href="https://fonts.googleapis.com/css?family=Lato:400,900&subset=latin-ext" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <style> button { float: left; width: 60px; height: 60px; font-size: 15px; margin: 5px; border-radius: 30px; -webkit-transition-duration: 0.4s; /* Safari */ transition-duration: 0.2s; cursor: pointer; text-align: center; font-family: 'Lato', sans-serif; font-weight: bold; outline:none; border: none; color:white; } #container { max-width: 280px; margin: auto; margin-top: 50px; background-color: #BDB7AA; border: 2px solid #AAB0BD; border-radius: 15px; padding: 5px; padding-top: 20px; padding-bottom: 20px; margin-top: 20px; } .power { background-color: white; color: black; } .power:hover { border: 2px solid black; color: black; } #off { background-color: black; color: white; } #off:hover { background-color: white; border: 2px solid black; color: black; } #on { background-color: red; color: white; } #on:hover { background-color: white; border: 2px solid red; color: black; } #red { background-color: #FF191B; } #red:hover { background-color: white; border: 2px solid #FF191B; color: black; } #red1 { background-color: #FF5319; } #red1:hover { background-color: white; border: 2px solid #FF5319; } #red2 { background-color: #FF6A5E; } #red2:hover { background-color: white; border: 2px solid #FF6A5E; } #red3 { background-color: #FF926B; } #red3:hover { background-color: white; border: 2px solid #FF926B; } #red4 { background-color: #F3F62F; } #red4:hover { background-color: white; border: 2px solid #F3F62F; } #green { background-color: #288F00; } #green:hover { background-color: white; border: 2px solid #288F00; color: black; } #green1 { background-color: #3CD45F; } #green1:hover { background-color: white; border: 2px solid #3CD45F; color: black; } #green2 { background-color: #47E3C6; } #green2:hover { background-color: white; border: 2px solid #47E3C6; color: black; } #green3 { background-color: #44C5DE; } #green3:hover { background-color: white; border: 2px solid #44C5DE; } #green4 { background-color: #289AE3; } #green4:hover { background-color: white; border: 2px solid #289AE3; color: black; } #blue { background-color: #122B9C; } #blue:hover { background-color: white; border: 2px solid #122B9C; color: black; } #blue1 { background-color: #6C6CD4; } #blue1:hover { background-color: white; border: 2px solid #6C6CD4; color: black; } #blue2 { background-color: #5D2AE3; } #blue2:hover { background-color: white; border: 2px solid #5D2AE3; color: black; } #blue3 { background-color: #9025DE; } #blue3:hover { background-color: white; border: 2px solid #9025DE; color: black; } #blue4 { background-color: #BE11E3; } #blue4:hover { background-color: white; border: 2px solid #BE11E3; color: black; } #white { background-color: white; color: black; } #white:hover { background-color: white; border: 2px solid black; color: black; } .function { background-color: #5A6170; font-size: 10px; } .function:hover { background-color: white; border: 2px solid #5A6170; color: black; font-size: 10px; } </style> </head> <body> <div id="container"> <a href="lightup"><button class="power"><i class="material-icons">brightness_5</i></button></a> <a href="lightdown"><button class="power"><i class="material-icons">brightness_3</i></button></a> <a href="off"><button id="off"><i class="material-icons">lightbulb_outline</i></button></a> <a href="on"><button id="on"><i class="material-icons">wb_incandescent</i></button></a> <div style="clear : both"></div> <a href="red"><button id="red">R</button></a> <a href="green"><button id="green">G</button></a> <a href="blue"><button id="blue">B</button></a> <a href="white"><button id="white">W</button></a> <div style="clear : both"></div> <a href="red1"><button id="red1"></button></a> <a href="green1"><button id="green1"></button></a> <a href="blue1"><button id="blue1"></button></a> <a href="flash"><button class="function">FLASH</button></a> <div style="clear : both"></div> <a href="red2"><button id="red2"></button></a> <a href="green2"><button id="green2"></button></a> <a href="blue2"><button id="blue2"></button></a> <a href="strobe"><button class="function">STROBE</button></a> <div style="clear : both"></div> <a href="red3"><button id="red3"></button></a> <a href="green3"><button id="green3"></button></a> <a href="blue3"><button id="blue3"></button></a> <a href="fade"><button class="function">FADE</button></a> <div style="clear : both"></div> <a href="red4"><button id="red4"></button></a> <a href="green4"><button id="green4"></button></a> <a href="blue4"><button id="blue4"></button></a> <a href="smooth"><button class="function">SMOOTH</button></a> <div style="clear : both"></div> </div> </body> </html> )====="; /* Kody IR */ #define IR_BPLUS 0xF700FF #define IR_BMINUS 0xF7807F #define IR_OFF 0xF740BF #define IR_ON 0xF7C03F #define IR_R 0xF720DF #define IR_G 0xF7A05F #define IR_B 0xF7609F #define IR_W 0xF7E01F #define IR_B1 0xF710EF #define IR_B2 0xF7906F #define IR_B3 0xF750AF #define IR_FLASH 0xF7D02F #define IR_B4 0xF730CF #define IR_B5 0xF7B04F #define IR_B6 0xF7708F #define IR_STROBE 0xF7F00F #define IR_B7 0xF708F7 #define IR_B8 0xF78877 #define IR_B9 0xF748B7 #define IR_FADE 0xF7C837 #define IR_B10 0xF728D7 #define IR_B11 0xF7A857 #define IR_B12 0xF76897 #define IR_SMOOTH 0xF7E817 void setup(void){ delay(1000); /* Uruchamianie kilku (nie)waznych rzeczy */ Serial.begin(115200); WiFi.begin(ssid, password); irsend.begin(); Serial.println(""); /* Czekanie na polaczenie z WiFi */ while(WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } /* Pokazanie kilku inforamcji o sieci na Serial Monitorze */ Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); /* Nadawanie specjalnej nazwy */ if(mdns.begin(device_name, WiFi.localIP())) { Serial.println("MDNS responder started"); } /* Pokazywanie odpowiedniej strony na podstawie URL i wysywlanie kodow IR */ server.on("/", [](){ server.send(200, "text/html", webPage); Serial.println("Loaded main page"); }); server.on("/lightup", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_BPLUS, 32); irsend.sendNEC(IR_BPLUS, 32); irsend.sendNEC(IR_BPLUS, 32); Serial.print("Pressed: "); Serial.println("lightup"); delay(1000); }); server.on("/lightdown", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_BMINUS, 32); irsend.sendNEC(IR_BMINUS, 32); irsend.sendNEC(IR_BMINUS, 32); Serial.print("Pressed: "); Serial.println("lightdown"); delay(1000); }); server.on("/off", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_OFF, 32); Serial.print("Pressed: "); Serial.println("off"); delay(1000); }); server.on("/on", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_ON, 32); Serial.print("Pressed: "); Serial.println("on"); delay(1000); }); server.on("/red", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_R, 32); Serial.print("Pressed: "); Serial.println("red"); delay(1000); }); server.on("/green", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_G, 32); Serial.print("Pressed: "); Serial.println("green"); delay(1000); }); server.on("/blue", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B, 32); Serial.print("Pressed: "); Serial.println("blue"); delay(1000); }); server.on("/white", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_W, 32); Serial.print("Pressed: "); Serial.println("white"); delay(1000); }); server.on("/red1", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B1, 32); Serial.print("Pressed: "); Serial.println("red1"); delay(1000); }); server.on("/green1", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B2, 32); Serial.print("Pressed: "); Serial.println("green1"); delay(1000); }); server.on("/blue1", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B3, 32); Serial.print("Pressed: "); Serial.println("blue1"); delay(1000); }); server.on("/flash", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_FLASH, 32); Serial.print("Pressed: "); Serial.println("flash"); delay(1000); }); server.on("/red2", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B4, 32); Serial.print("Pressed: "); Serial.println("red2"); delay(1000); }); server.on("/green2", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B5, 32); Serial.print("Pressed: "); Serial.println("green2"); delay(1000); }); server.on("/blue2", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B6, 32); Serial.print("Pressed: "); Serial.println("blue2"); delay(1000); }); server.on("/strobe", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_STROBE, 32); Serial.print("Pressed: "); Serial.println("strobe"); delay(1000); }); server.on("/red3", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B7, 32); Serial.print("Pressed: "); Serial.println("red3"); delay(1000); }); server.on("/green3", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B8, 32); Serial.print("Pressed: "); Serial.println("green3"); delay(1000); }); server.on("/blue3", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B9, 32); Serial.print("Pressed: "); Serial.println("blue3"); delay(1000); }); server.on("/fade", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_FADE, 32); Serial.print("Pressed: "); Serial.println("fade"); delay(1000); }); server.on("/red4", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B10, 32); Serial.print("Pressed: "); Serial.println("red4"); delay(1000); }); server.on("/green4", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B11, 32); Serial.print("Pressed: "); Serial.println("green4"); delay(1000); }); server.on("/blue4", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_B12, 32); Serial.print("Pressed: "); Serial.println("blue4"); delay(1000); }); server.on("/smooth", [](){ server.send(200, "text/html", webPage); irsend.sendNEC(IR_SMOOTH, 32); Serial.print("Pressed: "); Serial.println("smooth"); delay(1000); }); server.begin(); Serial.println("HTTP server started"); } void loop(void){ server.handleClient(); } |
Jest tylko jeden fragment, który bym chciał omówić. Chodzi o to:
1 2 3 |
if(mdns.begin(device_name, WiFi.localIP())) { Serial.println("MDNS responder started"); } |
Jest to uruchamianie usługi MDSN, która pozwala na dostęp do stronki za pomocą np. led.local/ . Jej konfiguracja ogranicza się do podania pierwszego członu adresu, czyli w tym wypadku led. Schowany jest on w zmiennej device_name.
Po wgraniu tego kodu do ESP-8266 wszystko nam się powinno ładnie uruchomić. Na serial monitorze dostaniemy adres IP do “pilota”. Prócz tego możemy wejść za pomocą adresu lokalnego (chyba tak to się nazywa) w tym (domyślnym) wypadku led.local/
Tak się kończy część pierwsza.
Część 2: Wykończenie projektu
W tej części pokażę Wam w jaki sposób sfinalizowałem ten projekt.
Moimi głównymi celami w momencie kończenia tego projektu były:
- zintegrowanie zasilania modułu z zasilaniem taśmy
- kompaktowe rozmiary
- bezpieczna obudowa czyli obudowa, która ochroni cienkie kable przed odkurzaczem.
Zacznijmy od zasilania.
Taśma działa na 12 voltach, ESP-8266 na 3.3 voltach, a moduł NodeMCU ma wbudowany regulator napięcia. Najłatwiej byłoby podłączyć taśmę pod złącze VIN na NodeMCU, ale nie znalazłem żadnej informacji jaki regulator napięcia posiada mój klon. Dlatego postawiłem na nieco bezpieczniejsze rozwiązanie, chodzi o zewnętrzny regulator napięcia. Jako że w moim pięknym mieście nie znalazłem regulatora napięcia 12V do 5V postanowiłem wykorzystać prostą ładowarkę samochodową. Tak oto się prezentuje po rozebraniu.
Tutaj bardzo “piękna” grafika przedstawiająca miejsca występowania napięć w MOJEJ ładowarce/przetwornicy.
Tak wygląda schemat podziału zasilania, jak i gotowej konstrukcji. Nie znalazłem we Fritzingu żadnej przetwornicy, więc zrobiłem prosty regulator napięcia.
Jeżeli ktoś nie zrozumiał podziału zasilania to już spieszę z wyjaśnieniem. Do gniazda DC podłączamy zasilacz do LEDów. Podłączona jest do niego wtyczka DC, dzięki której podłączamy zasilanie sterownikowi LEDów. Z gniazdka wyprowadzony jest też kabel do przetwornicy. Tak to się prezentuje w moim wykonaniu.
Obudowa
W miejscowych sklepach elektronicznych, nie znalazłem żadnej podobnej rozmiarowo obudowy do płytki NodeMCU, dlatego musiałem coś samemu wykombinować. W ręce wpadło mi pudełko po dużych TicTac’ach. Jak widać na załączonym zdjęciu rozmiarowo pasuje idealnie. (dla porównania wielkości kontroler do taśmy).
Naklejki zdjąłem ogrzewając je nad parą. Następnie zrobiłem dwa otwory. Jeden w górnej części, drugi od spodu. Ten większy specjalnie “wzbogaciłem” o wycięcie w stronę jednego z boków. Właśnie przez nie będzie wychodził kabel z wtyczką.
Pozostało jeszcze wszytko zlutować.
(Wstawiam zdjęcie LEDa podczerwonego, żeby było ciekawiej.)
Tak wygląda układ po przylutowaniu wszystkich modułów do mikrokontrolera.
Zostało tylko włożenie tego do obudowy i chyba gotowe. Od strony gniazda zasilania wszystko wygląda bardzo ładnie.
Trochę gorzej jest od strony pokrywki.
Znalazłem na to szybki patent. Przeciąłem w jednym miejscu oprawkę do LEDów i założyłem na kabel, następnie wcisnąłem do obudowy. Wygląda znacznie lepiej i nawet trochę ogranicza ruch przewodu.
I to by było tyle, gdyby nie jeden mankament jaki odkryłem. Płytka z mikrokontrolerem bardzo się w środku obudowy ruszała. Nie chciałem zostawić tak tego na pastwę losu, bo zaraz któryś z kabli byłby oderwany, albo by coś się spaliło od zwarcia. Nie chciałem też jej przyklejać, bo myślę nad rozbudową tego o dodatkowe możliwości. Dlatego zwinąłem w rurkę kawałek elastycznego plastiku (takiego ze sztywnej okładki do dokumentów) i włożyłem między NodeMCU, a obudowę. W ten sposób mikrokontroler jest dociśnięty do ścianek, a to uniemożliwia mu poruszanie się.
Na sam koniec wypadało by to pomalować, ale całość jest ukryta za szafką, więc tego nie widać jak wygląda.
Na tym gif’ie widać przykładowe działanie. (W niedługim czasie postaram się dodać film z efektem działania)
Update 27.12.2016
Postanowiłem zmienić dynamiczne przydzielanie adresu IP na jeden, statyczny. Dodałem również automatyczne uruchomienie taśmy po załadowaniu strony startowej. To wszystko zmiany jakie wprowadziłem po 3 miesiącach użytkowania :D.
Macie tutaj nowy kod!
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 |
/********* Oprogramowanie napisane przez: Mateusz Jaros Szczegły projektu na www.majsterkowo.pl, wyszukaj Kontroler LED WiFi *********/ /* Biblioteki */ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <IRremoteESP8266.h> /* Piny */ const int irPin = 4; // This is 'GPIO4' (D2 on NodeMCU) /* Ustawienia sieciowe */ const char* ssid = "*********"; const char* password = "*********"; const char* device_name = "led"; // mozesz dostać sie na strone za pomoca np. http://led.local/ IPAddress ip(192,168,1,111); // statyczny adsres IP po jakim chcesz się dostac na do pilota IPAddress gateway(192,168,1,1); // adres IP bramy domyslnej (routera) IPAddress subnet(255,255,255,0); // maska sieciowa /* Obiekty */ MDNSResponder mdns; ESP8266WebServer server(80); IRsend irsend(irPin); /* Strona internetowa Jezeli wrzucisz zawartosc strony do kodu tak: String webPage = R"=====(content of web page )====="; to nie musisz bac sie o tego typu znaki: ' " # < > / \ */ String webPage = R"=====( <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>LED CONTROLLER</title> <link href="https://fonts.googleapis.com/css?family=Lato:400,900&subset=latin-ext" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <style> button { float: left; width: 60px; height: 60px; font-size: 15px; margin: 5px; border-radius: 30px; -webkit-transition-duration: 0.4s; /* Safari */ transition-duration: 0.2s; cursor: pointer; text-align: center; font-family: 'Lato', sans-serif; font-weight: bold; outline:none; border: none; color:white; } #container { max-width: 280px; margin: auto; margin-top: 50px; background-color: #BDB7AA; border: 2px solid #AAB0BD; border-radius: 15px; padding: 5px; padding-top: 20px; padding-bottom: 20px; margin-top: 20px; } .power { background-color: white; color: black; } .power:hover { border: 2px solid black; color: black; } #off { background-color: black; color: white; } #off:hover { background-color: white; border: 2px solid black; color: black; } #on { background-color: red; color: white; } #on:hover { background-color: white; border: 2px solid red; color: black; } #red { background-color: #FF191B; } #red:hover { background-color: white; border: 2px solid #FF191B; color: black; } #red1 { background-color: #FF5319; } #red1:hover { background-color: white; border: 2px solid #FF5319; } #red2 { background-color: #FF6A5E; } #red2:hover { background-color: white; border: 2px solid #FF6A5E; } #red3 { background-color: #FF926B; } #red3:hover { background-color: white; border: 2px solid #FF926B; } #red4 { background-color: #F3F62F; } #red4:hover { background-color: white; border: 2px solid #F3F62F; } #green { background-color: #288F00; } #green:hover { background-color: white; border: 2px solid #288F00; color: black; } #green1 { background-color: #3CD45F; } #green1:hover { background-color: white; border: 2px solid #3CD45F; color: black; } #green2 { background-color: #47E3C6; } #green2:hover { background-color: white; border: 2px solid #47E3C6; color: black; } #green3 { background-color: #44C5DE; } #green3:hover { background-color: white; border: 2px solid #44C5DE; } #green4 { background-color: #289AE3; } #green4:hover { background-color: white; border: 2px solid #289AE3; color: black; } #blue { background-color: #122B9C; } #blue:hover { background-color: white; border: 2px solid #122B9C; color: black; } #blue1 { background-color: #6C6CD4; } #blue1:hover { background-color: white; border: 2px solid #6C6CD4; color: black; } #blue2 { background-color: #5D2AE3; } #blue2:hover { background-color: white; border: 2px solid #5D2AE3; color: black; } #blue3 { background-color: #9025DE; } #blue3:hover { background-color: white; border: 2px solid #9025DE; color: black; } #blue4 { background-color: #BE11E3; } #blue4:hover { background-color: white; border: 2px solid #BE11E3; color: black; } #white { background-color: white; color: black; } #white:hover { background-color: white; border: 2px solid black; color: black; } .function { background-color: #5A6170; font-size: 10px; } .function:hover { background-color: white; border: 2px solid #5A6170; color: black; font-size: 10px; } </style> </head> <body> <div id="container"> <a href="lightup"><button class="power"><i class="material-icons">brightness_5</i></button></a> <a href="lightdown"><button class="power"><i class="material-icons">brightness_3</i></button></a> <a href="off"><button id="off"><i class="material-icons">lightbulb_outline</i></button></a> <a href="on"><button id="on"><i class="material-icons">wb_incandescent</i></button></a> <div style="clear : both"></div> <a href="red"><button id="red">R</button></a> <a href="green"><button id="green">G</button></a> <a href="blue"><button id="blue">B</button></a> <a href="white"><button id="white">W</button></a> <div style="clear : both"></div> <a href="red1"><button id="red1"></button></a> <a href="green1"><button id="green1"></button></a> <a href="blue1"><button id="blue1"></button></a> <a href="flash"><button class="function">FLASH</button></a> <div style="clear : both"></div> <a href="red2"><button id="red2"></button></a> <a href="green2"><button id="green2"></button></a> <a href="blue2"><button id="blue2"></button></a> <a href="strobe"><button class="function">STROBE</button></a> <div style="clear : both"></div> <a href="red3"><button id="red3"></button></a> <a href="green3"><button id="green3"></button></a> <a href="blue3"><button id="blue3"></button></a> <a href="fade"><button class="function">FADE</button></a> <div style="clear : both"></div> <a href="red4"><button id="red4"></button></a> <a href="green4"><button id="green4"></button></a> <a href="blue4"><button id="blue4"></button></a> <a href="smooth"><button class="function">SMOOTH</button></a> <div style="clear : both"></div> </div> </body> </html> )====="; /* Kody IR */ #define IR_BPLUS 0xF700FF #define IR_BMINUS 0xF7807F #define IR_OFF 0xF740BF #define IR_ON 0xF7C03F #define IR_R 0xF720DF #define IR_G 0xF7A05F #define IR_B 0xF7609F #define IR_W 0xF7E01F #define IR_B1 0xF710EF #define IR_B2 0xF7906F #define IR_B3 0xF750AF #define IR_FLASH 0xF7D02F #define IR_B4 0xF730CF #define IR_B5 0xF7B04F #define IR_B6 0xF7708F #define IR_STROBE 0xF7F00F #define IR_B7 0xF708F7 #define IR_B8 0xF78877 #define IR_B9 0xF748B7 #define IR_FADE 0xF7C837 #define IR_B10 0xF728D7 #define IR_B11 0xF7A857 #define IR_B12 0xF76897 #define IR_SMOOTH 0xF7E817 void setup(void) { delay(1000); /* Uruchamianie kilku (nie)waznych rzeczy */ Serial.begin(115200); WiFi.begin(ssid, password); WiFi.config(ip, gateway, subnet); irsend.begin(); Serial.println(""); /* Czekanie na polaczenie z WiFi */ while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } /* Pokazanie kilku inforamcji o sieci na Serial Monitorze */ Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); /* Nadawanie specjalnej nazwy */ if (mdns.begin(device_name, WiFi.localIP())) { Serial.println("MDNS responder started"); } /* Pokazywanie odpowiedniej strony na podstawie URL i wysywlanie kodow IR */ server.on("/", []() { server.send(200, "text/html", webPage); Serial.println("Loaded main page"); irsend.sendNEC(IR_ON, 32); Serial.print("Pressed: "); Serial.println("on"); }); server.on("/lightup", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_BPLUS, 32); irsend.sendNEC(IR_BPLUS, 32); irsend.sendNEC(IR_BPLUS, 32); Serial.print("Pressed: "); Serial.println("lightup"); delay(1000); }); server.on("/lightdown", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_BMINUS, 32); irsend.sendNEC(IR_BMINUS, 32); irsend.sendNEC(IR_BMINUS, 32); Serial.print("Pressed: "); Serial.println("lightdown"); delay(1000); }); server.on("/off", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_OFF, 32); Serial.print("Pressed: "); Serial.println("off"); delay(1000); }); server.on("/on", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_ON, 32); Serial.print("Pressed: "); Serial.println("on"); delay(1000); }); server.on("/red", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_R, 32); Serial.print("Pressed: "); Serial.println("red"); delay(1000); }); server.on("/green", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_G, 32); Serial.print("Pressed: "); Serial.println("green"); delay(1000); }); server.on("/blue", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B, 32); Serial.print("Pressed: "); Serial.println("blue"); delay(1000); }); server.on("/white", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_W, 32); Serial.print("Pressed: "); Serial.println("white"); delay(1000); }); server.on("/red1", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B1, 32); Serial.print("Pressed: "); Serial.println("red1"); delay(1000); }); server.on("/green1", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B2, 32); Serial.print("Pressed: "); Serial.println("green1"); delay(1000); }); server.on("/blue1", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B3, 32); Serial.print("Pressed: "); Serial.println("blue1"); delay(1000); }); server.on("/flash", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_FLASH, 32); Serial.print("Pressed: "); Serial.println("flash"); delay(1000); }); server.on("/red2", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B4, 32); Serial.print("Pressed: "); Serial.println("red2"); delay(1000); }); server.on("/green2", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B5, 32); Serial.print("Pressed: "); Serial.println("green2"); delay(1000); }); server.on("/blue2", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B6, 32); Serial.print("Pressed: "); Serial.println("blue2"); delay(1000); }); server.on("/strobe", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_STROBE, 32); Serial.print("Pressed: "); Serial.println("strobe"); delay(1000); }); server.on("/red3", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B7, 32); Serial.print("Pressed: "); Serial.println("red3"); delay(1000); }); server.on("/green3", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B8, 32); Serial.print("Pressed: "); Serial.println("green3"); delay(1000); }); server.on("/blue3", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B9, 32); Serial.print("Pressed: "); Serial.println("blue3"); delay(1000); }); server.on("/fade", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_FADE, 32); Serial.print("Pressed: "); Serial.println("fade"); delay(1000); }); server.on("/red4", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B10, 32); Serial.print("Pressed: "); Serial.println("red4"); delay(1000); }); server.on("/green4", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B11, 32); Serial.print("Pressed: "); Serial.println("green4"); delay(1000); }); server.on("/blue4", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_B12, 32); Serial.print("Pressed: "); Serial.println("blue4"); delay(1000); }); server.on("/smooth", []() { server.send(200, "text/html", webPage); irsend.sendNEC(IR_SMOOTH, 32); Serial.print("Pressed: "); Serial.println("smooth"); delay(1000); }); server.begin(); Serial.println("HTTP server started"); } void loop(void) { server.handleClient(); } |
Dzięki za uwagę i do następnego!
(Jakbyście znaleźli jakieś błędy, to w komentarzach pod spodem, możecie mnie poprawić ;) )
Bardzo fajnie wykonany projekt, daję 5 :D
Ktrybula: Dzięki wielkie :D
Leci 5tka.
Najbardziej przypadła mi gustownie wykonana strona do sterowania wyglądająca jak pilot. Sam jakiś czas temu stałem przed wyzwaniem zrobienia czegoś podobnego i skończyło się na zwykłych, prostokątnych przyciskach [*]. Powiedz mi, w jaki sposób ją wykonałeś i czy można to zrobić przez jakiś program, creator itd?
woysz: za dużo pana Zelenta się naoglądałem to taki wynik jest :P
a tak na serio to wrzuciłem kod HTMLa (razem z CSS) w artykule, więc jak chcesz więcej szczegółów to sobie go skopiuj i wklej do jakiegoś edytora i przeanalizuj. A tak z grubsza to postawiłem sobie cel: strona bardzo podobna do pilota. Zacząłem kodować, na początku były prostokątne przyciski w ramce, ale powoli krok po kroku stronka nabierała obecnych kształtów. Nie wiem co ci więcej powiedzieć. Próbowałem kiedyś korzystać z creatora od Googl’a ale jakoś szybko się poddałem.
Leci piąteczka i Główna :) Gratuluję fajnego projektu!
@Łukasz Więcek: dzięki Łukasz!
A tak przy okazji podesłałbyś mi kod rabatowy do Botlandu?
Motocyklista :D Jaros: Odezwij się na lukasz@majsterkowo.pl :)
Witam. Projekt ciekawy i wymagał trochę pracy. Większość projektów tego typu realizowana jest z wykorzystaniem serwera www, ok wiem dlaczego, ale dlaczego by nie wykorzystać UDP? Jest szybsze i mniej obciąża esp8266. Dlaczego wysyłasz kod ir Neca aż 3 razy po sobie? Kiedy wystarczyło raz, sam korzystam z kodów neca i wystarczy tylko raz. Dlaczego nie ma zaimplementowanego ustawiania nazwy sieci i hasła po za przeprogramowaniem? Dlaczego pozbyłeś się sterowania orginalnym pilotem? Implementacja odbiornika podczerwieni banalnie prosta. I czego mi tu najbardziej brakuje, można było dołożyć jakieś efekty.
krisp74: Postaram się jakoś szybko obronić:
1) serwer – bo to pierwszy projekt na ESP, nie znałem wtedy (i dalej UDP nic mi nie mówi) innych technologii
2) wysyłam tylko w dwóch konkretnych przypadkach: przyciski jaśniej i ciemniej. Korzystając ze zwykłego pilota kody są wysyłanie cały czas od wciśnięcia do puszczenia, na tak napisanej stronie jak tu, nie ma możliwości takiej możliwości, więc chcą przyśpieszyć proces rozjaśniania/ściemniania kody wysyłam po prostu kilka razy
3)bo tego nie potrzebuję, projekt stworzyłem na własne potrzeby, opisałem jak go tworzyłem dla potomnych, a zmieniać ustawień sieci WiFi nie zamierzam, prędzej zmienię coś w elektronice niż nazwę sieci i hasło
4)nie pozbyłem się sterowania oryginalnym pilotem. Sterownik od LEDów (ten oryginalny) może być sterowany jednocześnie poprzez tą przystawkę WiFi jak i poprzez standardowego pilota. Myślałem nad tym ale ostatecznie zrezygnowałem. Teraz zastanawiam się czy w wersji 1.1 nie dodać tego feature’a
5)efekty – mi są kompletnie niepotrzebne. Dla mnie oryginalny pilot i tak już oferuje za dużo ;)
6)dzięki za docenienie
Dzięki za wyjaśnienia, to jeszcze dorzucę kilka uwag. Ten zapis pinów “const int irPin = 4;” generalnie tak się nie powinno robić, wiem że NODEMCU ma sporo pamięci, ale warto pisać oszczędzając pamięć ten zapis jest lepszy #define irPin 4 oszczędzasz 2 bajty pamięci. Druga sprawa, w tym projekcie akurat korzystasz tylko ze sterowania po wifi i ok, a co będzie jak będziesz chciał w innym projekcie z korzystać dodatkowego np. sterowania, i wtedy okaże się że dopóki nie połączy się z twoją siecią nic nie zrobisz. Bo w tym fragmencie kodu while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}
będzie próbował do skutku łączyć się z siecią, która akurat będzie nie osiągalna.
I trzy, nie wiem czy wiesz ale obciążalność wyprowadzeń esp to zaledwie 12 mA, Diodę ir podpina się tak jak ty to zrobiłeś ale dużo lepszym połączeniem jest wykorzystanie tranzystora.
A co do UDP to jest to jeden z protokołów sieciowych tzw bezpołączeniowy. Do szczęścia w tym protokole potrzeba adresu urządzenia i portu. I ma jeszcze jedną zaletę, te informacje można wysyłać po tzw brodcascie, czyli do wszystkich urządzeń które muszą ją np otrzymać. Na tym protokole zrobiłem sterownik oświetlenia akwarium, właściwie jest to podwójny bo steruje dwoma akwariami ze światłem dziennym i nocnym.
krisp74: doceniam to co teraz napisałeś, ale to co teraz robisz to jest sztuczne szukanie dziury w całym :/
Na pewno znasz to powiedzenie: “Jak coś jest głupie, ale działa to wcale nie jest głupie” i tak w tym wypadku jest ;)
Motocyklista :D Jaros
w kodzie użyłeś kodowania UTF-8
Próbowałeś może korzystać z polskich znaków?
U mnie pomimo ustawienia odpowiedniego kodowania cały czas na stronie wyświetlało krzaczki, zamiast ładnych polskich liter
Też tak jest u Ciebie i/lub wiesz jak sprawić, by polskie znaki wyświetlały się prawidłowo przy użyciu tych bibliotek?
A co do projektu, to bardzo mi się podoba – w zasadzie jest to prosty pilot IR, który może być wykorzystany do sterowania TV czy wzmacniaczem poprzez WiFi :)
Leci 5 ;)
Krapi: Dzięki za 5 ;)
A co do twojego pytania, to szczerze powiedziawszy nie próbowałem tego na Arduino, nie spotkałem się z tym problemem i nie wiem jak go rozwiązać. Spróbuj poszukać w google coś w stylu “latin extended ESP8266WebServer”
Witam
A czy jest możliwość pominięcia całkowicie transmisji IR ??
Ja mam ten sam sterownik i diody za telewizorem i pozostałe piloty wchodzą w interakcje ze sterownikiem LED
Czyli ściszam telewizor diody zaczynaja mrugac i podobne akcje:)
@Michał: jasne, że jest. Można kabel z Arduino wpiąć bezpośrednio do sterownika, z pominięciem odbiornika ir. Nie chciałem tego robić bo urządzenie byłoby skazane tylko na jeden sterownik, a nie chciałem go tak ograniczać.
Inna opcja? Pominąć całkowicie sterownik ledów i sterować z ESP8266. Wymaga podpięcia trzech tranzystorów dla każdego z kolorów i jakiegoś zasilacza 12V (choć ja bym proponował 9V; będą świecić ciemniej, ale tak szybko taśma się nie wypali; szczególnie ważne gdy nie ma możliwości chłodzenia, np. gdy listwa jest przyklejona do płyty biurowej). Uprości to elektrykę, ale wymaga dodatkowego kodu do obsługi ledów. Polecam do tego bibliotekę pololu.
Siema majsterkowicze, podoba mi się bardzo projekt, który stworzył MateuszxD, chciałbym spróbować samodzielnie wdrożyć ten projekt w swoim mieszkaniu i w związku z tym mam kilka pytań, a mianowicie:
– czy muszę stworzyć kilka bliźniaczych sterowników aby kontrolować oświetlenie w mieszkaniu czy istnieje jakiś sposób połączenia wszystkiego z jedną centralką? W razie co jak to ogarnąć? Logicznym następstwem gdybym stworzył kilka bliźniaczych sterowników było nadanie kliku pomieszczeniom/sterownikom różnych adresów IP. – takie myślenie na bieżąco.
– czy do powyższego schematu mogę zastosować obojętnie jaką taśmę led, byle była z programatorem?
Jak zacznę kombinować to na pewno wrzucę tu co z tego wyszło. Pozdrawiam Wojtek no i gratulacje dla autora za świetny projekt.
– jeszcze jedno jak to wszystko scalić z Qnap-em?
Siemanko :D
1) możesz zrobić to na wiele sposobów. Ja bym się skusił na zrobienie jednego modułu master, a resztę slave. W modułach slave pominąłbym całą stronę www, zostawiłbym tylko reakcje pod wejściu na podstronę, czyli to:
server.on(“/on”, []() {
irsend.sendNEC(IR_ON, 32);
});
oraz ustawił statyczne IP
Do modułu master zapakowałbym stronę z wieloma pilotami (czyli np 4 obok siebie), podpisał je i już ze strony wysyłałbym zapytanie GET np do 192.168.1.111/on
no i to jest moja logika
2) nie za bardzo wiem o co ci chodzi, ale jeżeli taśma będzie działać z takim sterownikiem to powinna też i zadziałać z moim urządzeniem :)
3) nie wiem co to jest Qnap, sorka
Dzięki za pochwałę, sorry, że odpisałem po miesiącu. Chętnie zobaczę twoją wersję ;)
Właśnie usiadłem, poskładałem iwrzuciłem kod do IDE ale niestety wciąż wywala mi błąd:
exit status 1
‘IRsend’ does not name a type
Jakieś pomysły ?
A można by tak pominąć tą diodę IR i pracować tylko na wifi?