Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'Ws2812b'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino i ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - DIY
    • Projekty - DIY roboty
    • Projekty - DIY (mini)
    • Projekty - DIY (początkujący)
    • Projekty - DIY w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie

Kategorie

  • Quizy o elektronice
  • Quizy do kursu elektroniki I
  • Quizy do kursu elektroniki II
  • Quizy do kursów Arduino
  • Quizy do kursu STM32L4
  • Quizy do pozostałych kursów

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Imię


Strona

Znaleziono 7 wyników

  1. Moje oświetlenie biurka (taśma ws2812b) mam podpięte według schematu jak wyżej do Arduino UNO (a raczej jakiś klon) + zewnętrzny zasilacz. Płytka jest podłączona przez kabel USB do komputera w celu sterowania oświetleniem przy pomocy Prismatik. Mam taki problem, że po wyłączeniu PC na porcie USB od Arduino na pinie Vcc mam cały czas +5V które idzie z zasilacza przez co na wszystkich portach USB komputera jest napięcie co powoduje podświetlanie się klawiatury, diody led na DACu itd., wiadomo o co chodzi. Czy można to napięcie jakoś odseparować? Na poprzednim komputerze pojawienie się tego napięcia powodowało dziwne zachowanie komputera, np. po wciśnięciu jakiegoś klawisza na klawiaturze potrafił się on zawiesić w systemie i wciskać przez kilka sekund lub nagłe spadki wydajności komputera (przycięcia w grach). Pomagało odłączenie zasilacza LED. Na nowym komputerze jest tylko problem ze świecącymi się diodami ale nie wiem czy to jest bezpieczne dla komputera skoro na starym działy się takie dziwne rzeczy.
  2. Witam, wykonuje projekt choinki na której zostaną zainstalowane okręgi z diodami led, projekt już działa jednak posiadam pewien dylemat i dlatego pisze prośbę o pomoc. Projekt realizuje na arduino nano. Program (kod) działa na zasadzie warunku switch, gdzie po wciśnięciu przycisku uruchamia się 1 tryb pracy a po jego skończeniu i ponownym wciśnięciu kolejny 2 tryb świecenia itd do 10. Po rozmowie z moim wykładowcą zaproponował mi bym użył przerzutnika asynchronicznego dzięki któremu będę mógł w trakcie wykonywania 1 pętli trybu, uruchomić kolejna bez czekania na jego zakończenie, moje pytanie brzmi jaki przerzutnik asynchroniczny rs kupić oraz jak go podpiąć? Domyślam się ze sterowanie Set będzie z przycisku a reset będzie od ? bardzo proszę o pomoc bo nie wiem jak się do tego zabrać. Pozdrawiam
  3. Witam, zbudowałem lampkę nocną krok po kroku z tym filmem: Wszystko byłoby w porządku gdyby nie jedna bardzo uciążliwa rzecz. Można za pomocą biblioteki FastLED i gotowego kodu zmieniać tylko efekty świecenia tej lampki (po wpięciu do prądu lampka od razu świeci). Chciałbym więc dodać włączenie i wyłączenie jej z tym że mam do dyspozycji tylko 1 przycisk monostabilny. Najprościej oczywiście byłoby dodać 2 przycisk, który będzie wpięty do obwodu zasilania ale nie wierzę że nie idzie tego rozwiązać w kodzie programu. Mam już nawet pewną koncepcję ale jestem amatorem więc kompletnie nie wiem jak powiązać tą bibliotekę z takim rozwiązaniem (https://www.youtube.com/watch?v=IsDzxtaZCoI) czyli długością wciśnięcia przycisku.(np żeby włączyć lampkę trzymamy 3 sekundy wciśnięty przycisk, żeby zmienić program klikamy szybko raz, a żeby wyłączyć znowu trzymamy 3s). Z góry dziękuję za odpowiedź
  4. Dość długo zabierałem się za ten projekt, ale w końcu udało się go zrealizować. Powstał on, ponieważ potrzebowałem czegoś, co umożliwi mi szybki wgląd w aktualne obciążenie komputera, bez niepotrzebnego przełączania okienek. Rozwiązanie czysto programowe byłoby też w moim przypadku o tyle mniej praktyczne, że często korzystam z maszyn wirtualnych, a taki zewnętrzny monitor obciążenia pozwala mi na wyświetlanie statystyk wszystkiego jednocześnie. Poza wyświetlaniem informacji zależało mi także na graficznej reprezentacji obciążenia, dzięki czemu można nawet "kątem oka" zauważyć że pojawiło się jakieś duże obciążenie lub że kończy się pamięć RAM. Parę lat temu zbudowałem taki monitor na ekranie LCD 4x20, jednak z biegiem czasu i modernizacją sprzętu coraz ciężej było zmieścić na nim wszystkie informacje które bym chciał, dlatego stwierdziłem że czas na nową odsłonę 😄 Tym razem zamiast ekranu LCD postanowiłem użyć wyświetlaczy OLED. Z kolei do reprezentacji graficznej chciałem wykorzystać diody WS2812. Dość długo zastanawiałem się w jaki sposób je ułożyć i jak to najprościej zrobić. Ostatecznie diody zostały ułożone w dwóch półpierścieniach nad wyświetlaczami. Aby ułatwić sobie życie kupiłem pierścienie 16 diodowe i 24 diodowe i przeciąłem na na pół. Wadą takiego rozwiązania było to, że tylko na jednej połówce miałem do dyspozycji wygodne pola lutownicze z tyłu, a na drugiej musiałem wlutować kable bezpośrednio w pierwszą diodę. Na zdjęciu widać pierwsze przymiarki diod do wyświetlacza: Docelowo planowałem wykonać 4 takie zestawy oled + diody, co wiązało się z pewnym problemem. Wyświetlacze które posiadałem podłącza się przez I2C, a ponieważ miałem 4 identyczne, to wszystkie miały ten sam adres, niestety producent wyświetlaczy nie przewidział takiego scenariusza (niektóre wersje umożliwiają ustawienie ostatniego bitu, co umożliwia podpięcie 2 wyświetlaczy, moje akurat nie miały takiej opcji). Po zrobieniu researchu rozwiązanie tego problemu okazało się bardzo proste. Polega ono na selektywnym doprowadzaniu sygnału zegara do poszczególnych wyświetlaczy. Ja w tym celu wykorzystałem demultiplekser 74HC139. Takie rozwiązanie jest możliwe, ponieważ tylko master (w tym wypadku mikrokontroler) steruje linią zegara, dzięki temu możliwe jest zastosowanie demultipleksera. W przypadku gdyby slave'y też sterowały linią zegara rozwiązanie byłoby bardziej złożone (o ile w ogóle możliwe), bo demultipleksery działają tylko w jedną stronę 😄 Z tego powodu też nie można tego zrealizować na linii danych (nawet jeśli przesyłanie danych odbywa się tylko w jedną stronę, to linia SDA musi być "dwustronna" żeby możliwa była realizacja protokołu I2C). W przypadku diod WS2812 sprawa była prostsza, docelowo każdy półpierścień dostał własny pin procesora, dzięki czemu każdy z nich może być odświeżany niezależnie. Jako mikrokontroler wybrałem Atmegę4809, ponieważ potrzebowałem 4kB ramu na trzymanie klatek z każdego z 4 oledów (128*64*4 = 32kb = 4kB). Możliwa by była realizacja przy mniejszej ilości pamięci, np 2kB, poprzez trzymanie tylko jednej klatki, jednak wiązałoby się to z mniejszą wydajnością całego programu, ponieważ generowanie kolejnej klatki można by było rozpocząć dopiero po zakończeniu przesyłania poprzedniej. W przypadku gdy każdy wyświetlacz ma swój bufor, to w trakcie gdy na przykład dane są wysyłane do pierwszego wyświetlacza możliwe jest generowanie obrazu dla drugiego wyświetlacza itd. Wymaga to asynchronicznej implementacji I2C, co zrealizowałem poprzez kolejkę do której można dodawać wskaźniki na tablice danych które mają być po kolei wysłane i ich obsługa jest w pełni realizowana na poziomie przerwania. Samo generowanie klatek zrealizowane jest w ten sposób, że dla każdego wyświetlacza przygotowany jest szablon zawierający stałe części obrazu, a następnie renderowane są na nim wartości w określonych pozycjach x,y, co łącznie generuje pełną klatkę obrazu. Graficznie wygląda to tak (po lewej templatka, po prawej z wypełnionymi wartościami): Wszystkie przygotowane ekrany wyglądają następująco: Ekrany przygotowane są stricte pod moją konfigurację, oczywiście możliwe by było generowanie wszystkiego po stronie komputera i przesyłanie gotowych klatek, akurat ja wolałem podejście z renderowaniem po stronie uC, ale co kto lubi 😄 Układ został zrealizowany na płytce uniwersalnej, a szkielet i obudowa zostały wydrukowane na drukarce 3D. Projekt ma budowę modułową i działa poprawnie z każdą liczbą modułów między 1 a 4, na ten moment mam zrealizowane dwa, kolejne dwa czekają aż będę miał trochę więcej wolnego czasu. Ponieważ każdy moduł wykorzystuje 4 kable do przesyłania danych (2 do pierścieni i 2 do wyświetlacza), to do ich podłączania wykorzystałem skrętkę, akurat po pół skrętki na moduł. Na ten moment całość prezentuje się następująco, kable z boku są przygotowane dla następnych modułów. Urządzenie łączy się z komputerem poprzez konwerter USB↔UART. Po stronie komputera działa aplikacja napisana w javascripcie, która zbiera dane z komputera na którym działa, używając głównie biblioteki systeminformation. Dodatkowo, nasłuchuje na jednym z portów sieciowych, pod który mogą się podpinać maszyny wirtualne i przesyłać dane o swoim obciążeniu. Technicznie, zamiast maszyn wirtualnych możliwe by było podpinanie innych fizycznych urządzeń, opcji jest wiele, wszystko zależy od potrzeb. Wyświetlanie informacji z dwóch źródeł jednocześnie na pierścieniach realizowane jest poprzez kolory, host wykorzystuje zielony i czerwony, natomiast maszyna wirtualna niebieski.
  5. Witam, realizuje w swoim pokoju projekt złożony z taśm led ws2812b, podzielonych na dwa niezależne paski ze względu na to że są różnej długości, a chce żeby efekty wyglądały na nich dobrze (jeden ma 640 diod, drugi 54 diod, aby efekt tęczy na obydwu miał pełne spektrum mam dwa oddzielne kody nadające paskom ten sam efekt). Mój problem pojawia się przy próbie sterowania tym, chcę aby wszystko było sterowane za pomocą pilota na podczerwień. Nie rozumiem kompletnie biblioteki IRemote, chciałbym aby wyglądało to tak, że po włączeniu włącza się efekt 1 (jakby animacja włączania), który jak się zakończy wyłącza się i włącza się efekt 2 (tęcza), który trwa cały czas, dopiero po przełączeniu pilotem na efekt 3 i tak samo z powrotem, pilotem na efekt 2. Efekt 4 (jeżel jest takie coś możliwe) po naciśnięciu przycisku na pilocie kolor zmienia sie powiedzmy z czerwonego na pomarańczowy, po ponownym nacisnieciu na żółty, dalej na zielony itd. Tak samo z jasnością efektu jeden przycisk na jasniej, drugi na ciemniej. I efekt 5 tak aby reagowało na muzykę, mam czujnik dzwieku ( https://allegro.pl/oferta/czujnik-dzwieku-8244890546 ) jeżeli się przyda, aby go wykorzystać do tego, bo podłączenie przez kabel jack odpada. Więc prosiłbym o pomoc z połączeniem tego wszystkiego, tak aby dało się to sterowac pilotem i napisanie tych 2 ostatnich efektów. dziękuję za wszystkie odpowiedzi Efekt 1 pasek 1 #include <Adafruit_NeoPixel.h> Adafruit_NeoPixel pasek1 = Adafruit_NeoPixel(640, 6, NEO_GRB + NEO_KHZ800); void setup() { pasek1.begin(); pasek1.show(); } void loop() { int i = 0; for (i = 0; i < 640; i++) { if (i < 640 ) { pasek1.setPixelColor(i, pasek1.Color(255, 0, 0)); } pasek1.show(); delay(10); } pasek1.clear(); } Efekt 1 pasek 2 #include <Adafruit_NeoPixel.h> Adafruit_NeoPixel pasek1 = Adafruit_NeoPixel(54, 6, NEO_GRB + NEO_KHZ800); void setup() { pasek1.begin(); pasek1.show(); } void loop() { int i = 0; for (i = 0; i < 54; i++) { if (i < 54 ) { pasek1.setPixelColor(i, pasek1.Color(255, 0, 0)); } pasek1.show(); delay(185); } pasek1.clear(); } efekt 2 pasek 1 #include <Adafruit_NeoPixel.h> class Strip { public: uint8_t effect; uint8_t effects; uint16_t effStep; unsigned long effStart; Adafruit_NeoPixel strip; Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) { effect = -1; effects = toteffects; Reset(); } void Reset(){ effStep = 0; effect = (effect + 1) % effects; effStart = millis(); } }; struct Loop { uint8_t currentChild; uint8_t childs; bool timeBased; uint16_t cycles; uint16_t currentTime; Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;} }; Strip strip_0(640, 6, 640, NEO_GRB + NEO_KHZ800); struct Loop strip0loop0(1, false, 1); //[GLOBAL_VARIABLES] void setup() { //Your setup here: strip_0.strip.begin(); } void loop() { //Your code here: strips_loop(); } void strips_loop() { if(strip0_loop0() & 0x01) strip_0.strip.show(); } uint8_t strip0_loop0() { uint8_t ret = 0x00; switch(strip0loop0.currentChild) { case 0: ret = strip0_loop0_eff0();break; } if(ret & 0x02) { ret &= 0xfd; if(strip0loop0.currentChild + 1 >= strip0loop0.childs) { strip0loop0.currentChild = 0; if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;} } else { strip0loop0.currentChild++; } }; return ret; } uint8_t strip0_loop0_eff0() { // Strip ID: 0 - Effect: Rainbow - LEDS: 640 // Steps: 640 - Delay: 20 // Colors: 3 (255.0.0, 0.255.0, 0.0.255) // Options: rainbowlen=640, toLeft=true, if(millis() - strip_0.effStart < 20 * (strip_0.effStep)) return 0x00; float factor1, factor2; uint16_t ind; for(uint16_t j=0;j<640;j++) { ind = strip_0.effStep + j * 1; switch((int)((ind % 640) / 18)) { case 0: factor1 = 1.0 - ((float)(ind % 640 - 0 * 18) / 18); factor2 = (float)((int)(ind - 0) % 640) / 18; strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2); break; case 1: factor1 = 1.0 - ((float)(ind % 640 - 1 * 18) / 18); factor2 = (float)((int)(ind - 18) % 640) / 18; strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2); break; case 2: factor1 = 1.0 - ((float)(ind % 640 - 2 * 18) / 18); factor2 = (float)((int)(ind - 36) % 640) / 18; strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2); break; } } if(strip_0.effStep >= 640) {strip_0.Reset(); return 0x03; } else strip_0.effStep++; return 0x01; } efekt 2 pasek 2 #include <Adafruit_NeoPixel.h> class Strip { public: uint8_t effect; uint8_t effects; uint16_t effStep; unsigned long effStart; Adafruit_NeoPixel strip; Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) { effect = -1; effects = toteffects; Reset(); } void Reset(){ effStep = 0; effect = (effect + 1) % effects; effStart = millis(); } }; struct Loop { uint8_t currentChild; uint8_t childs; bool timeBased; uint16_t cycles; uint16_t currentTime; Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;} }; Strip strip_0(54, 6, 54, NEO_GRB + NEO_KHZ800); struct Loop strip0loop0(1, false, 1); //[GLOBAL_VARIABLES] void setup() { //Your setup here: strip_0.strip.begin(); } void loop() { //Your code here: strips_loop(); } void strips_loop() { if(strip0_loop0() & 0x01) strip_0.strip.show(); } uint8_t strip0_loop0() { uint8_t ret = 0x00; switch(strip0loop0.currentChild) { case 0: ret = strip0_loop0_eff0();break; } if(ret & 0x02) { ret &= 0xfd; if(strip0loop0.currentChild + 1 >= strip0loop0.childs) { strip0loop0.currentChild = 0; if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;} } else { strip0loop0.currentChild++; } }; return ret; } uint8_t strip0_loop0_eff0() { // Strip ID: 0 - Effect: Rainbow - LEDS: 54 // Steps: 54 - Delay: 20 // Colors: 3 (255.0.0, 0.255.0, 0.0.255) // Options: rainbowlen=54, toLeft=true, if(millis() - strip_0.effStart < 20 * (strip_0.effStep)) return 0x00; float factor1, factor2; uint16_t ind; for(uint16_t j=0;j<54;j++) { ind = strip_0.effStep + j * 1; switch((int)((ind % 54) / 18)) { case 0: factor1 = 1.0 - ((float)(ind % 54 - 0 * 18) / 18); factor2 = (float)((int)(ind - 0) % 54) / 18; strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2); break; case 1: factor1 = 1.0 - ((float)(ind % 54 - 1 * 18) / 18); factor2 = (float)((int)(ind - 18) % 54) / 18; strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2); break; case 2: factor1 = 1.0 - ((float)(ind % 54 - 2 * 18) / 18); factor2 = (float)((int)(ind - 36) % 54) / 18; strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2); break; } } if(strip_0.effStep >= 54) {strip_0.Reset(); return 0x03; } else strip_0.effStep++; return 0x01; } efekt 3 pasek 1 #include <Adafruit_NeoPixel.h> class Strip { public: uint8_t effect; uint8_t effects; uint16_t effStep; unsigned long effStart; Adafruit_NeoPixel strip; Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) { effect = -1; effects = toteffects; Reset(); } void Reset(){ effStep = 0; effect = (effect + 1) % effects; effStart = millis(); } }; struct Loop { uint8_t currentChild; uint8_t childs; bool timeBased; uint16_t cycles; uint16_t currentTime; Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;} }; Strip strip_0(640, 6, 640, NEO_GRB + NEO_KHZ800); struct Loop strip0loop0(1, false, 1); //[GLOBAL_VARIABLES] void setup() { //Your setup here: strip_0.strip.begin(); } void loop() { //Your code here: strips_loop(); } void strips_loop() { if(strip0_loop0() & 0x01) strip_0.strip.show(); } uint8_t strip0_loop0() { uint8_t ret = 0x00; switch(strip0loop0.currentChild) { case 0: ret = strip0_loop0_eff0();break; } if(ret & 0x02) { ret &= 0xfd; if(strip0loop0.currentChild + 1 >= strip0loop0.childs) { strip0loop0.currentChild = 0; if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;} } else { strip0loop0.currentChild++; } }; return ret; } uint8_t strip0_loop0_eff0() { // Strip ID: 0 - Effect: Fade - LEDS: 640 // Steps: 5000 - Delay: 1 // Colors: 2 (0.0.0, 255.255.255) // Options: duration=5000, every=1, if(millis() - strip_0.effStart < 1 * (strip_0.effStep)) return 0x00; uint8_t r,g,b; double e; e = (strip_0.effStep * 1) / 5000; r = ( e ) * 255 + 0 * ( 1.0 - e ); g = ( e ) * 255 + 0 * ( 1.0 - e ); b = ( e ) * 255 + 0 * ( 1.0 - e ); for(uint16_t j=0;j<640;j++) { if((j % 1) == 0) strip_0.strip.setPixelColor(j, r, g, b); else strip_0.strip.setPixelColor(j, 0, 0, 0); } if(strip_0.effStep >= 5000) {strip_0.Reset(); return 0x03; } else strip_0.effStep++; return 0x01; } efekt 3 pasek 2 #include <Adafruit_NeoPixel.h> class Strip { public: uint8_t effect; uint8_t effects; uint16_t effStep; unsigned long effStart; Adafruit_NeoPixel strip; Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) { effect = -1; effects = toteffects; Reset(); } void Reset(){ effStep = 0; effect = (effect + 1) % effects; effStart = millis(); } }; struct Loop { uint8_t currentChild; uint8_t childs; bool timeBased; uint16_t cycles; uint16_t currentTime; Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;} }; Strip strip_0(54, 6, 54, NEO_GRB + NEO_KHZ800); struct Loop strip0loop0(1, false, 1); //[GLOBAL_VARIABLES] void setup() { //Your setup here: strip_0.strip.begin(); } void loop() { //Your code here: strips_loop(); } void strips_loop() { if(strip0_loop0() & 0x01) strip_0.strip.show(); } uint8_t strip0_loop0() { uint8_t ret = 0x00; switch(strip0loop0.currentChild) { case 0: ret = strip0_loop0_eff0();break; } if(ret & 0x02) { ret &= 0xfd; if(strip0loop0.currentChild + 1 >= strip0loop0.childs) { strip0loop0.currentChild = 0; if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;} } else { strip0loop0.currentChild++; } }; return ret; } uint8_t strip0_loop0_eff0() { // Strip ID: 0 - Effect: Fade - LEDS: 54 // Steps: 5000 - Delay: 1 // Colors: 2 (0.0.0, 255.255.255) // Options: duration=5000, every=1, if(millis() - strip_0.effStart < 1 * (strip_0.effStep)) return 0x00; uint8_t r,g,b; double e; e = (strip_0.effStep * 1) / 5000; r = ( e ) * 255 + 0 * ( 1.0 - e ); g = ( e ) * 255 + 0 * ( 1.0 - e ); b = ( e ) * 255 + 0 * ( 1.0 - e ); for(uint16_t j=0;j<54;j++) { if((j % 1) == 0) strip_0.strip.setPixelColor(j, r, g, b); else strip_0.strip.setPixelColor(j, 0, 0, 0); } if(strip_0.effStep >= 5000) {strip_0.Reset(); return 0x03; } else strip_0.effStep++; return 0x01; }
  6. 1. Wprowadzenie Pewnego dnia zapragnąłem stać się właścicielem lampki nocnej RGB, którą mógłbym sterować smartfonem przy wykorzystaniu przeglądarki internetowej. Z możliwością sterowania w przyszłości takimi systemami, jak Domoticz, czy też asystentem takim jak Google Home Mini, czy Alexa Amazon. Nie potrzebuje dużej mocy, aby na przykład móc czytać przy jej świetle literaturę piękną, a raczej preferuję podejście proekologiczne w zużyciu energii. Lampka ma pełnić funkcję głównie dekoracyjną tworząc przyjemny nastrój w pomieszczeniu. Przeglądając ofertę dostępnych na rynku rozwiązań doszedłem do wniosku, że ceny tego typu urządzeń są w moim mniemaniu bardzo wysokie, więc postanowiłem zbudować lampkę własnoręcznie. Moją uwagę przykuł jeden z modeli marki Xiaomi, a mianowicie Mi Bedside Lamp (cena to około 250 pln). Na tym projekcie będę bazował podczas budowy. Całość planuję wykonać z materiałów ekologicznych, oczywiście w miarę moich skromnych możliwości. 1.1. Lampka nocna Mi Bedside Lamp Silver. 1.2. Lampka nocna Mi Bedside Lamp Silver – schemat budowy wewnętrznej. 1.3. Lampka nocna Mi Bedside Lamp Silver – prezentacja wyglądu podświetlenia w różnych kolorach. 2. WS2812 Według producenta WS2812 jest on inteligentnym sterownikiem LED z wbudowanym źródłem światła. Bliższe rzeczywistości jest jednak stwierdzenie, że układ ten składa się zazwyczaj z diody RGB 5050 z wbudowanym w nią sterownikiem WS2811. Należy zaznaczyć, że rozwiązanie to produkowane jest wielu typach obudów. Ogromną zaletą takiego rozwiązania w przeciwieństwie do konwencjonalnych diod RGB jest możliwość szeregowego łączenia i sterowania niemalże dowolną liczbą diod za pomocą pojedynczego przewodu sygnałowego z cyfrowego pinu mikrokontrolera. 2.1. Schemat szeregowego połączenia WS2812. Na rynku dostępne jest wiele wersji WS2812 w różnych obudowach. Dość popularną wersją, która została wykorzystana tym w projekcie jest wersja WS2812B w obudowie 5050. Wersja WS2812 posiada sześć nóżek, natomiast wersja z dopiskiem B tylko cztery. Największą różnicą między modelami bez dopisku B i z dopiskiem jest zabezpieczenie przed odwrotnym podłączeniem zasilania diody dla wersji B, co w przypadku standardowej wersji skutkuje zniszczeniem elementu. 2.2. Pojedyncza dioda WS2812 w wersji obudowy 5050. 2.3. Pojedyncza dioda WS2812B w wersji obudowy 5050. 2.4. Schemat szeregowego łączenia WS2812B. Podczas pracy z WS2812 niezależnie od wersji należy pamiętać, aby: Nie przekraczać napięcia zasilania powyżej 5V, ponieważ uszkodzimy układ. Dodać kondensator elektrolityczny o pojemności od 100µF do 1000µF (na 6.3V lub wyższy) przy zasilaniu pierwszej diody. Dodać rezystor o wartości od 300Ω do 1kΩ pomiędzy mikrokontrolerem, a pierwszym pinem DIN i aby umieść go jak najbliżej diody. W miarę możliwości jak najbardziej skrócić odległość pomiędzy mikrokontrolerem, a pierwszą diodą. Nie podłączać diod przy włączonym zasilaniu. Jeśli nie mamy innego wyboru, to należy zachować kolejność: masa, zasilanie, linia sterująca, a odłączamy w odwrotnej kolejności. Jeżeli diody zasilane są z oddzielnego źródła zasilania, to najpierw należy doprowadzić zasilanie do diod, a następnie do mikrokontrolera. 3. Projekt i narzędzia Główną część lampy stanowi szklany słoik, wewnątrz są warstwy rozpraszające światło w postaci arkusza kalki technicznej i białego papieru. Całość została osadzona w kartonowej podstawie. Całość będzie składała się z: Szklany słoik, najlepiej wypiaskowany aby dobrze rozpraszał światło. Ja użyłem słoika Ikea Dropper, ale nada się każdy inny podobny. Ten, którego użyłem nie jest idealny, ponieważ nie jest w całości wypiaskowany. Kalka techniczna do rozpraszania światła. Pomaga uzyskać lepsze rozproszenie, zwłaszcza gdy piaskowanie nie jest całkowite. Kartka białego papieru A4. Również pomocna przy rozpraszaniu, warto wąski pasek umieścić przy tuż przy diodach. Karton, tektura. Do do budowy podstawy, jeśli nie umiemy sobie takiej podstawy wyrzeźbić na przykład z drewna lub nie mamy drukarki 3D. Klej biurowy, przeźroczysta taśma klejąca. Ładowarka z wyjściem USB 5V 1A+. Taka, jakiej używa się się do ładowania większości smartfonów. Kabel USB – micro USB o długości dostosowanej do własnych potrzeb. W projekcie zastosowałem taki o długość 100 cm. Kondensator elektrolityczny w przedziale od 100µF do 1000µF na 6.3V. W projekcie został użyty 1000µF 6.3V. Rezystor o wartości od 300Ω do 1kΩ. W projekcie został użyty 470Ω ¼W. Gniazdo wejściowe microUSB do zasilania układu. Z racji braku gniazda użyłem moduły TP4056, co daje dodatkową możliwość zastosowania w przyszłości zasilania bateryjnego z ogniw 18650. Koło / pierścień diod WS2812B + moduł ESP8266 (ESP-01 / ESP-01S) + łącznik ESP-01S/ESP-01 RGB LED. W tym konkretnym projekcie zostało użyte koło z 16 diodami. Lutownica lub stacja lutownicza, stop lutowniczy i topnik. Przewody, kilka cm. Cążki do metalu. Śrubokręt, nożyczki, czy inne narzędzia potrzebne do obróbki wybranego materiału. 3.1. Zestaw składający się z WS2812B, ESP-01 i łącznika. 4. Schemat połączeń Jeśli korzystamy z gotowego zestawu, to schemat połączeń jest bardzo prosty. 4.1. Schemat połączeń wszystkich podzespołów. 5. Kod i programowanie #include <adafruit_neopixel.h> #include <esp8266wifi.h> const char* ssid = "<nazwa_sieci_wifi>"; const char* password = "<haslo_do_sieci_wifi>"; Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, 2, NEO_GRB + NEO_KHZ800); WiFiServer server(80); long aniMillis = 0; byte aniFlag = 0; void setup() { Serial.begin(115200); delay(100); strip.begin(); for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 0); strip.show(); } IPAddress ip(192, 168, 0, 100); 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("."); } server.begin(); } void loop() { while (WiFi.status() == WL_CONNECTED) { WiFiClient client = server.available(); if (!client) { return; } while (!client.available()) { delay(10); } String request = client.readStringUntil('\r'); client.flush(); if (request.indexOf("/off") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 0); strip.show(); } } // jasnosc if (request.indexOf("/b0") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setBrightness(30); strip.show(); } } if (request.indexOf("/b1") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setBrightness(128); strip.show(); } } if (request.indexOf("/b2") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setBrightness(255); strip.show(); } } // jasnosc end // kolory // bialy if (request.indexOf("/c0") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 255, 255, 255); strip.show(); } } // zoly if (request.indexOf("/c1") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 255, 255, 0); strip.show(); } } // pomaranczowy if (request.indexOf("/c2") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 255, 127, 0); strip.show(); } } // czerwony if (request.indexOf("/c3") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 255, 0, 0); strip.show(); } } // rozany if (request.indexOf("/c4") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 255, 0, 127); strip.show(); } } // magenta if (request.indexOf("/c5") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 255, 0, 255); strip.show(); } } // fioletowy if (request.indexOf("/c6") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 127, 0, 255); strip.show(); } } // niebieski if (request.indexOf("/c7") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 0, 0, 255); strip.show(); } } // blekitny if (request.indexOf("/c8") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 0, 127, 255); strip.show(); } } // cyjan if (request.indexOf("/c9") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 0, 255, 255); strip.show(); } } // wiosenna zielen if (request.indexOf("/c10") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 0, 255, 127); strip.show(); } } // zielony if (request.indexOf("/c11") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 0, 255, 0); strip.show(); } } // zielen chartreuse if (request.indexOf("/c12") > 0) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 127, 255, 0); strip.show(); } } // kolory end client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(""); client.println(""); client.println(""); client.println(""); client.println("<title>Lampka</title>"); client.println("<meta charset="\"utf-8\"">"); client.println("<meta name="\"apple-mobile-web-app-capable\"" content="\"yes\"">"); client.println("<meta name="\"apple-mobile-web-app-status-bar-style\"" content="\"black\"">"); client.println("<meta name="\"robots\"" content="\"none\"">"); client.println("<meta name="\"viewport\"" content="\"width=device-width," initial-scale="1\"">"); client.println("<style>"); client.println("body {background: #313236; text-align: center; padding: 0; margin: 50px 0;}"); client.println("button {border: 0; font: bold 12px Verdana, sans-serif; color: #000000; width: 85px; height: 85px; border-radius: 50%;}"); client.println(".b0 {background: #000000; color: #ffffff;}"); client.println(".b1 {background: #949494;}"); client.println(".b2 {background: #bdbebd;}"); client.println(".b3 {background: #e9e9e9;}"); client.println(".c0 {background: rgb(255, 255, 255); margin-right: 266px;}"); // bialy client.println(".c1 {background: rgb(255, 255, 0);}"); // zolty client.println(".c2 {background: rgb(255, 127, 0);}"); // pomaranczowy client.println(".c3 {background: rgb(255, 0, 0);}"); //czerwony client.println(".c4 {background: rgb(255, 0, 127);}"); // rozany client.println(".c5 {background: rgb(255, 0, 255);}"); // magenta client.println(".c6 {background: rgb(127, 0, 255);}"); // fioletowy client.println(".c7 {background: rgb(0, 0, 255);}"); // niebieski client.println(".c8 {background: rgb(0, 127, 255);}"); // blekitny client.println(".c9 {background: rgb(0, 255, 255);}"); // cyjan client.println(".c10 {background: rgb(0, 255, 127);}"); // wiosenna zielen client.println(".c11 {background: rgb(0, 255, 0);}"); // zielony client.println(".c12 {background: rgb(127, 255, 0);}"); // zielen chartreuse client.println(".mgb4 {margin-bottom: 4px;}"); client.println(".mgb50 {margin-bottom: 50px;}"); client.println("</style>"); client.println(""); client.println(""); client.println("<a href="\"/b0\""><button class="\"b1" mgb50\"="">MIN</button></a>"); client.println("<a href="\"/b1\""><button class="\"b2" mgb50\"="">50%</button></a>"); client.println("<a href="\"/b2\""><button class="\"b3" mgb50\"="">MAX</button></a>"); client.println("<a href="\"/off\""><button class="\"b0" mgb50\"="">OFF</button></a><br>"); client.println("<a href="\"/c0\""><button class="\"c0" mgb4\"=""></button></a><br>"); client.println("<a href="\"/c1\""><button class="\"c1" mgb4\"=""></button></a>"); client.println("<a href="\"/c2\""><button class="\"c2" mgb4\"=""></button></a>"); client.println("<a href="\"/c3\""><button class="\"c3" mgb4\"=""></button></a>"); client.println("<a href="\"/c4\""><button class="\"c4" mgb4\"=""></button></a><br>"); client.println("<a href="\"/c5\""><button class="\"c5" mgb4\"=""></button></a>"); client.println("<a href="\"/c6\""><button class="\"c6" mgb4\"=""></button></a>"); client.println("<a href="\"/c7\""><button class="\"c7" mgb4\"=""></button></a>"); client.println("<a href="\"/c8\""><button class="\"c8" mgb4\"=""></button></a><br>"); client.println("<a href="\"/c9\""><button class="\"c9\""></button></a>"); client.println("<a href="\"/c10\""><button class="\"c10\""></button></a>"); client.println("<a href="\"/c11\""><button class="\"c11\""></button></a>"); client.println("<a href="\"/c12\""><button class="\"c12\""></button></a>"); client.println(""); client.println(""); delay(10); } setup(); } 6. Efekt końcowy Efekt końcowy prezentuje się tak, jak to widać na poniższych zdjęciach. Należy zaznaczyć, że w rzeczywistości podświetlenie jest bardziej jednolite, niż widać to na zdjęciach. Prawdopodobnie ekspozycja podczas robienia zdjęcia byłą zbyt długa, ale ciężko zrobić w inny sposób zdjęcia w nocy bez dobrego sprzętu. Obsługa lampki odbywa się przez interfejs sieciowy pod adresem 192.168.0.100. 6.1. Interfejs sieciowy pod adresem 192.168.0.100. 6.2. Wnętrze podstawy lampy. 6.3. Warstwy rozpraszające światło bez i z koszem. 6.4. Wybrane kolory.
  7. Witam Mam problem z paskiem led z diodami WS2812B i arduino uno. Pasek wyświetla błędne kolory, da przykładu kiedy chcę aby trzy diody zapaliły się na kolor czerwony to uzyskuję kolor czerwony niebieski oraz zielony. Dałem już rezystor na sygnał sterowania, ale nic to nie pomogło. Diody zasilałem zewnętrznym zasilaczem 5V i oczywiście GND spięte z GND arduino. Próbowałem też zmian w kodzie i dwóch różnych bibliotek ale cały czas mam ten sam problem.
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.