ring ws2812b

User avatar
malarz
Posts: 506
Joined: Wed Jan 27, 2021 4:04 pm
Been thanked: 2 times

Post

Dłubię sobie właśnie mały projekt świąteczny. Założenie jest takie, że mam sterować dwoma ringami po 16 WS2812B. Jeszcze nie wiem, czy użyję ESP8266 czy ESP32 (mam w szufladzie kilka do wyboru). Zasilanie tylko przez USB / 18650, co pewnie jest na granicy wydolności. Jak trzeba będzie to przejdę na jednego ringa 16 LED.

Czasu zostało trochę a ja praktycznie nigdy nie sterowałem tymi diodami. Jakich kontrolek Supla użyć aby wygodnie było sterować z aplikacji? Jakiej biblioteki do obsługi samych diod użyć. Gdzieś czytałem, że ESP32 ma tę obsługę w boardach.
Próbuję przerobić pomysły na działające projekty w ArduinoIDE.
User avatar
klew
Posts: 13907
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

Supla nie ma niczego sensownego do diod adresowanych.
Jedynie można to w RGB wrzucić i ustawiać wszędzie taki sam kolor i jasność.
Możesz próbować jakieś efekty załączać np wirtualnymi przekaźnikami
Najlepsze suple dla Twojego domu :mrgreen:
Mmof
Posts: 1220
Joined: Sun Jan 26, 2020 5:49 pm
Has thanked: 34 times
Been thanked: 4 times

Post

Jeżeli chodzi o WLed to chyba największe doświadczenie ma @veeroos (Robert) ma kilka projektów z tym związanych ale część jest na FB trochę zaczęło się od moich pasków płynących ale skończyło się grubo więc może Robert coś podpowie 😉.
https://github.com/v33r005?tab=repositories
Zapraszam na Facebook do wspólnej pomocy mniej zawansowanym użytkownikom Supla.
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/supladiy
https://www.facebook.com/groups/suplaauraton
User avatar
malarz
Posts: 506
Joined: Wed Jan 27, 2021 4:04 pm
Been thanked: 2 times

Post

klew wrote: Sat Dec 06, 2025 5:38 pm Supla nie ma niczego sensownego do diod adresowanych.
Jedynie można to w RGB wrzucić i ustawiać wszędzie taki sam kolor i jasność.
Możesz próbować jakieś efekty załączać np wirtualnymi przekaźnikami
Inspirując się trochę projektem @veeroos (viewtopic.php?t=17626) a więc i przy okazji projektem @radzik_r (viewtopic.php?p=118494#p118494) popełniłem wstępnie klasę:

Code: Select all

/*
 Copyright (C) malarz
*/
#include <supla/control/rgb_base.h>
#include <Adafruit_NeoPixel.h>

class RgbLeds : public Supla::Control::RGBBase {
  public:
    RgbLeds(uint16_t number, int16_t pin) {
          numberOfLeds = number;
          pixels = new Adafruit_NeoPixel(numberOfLeds, pin, NEO_GRB + NEO_KHZ800);

          pixels->begin();
    }
    void setRGBWValueOnDevice(uint32_t red,
                              uint32_t green,
                              uint32_t blue,
                              uint32_t colorBrightness,
                              uint32_t brightness) {

      red   = (red+1)   * (colorBrightness+1) / 4 / 1024 - 1;
      green = (green+1) * (colorBrightness+1) / 4 / 1024 - 1;
      blue  = (blue+1)  * (colorBrightness+1) / 4 / 1024 - 1;

      RGBcolor = pixels->Color(red, green, blue);
    }

  void iterateAlways() {
    // włączanie kolejnych LEDów
    if (isOn() && lightedLeds<numberOfLeds && (millis()-lastTime >= OneLedTime) || (millis() < lastTime)) {
      lastTime = millis();
      SUPLA_LOG_DEBUG("TASMA RGB zapalanie diody %d", lightedLeds);
      pixels->setPixelColor(lightedLeds, RGBcolor);
      pixels->show();
      lightedLeds++;
    }

    // zmiana koloru LEDów
    if (lightedLeds) {
      for (int i=0; i<lightedLeds; i++){
        pixels->setPixelColor(i, RGBcolor);
      }
      pixels->show();
    } 

    // wyłączanie kolejnych LEDów
    if (!isOn() && lightedLeds>0 && (millis()-lastTime >= OneLedTime) || (millis() < lastTime)) {
      lastTime = millis();
      lightedLeds--;
      SUPLA_LOG_DEBUG("TASMA RGB gaszenie diody %d", lightedLeds);
      pixels->setPixelColor(lightedLeds, 0);
      pixels->show();
    }
  }

  private:
    Adafruit_NeoPixel *pixels;
    uint16_t numberOfLeds;
    uint16_t lightedLeds = 0;
    uint32_t RGBcolor = 0;

    int OneLedTime = 200;
    uint32_t lastTime = 0;
};
Działa w miarę zgodnie z oczekiwaniem i pomysłem veeroos.

W różnych momentach pojawia się tylko problem polegający na przełączeniu się w aplikacji jasności na 0 (czarny/ciemny), wyłączenia itp. Nie przenosi się to od razu na LEDy (nie zmienia się wartość odczytywana przez isOn(), nie jest wywoływana funkcja setRGBWValueOnDevice(). Ale późniejszy jakikolwiek ruch w aplikacji w efekcie prowadzi do wygaszenia LEDów.

Przydałoby mi się jakiś krótki opis działania klasy (co trzeba przedefiniować dla swojego sprzętu aby wszystko działało dobrze).
Próbuję przerobić pomysły na działające projekty w ArduinoIDE.
User avatar
veeroos
Posts: 1081
Joined: Sun Mar 20, 2022 9:30 am
Location: Głogów
Has thanked: 1 time
Been thanked: 9 times

Post

już Ci mówię dlaczego tak jest, bo po załączeniu kanału narasta jasność i podczas zapalania pierwsze parę diod jest ciemniejszych, więc tak naprawdę należało by zanim odpali się animacja odczekać z 1s i dopiero to odpalić, tak chyba u Marcina (mmof) zrobiłem lekkie opóźnienie
Zamel Mew-01, Zamel PEW-01, Zamel SBW-01, Zamel THW-01, Zamel SRW-01, Zamel mSLW-02, Auraton BOX + Indor Sensor, Airly Gate By Veeroos, Zigbee to Supla Gateway + sensors, Zamel SGW-01 and more

https://github.com/v33r005
User avatar
klew
Posts: 13907
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

isOn działa w oparciu o ustawienie docelowej jasności dla RGB lub dimmera, a nie na podstawie aktualnej jasności. Także to powinno działać niezależenie od tego mechanizmu rozjaśniania.

Nadpisałeś iterateAlways() bez zachowania oryginalnej funkcji. Najlepiej wywołaj w ramach swojego iterateAlways() także bazowe:
RGBWBase::iterateAlways();

Metoda setRgbwValuesOnDevice może być wywoływana nawet co 1 ms. Także upewnij się, że te metody z "pixels" wykonują się szybciej niż 1 ms.
Najlepsze suple dla Twojego domu :mrgreen:
User avatar
malarz
Posts: 506
Joined: Wed Jan 27, 2021 4:04 pm
Been thanked: 2 times

Post

veeroos wrote: Mon Dec 08, 2025 10:17 am już Ci mówię dlaczego tak jest, bo po załączeniu kanału narasta jasność i podczas zapalania pierwsze parę diod jest ciemniejszych, więc tak naprawdę należało by zanim odpali się animacja odczekać z 1s i dopiero to odpalić, tak chyba u Marcina (mmof) zrobiłem lekkie opóźnienie
To nie ma znaczenia, bo co chwila ten kolor bywa zmieniany. W mojej implementacji animacja podczas włączania/wyłączania kolejnych LEDów nie blokuje zmiany koloru. Trwającą animację rozpoznaję po ilości zapalonych LEDów a nie jakiś flagach logicznych. A zmiany koloru są dokonywane jeżeli przynajmniej jeden z LEDów jest zapalony.
Last edited by malarz on Mon Dec 08, 2025 11:20 am, edited 1 time in total.
Próbuję przerobić pomysły na działające projekty w ArduinoIDE.
User avatar
malarz
Posts: 506
Joined: Wed Jan 27, 2021 4:04 pm
Been thanked: 2 times

Post

klew wrote: Mon Dec 08, 2025 10:50 am isOn działa w oparciu o ustawienie docelowej jasności dla RGB lub dimmera, a nie na podstawie aktualnej jasności. Także to powinno działać niezależenie od tego mechanizmu rozjaśniania.
Mi się wydawało, że isOn() daje info po prostu o naciśnięciu "Włącz".
klew wrote: Mon Dec 08, 2025 10:50 am Nadpisałeś iterateAlways() bez zachowania oryginalnej funkcji. Najlepiej wywołaj w ramach swojego iterateAlways() także bazowe:
RGBWBase::iterateAlways();
Fakt, była odziedziczona. Ja sprawdziłem tylko w klasie RGBBase a tam nie było :-(
klew wrote: Mon Dec 08, 2025 10:50 am Metoda setRgbwValuesOnDevice może być wywoływana nawet co 1 ms. Także upewnij się, że te metody z "pixels" wykonują się szybciej niż 1 ms.
Ja tam wywołuję jedynie Color, a to funkcja która tylko trzy 8 bitowe wartość skleja w jedną 32 bitową. Co się stałoby gdyby ta funkcja działała za długo? W skrajnych przypadkach przepełnię pamięć? Czy to coś bardziej przyziemnego (Suplowego)?
Próbuję przerobić pomysły na działające projekty w ArduinoIDE.
User avatar
klew
Posts: 13907
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

malarz wrote: Mon Dec 08, 2025 11:18 am Mi się wydawało, że isOn() daje info po prostu o naciśnięciu "Włącz".
isOn zwraca true, gdy jest włączone jakieś "świecenie". Nie tu nigdzie informacji o przyciskach, ani tego co było wciśnięte.
malarz wrote: Mon Dec 08, 2025 11:18 am Ja tam wywołuję jedynie Color, a to funkcja która tylko trzy 8 bitowe wartość skleja w jedną 32 bitową. Co się stałoby gdyby ta funkcja działała za długo? W skrajnych przypadkach przepełnię pamięć? Czy to coś bardziej przyziemnego (Suplowego)?
Nie jestem pewien ;). Zależnie od użytej implementacji timera, może on się wykonać zanim poprzedni skończy, albo może blokować inne taski.
Ogólna zasada jest taka, że ta metoda docelowo odpala się co 1 ms i kod, który tam jest, nie może być blokujący i musi się wykonać szybko (dużo poniżej 1 ms).
Najlepsze suple dla Twojego domu :mrgreen:
User avatar
veeroos
Posts: 1081
Joined: Sun Mar 20, 2022 9:30 am
Location: Głogów
Has thanked: 1 time
Been thanked: 9 times

Post

Dobra bo głupoty napisałem, bo odpisywałem komuś innemu na pytania związane z nierównomiernym zapalaniem się paska i się zamotałem :D . Nie wiem czy dokładnie o to Ci chodzi, ale zobacz jak ja to rozwiązałem w swoim programie, musiałem zapisać stan paska w jakim się on znajdował tak aby zaczęło się wygaszać od tego momentu do którego się zapaliło i na odwrót, musiałem stworzyć zmienną bool (trwa_animacja), która informowała czy animacja już się zakończyła, czy nie, wtedy odpowiednio układ reagował. Zauważ też, że w moim programie jak zapalają się diody i jak zmieniasz kolor w kanale RGB to od momentu włączenia danego koloru kolejne diody zapalają się na ustawiony kolor. Przeportuj mój program pod ESP8266 ustaw na sztywno prędkości reagowania na przycisk, czasy rozjaśniania i wygaszania, prędkość animacji i spróbuj stworzyć klasę uniwersalną pod pasek programowalny.
Zobacz na ten efekt, który później dorobiłem do tego programu:
https://youtube.com/shorts/W7bKKHs0sbk?feature=share
Pomyśl nad klasą która by mogła też takie efekty generować, ewentualnie zostawić klasę dziedziczącą w takiej formie jak mniej więcej ja i Radek zrobiliśmy, do tego użyć dedykowanej biblioteki i wywoływać tylko wewnątrz klasy zapalanie się konkretnego piksela, a nie generować w klasie efektów.
coś na przykład takiego:

Code: Select all

RgbLeds->SetPixel(numPixel, ColorPixel);
No chyba, że źle myślę. Cała logika wtedy by była w programie, a obsługa pikseli w klasie. Ja właśnie tak sobie to wyobrażałem, chciałem też stworzyć taką klasę, ale brakuje wiecznie mi czasu.
Zamel Mew-01, Zamel PEW-01, Zamel SBW-01, Zamel THW-01, Zamel SRW-01, Zamel mSLW-02, Auraton BOX + Indor Sensor, Airly Gate By Veeroos, Zigbee to Supla Gateway + sensors, Zamel SGW-01 and more

https://github.com/v33r005

Return to “Pomoc”