Cześć!
Chcę Wam dzisiaj zaprezentować projekt, który wykonałem jako prezent, a jest nim lampka sterowana przez WIFI z diodami adresowanymi WS2812b. Głównym zamysłem projektu było to, by lampka zapalała się po otrzymaniu SMS’a z danego numeru i wyświetlała animację.
Do dzieła!
Użyłem w projekcie następujących elementów:
- NodeMCU V2 (amica)
Diody adresowane WS2812b (18 sztuk)
- Rezystory – 2x 220Ohm i 1x 330Ohm
Kabel USB
Ładowarka USB do telefonu
Kabelki połączeniowe żeńsko-męskie
Natomiast z narzędzi i innych:
Papier ścierny 500, 1000
Klej dwuskładnikowy
Farba w sprayu czarna
Wkręty czarne
Odpady z płyt PCV, Plexi, Dibond
Wiertła do metalu (1,5mm, 3mm, 10mm)
Frezarka CNC
- Szara taśma montażowa
Wkrętarka
Początek
Wszystko zaczęło się od zaprojektowania ogólnego wyglądu na kartce papieru, a potem przeniosłem gotowy pomysł do programu 3D. Użyłem bezpłatnego oprogramowania Google SketchUP. Umożliwia ono dokładne i łatwe modelowanie elementów, a także podział na komponenty, co zdecydowania ułatwia późniejsze przenoszenie projektu do rzeczywistości.
Po zaprojektowaniu gotowego modelu i przygotowaniu pliku, zabrałem się za eksport odpowiednich krzywych do formatu DXF. Następnie, udałem się z plikami do zaprzyjaźnionej firmy tworzącej reklamy zewnętrzne – jest to świetny sposób na zdobycie bardzo tanio materiałów takich jak PCV, Plexi i Dibond (sporo odpadów, więc jest w czym wybierać), gdzie następnie pliki trafiły na frezarkę CNC i wszystkie elementy zostały dokładnie wycięte.
Obudowa składała się z 4 elementów, ze względu na grubość płyty PCV (10mm). Dlatego poszczególne warstwy kleiłem do siebie zgodnie z instrukcjami na kleju. Co do rodzaju kleju: moim zdaniem zwykły dwuskładnikowy skleił PCV idealnie, aczkolwiek słyszałem opinie, że nie zawsze się to dobrze trzyma – pewnie kwestia indywidualna, zależna od dokładności wyczyszczenia klejonej powierzchni.
Po sklejeniu wszystkich elementów obudowy, wywierciłem otwory na dwie diody sygnalizujące pracę urządzenia z przodu obudowy i następnie wygładziłem papierem ściernym widoczne łączenia sklejonych płyt PCV.
Po wyczyszczeniu elementu i sprawdzeniu dobrego spasowania obudowy do płytki plexi, pomalowałem obudowę dwoma, cienkimi warstwami czarnej, błyszczącej farby w sprayu i odstawiłem do wyschnięcia
Czas na elektronikę
Z paska diód adresowanych 60szt/m wyciąłem pasek 13 diod. Jest to idealna ilość na 29,5cm szerokość plexi. Na końcu wyciętego paska dolutowałem goldpiny. Taśmy adresowane oparte na chipie WS2812b mają 4 wyprowadzenia: 5V, Data In, Data Out i GND. Ważne jest przy podłączaniu by nie pomylić Data In z Data Out (diody mają narzucony kierunek transmisji danych).
Dodałem trzy kabelki połączeniowe męsko-żeńskie, w których to kabel Data In przeciąłem i wlutowałem w niego rezystor 330Ohm (zgodny z zaleceniami producenta – bardzo dużo informacji na temat tych diod znajdziecie wyszukując w internecie frazę „neopixel uberguide”)
Po wyschnięciu przyszedł czas na wklejenie plexi do obudowy oraz na przyklejenie paska diod adresowanych do krawędzi plexi. W tym celu użyłem zwykłej szarej taśmy z racji elastyczności i łatwej ewentualnej wymiany tych diod.
W miejscu wywierconych drobnych otworów na diody sygnalizacyjne, w środku obudowy montujemy diody LED – przez rezystory 220Ohm odpowiednio do pinu 4 i 5. Pierwsza od lewej będzie sygnalizować zasilanie lampki, a druga podłączenie się do sieci WIFI.
Do NodeMCU podłączamy wyprowadzenia taśmy LED – 5V do Vin, masy razem oraz Data In do pinu 14(D5), diody sygnalizacyjne – katody wspólnie do masy, anody przez rezystory, odpowiednio do pinu 4(D1) i 5(D2) oraz kabel microUSB. Kabel ten będzie służył do programowania układu, jak i późniejszego zasilania lampki z ładowarki USB.
Warto dodać, że moduł NodeMCU występuje w paru wersjach. Najczęściej spotykane są wersje: V2 (amica, m.in. sprzedawana w Botlandzie) i V3 (lolin). Zdecydowanie bardziej polecam wersję V2, która po prostu jest mniejsza i bez problemu pasuje do płytki prototypowej. W przypadku wersji V3, moduł zajmuje cała powierzchnię pinów, co powoduje konieczność skorzystania z dwóch płytek prototypowych jednocześnie.
Przyszła pora na zamknięcie lampki.
Z tyłu obudowy wycinamy otwór na wyjście kabla USB. Następnie małym wiertłem, z założoną klapką z Dibondu (materiał często wykorzystywany w reklamie, płyty o aluminiowych okładzinach z polietylenowym wypełnieniem) wiercimy dziury na wkręty zamykające obudowę. Teraz możemy dodatkowo zfazować nieco otwór w Dibondzie wiertłem 10mm, w celu schowania w nim łebka wkrętu.
Czynność powtarzamy dla drugiego wkrętu i obudowa gotowa!
Kod
Skorzystałem z przykładu znajdującego się w bibiliotece ESP8266 oraz strandtest z biblioteki Adafruit NeoPixel które zmodyfikowałem do swoich potrzeb.
Zadaniem programu jest obsługa serwera strony WWW, która będzie panelem kontrolnym lampki i ustawianie koloru diod wedle życzenia.
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 |
#include <Adafruit_NeoPixel.h> #include <ESP8266WiFi.h> const char* ssid = "AndroidAPa"; //nazwa ssid sieci const char* password = "testtest"; //haslo #define PIN 14 //pin do podlaczenia diod adresowanych #define diodaWifi 5 //pin diody wifi #define diodaPower 4 //pin diody zasilania Adafruit_NeoPixel strip = Adafruit_NeoPixel(18, PIN, NEO_GRB + NEO_KHZ800); WiFiServer server(80); long aniMillis=0; byte aniFlag=0; void setup() { Serial.begin(115200); delay(10); pinMode(diodaPower, OUTPUT); pinMode(diodaWifi, OUTPUT); digitalWrite(diodaPower, HIGH); digitalWrite(diodaWifi, LOW); //Zerowanie diod adresowanych strip.begin(); for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 0); strip.show(); } //Laczenie z siecia wifi Serial.println(); Serial.println(); Serial.print("Laczenie z: "); Serial.println(ssid); IPAddress ip(192, 168, 0, 133); //preferowany adres IP IPAddress gateway(192, 168, 0, 1); IPAddress subnet(255, 255, 255, 0); WiFi.config(ip, gateway, subnet); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi polaczone"); digitalWrite(diodaWifi, HIGH); // Start serwera server.begin(); Serial.println("Serwer uruchomiony"); // Wyswietlanie adresu IP Serial.print("Uzyj tego adresu URL by polaczyc sie z lampka: "); Serial.print("http://"); Serial.print(WiFi.localIP()); Serial.println("/"); } void loop() { //Sprawdz czy klient sie podlaczyl while (WiFi.status() == WL_CONNECTED){ WiFiClient client = server.available(); if (!client) { return; } // Poczekaj na odbior danych Serial.println("new client"); while(!client.available()){ delay(1); } String request = client.readStringUntil('\r'); Serial.println(request); client.flush(); //Dopasuj zadanie //wlaczenie ulubionego koloru lampki if (request.indexOf("/turnOn") > 0) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 255,120,0); strip.show(); } } //wylaczanie lampki if (request.indexOf("/turnOff") >0) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 0); strip.show(); } } //wlaczenie animacji if (request.indexOf("/animationOn") > 0) { aniMillis=millis(); rainbowCycle(20); aniFlag=1; } if (request.indexOf("/animationOff") >0) { aniFlag=0; for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 0); strip.show(); } } //wyswietlanie koloru bialego if (request.indexOf("/white") > 0) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 255,255,255); strip.show(); } } //wyswietlanie koloru czerwonego if (request.indexOf("/red") > 0) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 255,0,0); strip.show(); } } //wyswietlanie koloru zielonego if (request.indexOf("/green") > 0) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 0,255,0); strip.show(); } } //wyswietlanie koloru niebieskiego if (request.indexOf("/blue") > 0) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 0,0,255); strip.show(); } } //wylaczanie animacji po okreslonym czasie if (aniFlag==1) { if (millis()-aniMillis>3000) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 0); strip.show(); delay(10); } Serial.println("Wylaczam"); aniFlag=0; } } //Zwroc odpowiedz client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(""); // do not forget this one client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); client.println("<meta name='apple-mobile-web-app-capable' content='yes' />"); client.println("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />"); client.println("</head>"); client.println("<body bgcolor = \"#dddddd\">"); client.println("<hr/><hr>"); client.println("<h4><center> Panel kontrolny lampki LED </center></h4>"); client.println("<hr/><hr>"); client.println("<br><br>"); client.println("<br><br>"); client.println("<center>"); client.println("Zaswiec"); client.println("<a href=\"/turnOn\"\"><button>Wlacz </button></a>"); client.println("<a href=\"/turnOff\"\"><button>Wylacz </button></a><br />"); client.println("</center>"); client.println("<br><br>"); client.println("<center>"); client.println("Animacja"); client.println("<a href=\"/animationOn\"\"><button>Wlacz</button></a>"); client.println("<a href=\"/animationOff\"\"><button>Wylacz</button></a><br />"); client.println("</center>"); client.println("<br><br>"); client.println("<center>"); client.println("Kolor"); client.println("<a href=\"/red\"\"><button>Czerwony</button></a>"); client.println("<a href=\"/green\"\"><button>Zielony</button></a>"); client.println("<a href=\"/blue\"\"><button>Niebieski</button></a>"); client.println("<a href=\"/white\"\"><button>Bialy</button></a><br />"); client.println("</center>"); client.println("<center>"); client.println("<br><br>"); client.println("<center>"); client.println("</html>"); delay(1); Serial.println("Client disonnected"); Serial.println(""); } setup(); //ponowne laczenie z siecia wifi w przypadku rozlaczenia } // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, c); strip.show(); delay(wait); } } void rainbow(uint8_t wait) { uint16_t i, j; for(j=0; j<256; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel((i+j) & 255)); } strip.show(); delay(wait); } } //Przyklad z biblioteki Adafruit neopixel dla animacji teczy // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) { uint16_t i, j; for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); } strip.show(); delay(wait); } } // Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } |
Poprzez dodanie odpowiednich przycisków i obsługi interakcji kliknięcia, możemy zaprogramować kilka kolorów świecenia diod adresowanych. Od typowych: Czerwony, zielony, niebieski, biały, po specjalne typu ‘tęcza’, przenikanie itd. Dopiero w tych ciekawszych pomysłach, diody adresowane pokazują swoją wyjątkowość :)
Automatyzacja
Jako, że jest to lampka domowa, nonsensem byłoby dodawanie do niej modułu GSM. Zdecydowałem, że za zdalne, automatyczne włączanie lampki po otrzymaniu SMS’a będzie odpowiadał sam telefon. Stąd, komunikacja odbywa się w sposób: telefon→ router WIFI→ lampka. Wgrałem na telefon aplikację MacroDroid, która umożliwia, by po otrzymaniu SMS’a z danego numeru, wysyłała informację do serwera WWW na NodeMCU, by moduł włączył animację. Działa to idealnie, a dodatkowo opcji samych wyzwalaczy jest pełno – można na takiej bazie zrobić także lampkę z powiadomieniami z Twittera, Facebooka i innych.
Uwagi końcowe
Lampka w przypadku wyświetlania białego koloru zdecydowanie przekracza pobór prądu 500mA, dlatego nie polecam jej zasilać ze złącza USB w komputerze. Najodpowiedniejsza będzie ładowarka gniazdkowa USB, o prądzie minimum 1A.
Efekt końcowy
Ładne – masz piątkę.
Zastosowałbym jednak ESP8266WebServer zamiast prostego WiFiServer – co prawda wymaga więcej pamięci (ale w Twoim przypadku masz jeszcze mnóstwo wolnego RAM-u), ale za to obsługuje również normalne parametry przesyłane przez GET/POST – a co najważniejsze, treść wysyłanej strony możesz umieścić bezpośrednio we flashu i wysłać przez send_P. Jakoś nie lubię całego ekranu println…
ethanak: dziękuję, ogólnie tematykę serwerów muszę jeszcze dokładniej zgłebić – niestety nie byłem w technikum, więc nikt nie przekazał mi choć grama wiedzy na ten temat :) W nastepnym projekcie już postaram się to poprawić :D
woysz: W technikum nikt Ci takiej wiedzy nie przekaże :) Nawet teraz w elektronicznych technikach nadal trwa walka o sprzęt, a ja w informatycznym nawet nie usłyszałem o czymś takim jak programowanie na sprzęt. Jak nie sam, to nikt nie pomoże, więc gratuluję.
Zainspirowałeś mnie do zrobienia czegoś podobnego dla drugiej połówki :)
Hey, miałbyś chwilę czasu w weekend żeby przegadać temat lampki na priv ?
Fajny projekt, leci 5’tka !
Ale moja nadgorliwość nie pozwala mi nie przypomnieć że wierci się otwór a jak mówił mój nauczyciel “dziura to jest w dupie” :D
Bardzo fajny projekt ! – piątka poszła.
A jest możliwość żebyś wrzucił ten projekt lampki zrobiony w 3D ?
Ponieważ planuje cos podobnego zrobić :)
dodek91: Dziękuję, nie ma problemu – interesuje Ciebie plik .skp do edycji w SketchUP czy .dxf do późniejszego wyfrezowania? :)
woysz:
Witam do edycji :) Albo jak nie jest problem to oba :)
https://www.dropbox.com/s/yn47prnheib8uag/lampka_model_do_frezowania.skp?dl=0 -> model w SketchUP
Do późniejszego eksportu poszczególnych warstw przydatne jest jeszcze dodatek do SketchUP’a do eksportu krzywych do dxf -> http://www.guitar-list.com/download-software/convert-sketchup-skp-files-dxf-or-stl
DXF może być potem przerobiony na GCode czyli kod, który leci prosto do frezarki CNC
dodaj do tego prosty serwer DNS taki tylko żeby każdą nazwę domeny zamieniał na jeden IP pod którym siedzi serwer WWW i masz captive portal, tym samym nie musisz znać adresu IP serwera WWW telefon albo sam o ni poinformuje abo wpisują cokolwiek w przeglądarkę dostaniesz zawsze to samo
@828586: Czyli telefon ma się łączyć z lampką działającą w trybie SOFT AP i nie mieć dostępu do reszty świata?
Tak się nie robi.
ESP powinien przełączyć się w tryb SOFT AP (z ew. uruchomieniem mDNS) jeśli nie uda mu się połączenie z zaprogramowaną siecią – i uruchomić prosty serwer WWW, którego zadaniem jest wyłącznie zapisanie nowych parametrów połączenia (IP, GW, maska) i reset ustrojstwa. Dla bezpieczeństwa – jeśli w ciągu jakiegoś czasu (np. dwóch minut) od uruchomienia w tym trybie nikt nie połączy się z urządzeniem, powinna być ponowiona próba połączenia z zaprogramowaną siecią (to mógł być skutek np. zaniku zasilania – wiadomo że router wstaje nieco wolniej niż mikrokontroler).
@828586: zacząłem prace na aplikacją na androida w AppInventorze i wtedy w ogóle nie trzeba tworzyć DNS, bo w przyciskach ‘Włącz’, ‘Wyłącz’ itd można ukryć komendy do sterowania przez serwer WWW
woysz: w takiej sytuacji lepiej nie pier* się z WIF ale użyć moduł BT LE
ethanak a to dlaczego się nie robi ?, grozi za to kara śmieci, ja zrobiłem zamek i dzwonek do furtki na tej zasadzi i nikt ni się jeszcze nie włamał, dodałem jeszcze czytnik RFID dla innych mieszkańców, nie każdy jest taki oblatany w komórkach WIFI etc…, cała instalacja jest całkiem stabilna ale dodatkowy Arduino micro robi za wachdog-a tak na wszelki wypadek
jak telefon zbliży się do AP i połączy, natychmiast telefon wykrywa brak dostępu do internetu i anonsuje w powiadomieniu captive portal wystarczy kliknąć na powiadomienie otwiera się strona z guzikiem itd…..
@828586: Temu tak się nie robi, bo jeśli w domu (zauważ: lampka ma stać w domu) jest już router WiFi (a z kodu programu wynika że jest), telefon jest już z reguły połączony ze swoim routerem i wcale nie będzie miał zamiaru z Twoim AP się łączyć.
No, chyba że uznałeś moje pytanie z poprzedniego komentarza (czy telefon ma się odciąć od netu i całe życie być podłączony do lampki) za retoryczne i odpowiedź twierdzącą za oczywistą ;)
Zamek do furtki a lampka do pokoju to chyba dwa różne urządzenia i to, co pasuje do jednego (zamek do furtki) wcale nie musi być odpowiednie dla drugiego (lampka).
Świetna lampka i nie wygląda na trudną do wykonania. Projekt na 5! Myślę, że w niedługim czasie spróbuję coś takiego wykonać. Dzięki za inspiracje! ;)
Jak zrobiony jest napis?
To są jakieś elementy naklejone na pleksi, czy było to frezowane?
@MorisQ: napis był frezowany po konturze na frezarce CNC – delikatne zagłębienie frezem 1.5mm na głębokość bodajże 1mm.
Wygląda to mega !!
Muszę sobie coś takiego zrobić, największy problem będzie z wyfrezowanie napisu.
Można próbować ręcznie dremelkiem, ale zdecydowanie jednak lepiej wykorzystać CNC. Usługi frezowania CNC są praktycznie w każdej firmie zajmującej się produkcją szyldów reklamowych. Można także podpytać np. na forum, bo często majsterkowicze robią własne frezarki CNC :)
No właśnie jakieś pomysły gdzie takie reczy mogą frezować? Bo to w sumie jedyny problem dla mnie w tym projekcie…
Jeżeli jesteś z Poznania, to mogę Ci podrzucić parę adresów – ogólnie wszelakie firmy reklamowe zajmujące się produkcją szyldów. Praktycznie większość posiada frezarki CNC i bez problemu zrobią to na miejscu za darmo bądź niewielką opłatą :)
szkoda ze program nie obsługuje 442 diod
Czy mogę obsłużyć 30 diod poprzez takie podłączenie ? Oraz, czy zamiast V2 zadziała to na V3 ?