AQI LED - Zdalny diodowy sygnalizator

#34

No to małych przebojach się udało :slight_smile:
Obudowa się jeszcze drukuje, ale działa.

Mam pytanie - lokalny czujnik adres mogę podać typu: nam-numer.local/data.json ?

Działa mi z AQI, ale nie mogę uruchomić tego lokalnie.

Czy pierwsza dioda ma jakieś dodatkowe znacznie? Raz mam na zielono, a raz na żółto.

EDIT:
Takie małe spostrzeżenia:
Przy ringu 16 diod nie ma gradientu, z tego co widzę to jest 5 zielonych, 6 żółtych i pewnie 5 czerwonych (jak dotychczas miałem jedną zapaloną).
Pierwsza dioda mogła by robić jako dioda sygnalizacyjna. Czyli przy braku połączenia z WiFi mogła by się świecić na niebiesko, przy problemie z pobieraniem danych na fioletowo. Przy aktualizacji mrugnięcie, a domyślnie wygaszona…
Może zamiast gradientu zrobić podział według kolorów z AQI. Według skali z której korzystają jest 5 kolorów, czyli wychodzi po 3 diody na kolor plus pierwsza sygnalizacyjna.

#35

Mam pytanie - lokalny czujnik adres mogę podać typu: nam-numer.local/data.json ?

Opcja z adresem IP i ustawieniem Sensor type: local device powinna zadziałać:

10

Czy pierwsza dioda ma jakieś dodatkowe znacznie? Raz mam na zielono, a raz na żółto.

  • Żółta: pobieranie danych,
  • Zielona: dane pobrano OK,
  • Czerwona: nie można pobrać danych

Przy ringu 16 diod nie ma gradientu, z tego co widzę to jest 5 zielonych, 6 żółtych i pewnie 5 czerwonych (jak dotychczas miałem jedną zapaloną).
Może zamiast gradientu zrobić podział według kolorów z AQI. Według skali z której korzystają jest 5 kolorów, czyli wychodzi po 5 diod na kolor plus pierwsza sygnalizacyjna.

Dosyć trudno zrobić gradient przy niskim poziomie jasności. Z moich doświadczeń wynika, że diody mogą przyjąć wtedy tylko kilka kolorów. Skoro gradient i tak nie działa, wprowadziłem 5 kolorów z aqi.eco - choć kilka z nich (lekko zielony i żółty) i tak wyglądają tak samo na LEDach:

Ta wersja umożliwia konfigurację liczby diodek i jasności przy użyciu panelu WWW, ale wiąże się to z utratą ustawień wifi dla już skonfigurowanych czujników (znowu trzeba się połączyć z siecią “AQI LCD” i wpisać hasło wifi). W przyszłości postaram się ograniczyć podobnych takich zmian do minimum.

1 Like
#36

A nie lepiej zamiast IP, które może być zmienne (mam ruter Huawei B315s-22 i nie moge ustawić stałego IP) korzystać z nazwy modułu.
W tej chwili po wpisaniu nazwy http://nam-14696265.local/data.json skrypt nadaje sieć, ale nie można się dostać do konfiguracji.

A i czy moduły (NAM i AQI LED) muszą być na tej samej sieci WiFI, czy wystraszy ze są na tym samym routerze?

#37

A nie lepiej zamiast IP, które może być zmienne (mam ruter Huawei B315s-22 i nie moge ustawić stałego IP) korzystać z nazwy modułu.

Nazwa nam-14696265.local jest nadawana przez mDNS. AQI-LED nie ma w tej chwili wsparcia dla tej usługi od strony klienckiej. Sprawdzę, czy da się to łatwo dodać.

W tej chwili po wpisaniu nazwy http://nam-14696265.local/data.json skrypt nadaje sieć, ale nie można się dostać do konfiguracji.

No tak, z tym coś zrobię.

A i czy moduły (NAM i AQI LED) muszą być na tej samej sieci WiFI, czy wystraszy ze są na tym samym routerze?

Do łączenia przez IP-ka, musi być możliwość przeroute’owania się z jednego urządzenia do drugiego. Co do mDNS i jego potencjalnej obsługi w przyszłości, nie jestem pewien jak to działa.

#38

Jaką jasność ustawić aby jak najlepiej oddać barwy?

Staram się sprawdzić czy ilość pokazywanych kolorów (5) jest poprawny dla ringa 16 diod.
Na jasności 1 widać zielone i żółte, ale w
uint32_t colors[] = {0x57b108, 0xb0dd10, 0xffd911, 0xe58100, 0x990000};
są dwa zielone ciemny i jasny, żółty, pomarańczowy i bordowy (czerwony).

Na jasności 75 pierwsza dioda jest wyraźnie zielona i mruga na żółto (aktualizacja), później jakby jasny zielony i przechodzi w żółty.

PS
W poprzednim poście zrobiłem byka :stuck_out_tongue: bo jak mamy 5 kolorów to na każdy przypada 3 diody, a wklepałem 5.

Tak u mnie wygląda AQI:
Screenshot_2019-12-22%20Jako%C5%9B%C4%87%20powietrza%20-%20Czarna%20Rola%2024

A tak palą się diody na jasności 1:

EDIT
Pozmieniałem na inne kolory aby był kontrast i jest OK, po 3 diody na kolor.
Tylko diody źle przedstawiają barwy.

#39

A zobacz takie kolory:
uint32_t colors[] = {0x008000, 0x3FFF15, 0xFFFF00, 0xFF4500, 0x800000};
i jasność na 16 lub 50 lub 255.
Ogólnie to na każdej chyba są różnice miedzy poszczególnymi etapami.

Takie małe spostrzeżenia, spadło mi zanieczyszczenie do niskiego a dalej 1 dioda żółta.
Czy w aqi-lcd-master\src\pollution-levels.cpp
nie powinno być:
return ((v - prevLevel) / (currentLevel - prevLevel) + i - 1) / 5;
zamiast
return ((v - prevLevel) / (currentLevel - prevLevel) + i - 1) / 4;
czyli dzielimy przez 5 zamiast przez 4?

AQI LED - obudowa 3D Print
#40

Takie pytanie bo nie mogę poszukać gdzie jest obliczane numPixels?

#41

Wesołych Świąt!

Wsparcie mDNS to jakiś koszmar, ale ostatecznie chyba się udało:

Od powyższego commitu, AQI-LCD powinien wspierać lokalne adresy w postaci:
http://nam-2392534.local/data.json

Takie pytanie bo nie mogę poszukać gdzie jest obliczane numPixels?

W tej chwili jest to wartość ustawiana w panelu WWW, przekazywana jako pierwszy argument konstruktora Adafruit_NeoPixel():

#42

A zaglądałeś w kod odpowiadający za skalę PM 2.5 i PM 10?
Ja oprócz zmian kolorów LED, zmieniłem sposób działania pierwszej diody sygnalizacyjnej. Nie pali mi na zielono cały czas, żółta i czerwoną będą palić się do skutku.

#43

Idea jest taka, że z tej funkcji dostajemy liczbę między 0 a 1, pokazującą w którym miejscu skali jesteśmy. Żeby było ciekawiej, nie chcę, żeby funkcja rosła liniowo, w zależności od v, ale żeby rosła wg. poziomów zanieczyszczenia, np. dla PM2.5 mamy: {15, 30, 55, 110}. Oznacza to, że np. jeśli v=55, to chcę widzieć, że rozpoczynamy poziom 3 z 4 dostępnych, więc powinniśmy dostać 0.75.

Mamy tutaj takie niezmienniki:

  • i = indeks zakresu currentLevel
  • i-1 = indeks zakresu prevLevel
  • prevLevel <= v < currentLevel
  • 1 <= i <= 4
  • 0 <= i-1 <= 3

Ten pierwszy iloraz oblicza gdzie między prevLevel a currentLevel leży v. Jeśli v=prevLevel, to dostajemy 0, a jeśli v~currentLevel, to mamy iloraz = 0.999.

Do tego ilorazu dodajemy indeks zakresu prevLevel (czyli i-1). Maksymalnie może to być 3.

Stąd, jeśli v jest bardzo blisko ostatniego zakresu, dostaniemy 0.999 + 3 = 3.999. Dzielimy to przez 4, żeby dostać 0.999. Przykładowo, dla PM2.5=109, dostajemy poziom 0.995454 (co oznacza, że jesteśmy blisko końca skali).

No tak, im wyższa jasność, tym więcej kolorów można rozpoznać. Ja używam paska z jasnością 1, stąd pewne problemy (większość składowych jest skalowana do 0). Sprawdzę tę propozycji nowej palety przy wyższej jasności.

#44

No właśnie z tymi poziomami nie jest chyba tak do końca ok.
Bo poziomów jest 5 a nie 4:

  • bardzo niski
  • niski
  • średni
  • wysoki
  • bardzo wysoki

Braknie skali dla bardzo wysokiego, więc zapala się razem z trzecią diodą pomarańczową - przynajmniej przy 16 diodach.

#45

No tak, “1” oznacza wartość pomiaru >= najwyższy próg (110 dla PM25, 180 dla PM10):

nazwa          | PM2.5       | poziom
---------------+-------------+-------
bardzo niski   | [0,   15)   | [0.00, 0.25)
niski          | [15,  30)   | [0.25, 0.50)
średni         | [30,  55)   | [0.50, 0.75)
wysoki         | [55,  110)  | [0.75, 1.00)
bardzo wysoki  | [110, ...)  |  1.00

Aby policzyć ilość zapalonych LEDów, wystarczy pomnożyć poziom przez całkowitą ilość diód w instalacji (np. 0.75*16 = 9). Zgadzam się, że w przypadku przekroczenia poziomu bardzo wysokiego, tracimy informację o tym, jak bardzo ten poziom jest przekroczony (bo poziom=1 dla PM2.5=110 ale i PM2.5=300). Myślałem o dodatkowych efektach, np. ostatnia dioda mrugająca wolniej lub szybciej. Czy masz jakieś inne pomysłu lub propozycje?

#46

Sam nie wiem jeszcze jak, aktualnie zrobiłem tak:

const int PollutionLevels::PM25_LEVELS[] = {0, 15, 30, 55, 110, 120};
const int PollutionLevels::PM10_LEVELS[] = {0, 25, 50, 90, 180, 190};
const int PollutionLevels::PM25_MAX = 25;
const int PollutionLevels::PM10_MAX = 50;
float PollutionLevels::getLevel(const JsonModel *model) {
float pm25Level = findThreshold(model->pm25, PM25_LEVELS);
float pm10Level = findThreshold(model->pm10, PM10_LEVELS);
return max(pm25Level, pm10Level);
}
float PollutionLevels::findThreshold(float v, const int levels[]) {
float prevLevel = 0;
for (int i = 1; i < 6; i++) {
float currentLevel = levels[i];
if (currentLevel > v) {
return ((v - prevLevel) / (currentLevel - prevLevel) + i - 1) / 5;
}
prevLevel = currentLevel;
}
return 1.0F;
}

Czyli dodałem dodatkową skale, w PM10 i PM2.5, twoje obliczenia dziele przez 5 a nie przez 4.
Mam zamiar jeszcze to dopracować, ale wyniki na LEDach wydają mi się lepsze i porównywalne do AQI.
Ogólnie widziałbym to tak:

  • po przekroczenie progu minimum zapala pierwszy LED w danej skali, pozostałą ilość zapala się stopniowe wraz ze zwrotem wartości. Ostatnia dioda z zakresu od pewnego momentu do maksymalnego zakresu.
  • ostatni stan czyli bardzo wysoki zapalałby się również stopniowo po przekroczeniu maksa (PM10 - 180, PM2.5 - 110), więc trzeba by dorobić dodatkowy zakres (tak jak ja zrobiłem) tylko bym jeszcze zwiększył tak do PM10 - 230, PM2.5 - 150.
#47

Jeśli dobrze rozumiem opis, to tak to działa w tej chwili, np. dla zakresu: PM2.5=[0,15) mamy poziom [0,0.25), co może się przełożyć na 1, 2 lub 3 zapalone diody na 16-LEDowym ringu (lub 1-14 diód przy 60-LEDowym pasku).

OK, czyli proponujesz aby przeskalować wskazania w dół i w powstałe miejsce dodać jeszcze jeden próg. Jest to jakieś rozwiązanie. Mam jedną wątpliwość: istniejące progi są podparte mniej lub bardziej oficjalnymi wskaźnikami. Pełny ring w tej chwili oznacza, że doszliśmy do końca skali, indeks jest bardzo wysoki. Jeśli dodamy nowy zakres, będzie on siłą rzeczy arbitralny (bo czemu np. PM2.5=150 a nie 300?)

Można by to rozwiązać dodając nową sekcję konfiguracji w panelu WWW i tam pozwolić na wprowadzenie progów lub zrezygnować z progów całkowicie, skalować wartości liniowo i zapytać użytkownika jak wysoki powinien być PM10/PM2.5 aby zapaliły się wszystkie diody.

Z drugiej strony, nie jestem przekonany do skalowania w dół. Płuca mamy takie same, niezależnie od miejsca. Takie przeskalowanie może prowadzić do sytuacji, w której oswajamy się z bardzo wysokimi wskazaniami (nie jest jeszcze aż tak źle, skoro 3 ostatnie diody są jeszcze zgaszone). Dlatego chyba wolałbym zostawić wszystkie diody zapalone przy wartościach maksymalnych pochodzących z tej strony i wprowadzić dodatkowe efekty wizualne aby określić, jak bardzo przekroczyliśmy ostatni poziom.

#48

Według mojej teorii działa u mnie jeden układ. Nie ma obniżania czy zawyżania skali.
Testowałem to iż utworzyłem swój plik json i wrzuciłem na serwer. Ręcznie zmieniałem wartości i patrzyłem jak zachowuje się ring.
Przy ustawieniu maksa wartości z zakresów PM palą się wszystkie diody. Zmniejszenie o jeden gasi czerwone i o ile dobrze pamiętam ostatnią pomarańczową. Czyli nie jest płynnie prezentowany wynik.
Obliczenia:
Od ilości diod odjąć 1 na diodę sygnalizacyjną, pozostałą część podzielić na 5. Przy 16 diodach wyjdzie równo, przy 24 i 32 bym widział jako zaokrąglenie czterech zakresów w górę (bo są bardziej przydatne) a stan bardzo wysoki to co pozostanie czyli dla 24 diod byłyby to 3 diody, a dla 32 jedna czerwona.
Zauważ że teraz przy przekroczeniu progu minimalnego z któregoś zakresu, nie zapala się diodą odpowiadającą jego kolorowi.
Twoje zakresy dla koloru podziel przez ilość diod na kolor. Pierwsza dioda musiałby się zapalać po przekroczeniu progu już o 0,01. Kolejne według dzielenia. Czyli przy 3 diodach na kolor, pierwsza zapala się po przekroczeniu o 0,01, druga w ⅓ zakresu a trzecia w ⅔ zakresu.

Tak bym to widział.
Będę próbował to odciągnąć, ale nie jestem programistą. Jedynie coś tam się bawiłem z JS i PHP. A czeka mnie jeszcze przeniesienie mojego forum na nowy serwer. Ale jak to się mówi, nie spieszy mi się i w wolnej chwili będę dłubał w tym projekcie.

#49

Na razie wrzuciłem do kodu Twoje kolory, rzeczywiście, wyglądają lepiej, jasno- i ciemno-zielony są odróżnialne, dzięki :slight_smile:

Co do progów, to rozumiem, że dobrze byłoby, gdyby kolory LEDów pokrywały się z aktualnym kolorem na aqi.eco. Obie wizualizacje działają w trochę inny sposób - na aqi.eco mamy jedno pole z kolorem który zmienia się już przy przekroczeniu progu o 0.01, na LEDach mamy skalę która może być nieco bardziej leniwa (bo potrzeba więcej niż 0.01 aby zapaliła się kolejna diodka). Pomyślę jeszcze jak można by to ujednolicić. Dzięki za feedback i konstruktywne propozycje!

1 Like
#50

A możesz dodać na stronie konfiguracyjnej checkbox “Config LED disabled”, oraz w led-fronted.cpp po:
switch (status) {
case SUCCESS:
color = 0x00ff00;
break;

case FAILURE:
color = 0xff0000;
break;

case IN_PROGRESS:
color = 0xffff00;
break;

}
strip->setPixelColor(0, color);
strip->show();

Dodać dodatkowego ifa uzależnionego od dodanego checkboxa który by zawierał:
if (color == 0x00ff00) {
delay(1000);
strip->setPixelColor(0, 0x0);
strip->show();
}

Czyli by można było sobie ustawić czy pierwsza dioda ma się palić na zielono, czy wygasić ją po 1 sekundzie gdy odczyt był poprawny.

#51

Rzeczywiści działa, ale jest jakiś problem.
Pierwsza próba pobrania danych po rozruchu nie dochodzi do skutku:

Fetching from local device: http://nam-14696265.local/data.json
State changed from: 3 to 4
[HTTP] Begin...
[HTTP] Can't resolve nam-14696265.local

Kolejne już przechodzą bez problemu.
Możliwe ze stara się pobrać zanim coś się załaduje, lub połączy na dobre z WiIF.

EDIT
A jednak później też się pojawiają problemy.

#52

Moja nowa obudowa :slight_smile:IMG_20191230_234513

#53

To problem wynikający z tego, że mDNS pobieramy asynchronicznie i czasami zdarza się, że drugi asynchroniczny proces (pobieranie danych z czujnika) uruchomi się zanim mDNS zwróci odpowiedź. Mogę dodać synchronizację, ale masa z tym kłopotów (np. co jeśli mDNS w ogóle nie zwróci odpowiedzi). Najłatwiej będzie zignorować ten komunikat błędu i założyć, że uruchomienie AQI-LCD z mDNS-em może zająć około minuty :slight_smile:

A jednak później też się pojawiają problemy.

Nie wiem jakiego typu problemy masz na myśli, ale ja też natrafiłem na kilka (np. AQI-LCD resetował się gdy coś otwierałem okienko drukarki na komputerze :). Problemy te były spowodowane dużym ruchem na broadcaście 224.0.0.251 (wybranym do obsługi mDNS). Wiele domowych urządzeń sieciowych ogłasza tam swoje adresy. Mały ESP8266 nie był w stanie tego wszystkiego przetworzyć i wybrać, czym powinien się zainteresować. Pewnie można to jakoś zoptymalizować, ale będę chyba raczej czekał na PR-y. Zalecaną opcją jest użycie aqi.eco, a jeśli już lokalny czujnik, to z własnym IPkiem.