logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Rysowanie wykresów w HTML na Arduino R4 - statystyki, pomiary na mini stronie WWW

p.kaczmarek2 01 Lut 2024 11:05 1428 10
REKLAMA
MediaMarkt Black Week
  • Rysowanie wykresów w HTML na Arduino R4 - statystyki, pomiary na mini stronie WWW
    Dzisiaj pokażę jak można postawić na Arduino R4 WiFi prostą stronę WWW wyświetlającą zebrane przez nas pomiary na ładnych, czytelnych wykresach. Być może przyda się komuś to do projektu typu czujnik temperatury, pomiar zużycia energii czy tam stacja pogodowa. Wykresy będzie rysować dobrana przeze mnie biblioteka Javascript, której skrypty pobierane będą z internetu. Nie zamierzam hostować ich na Arduino R4 WiFi, co nieco uprości nam projekt.

    Wstęp - jak rysować wykresy na HTML?
    Zacznijmy od wytłumaczenia jak w ogóle można wyświetlić wykres na stronie WWW. Na razie kwestię Arduino pomijamy.
    Zasadniczo mamy do tego gotowe biblioteki, które są napisane w Javascripcie. Podpinamy taki Javascript do naszego HTML, podajemy mu w jakiejś formie dane i ten skrypt wygeneruje nam wykres, o ile nasz klient go obsługuje.
    Tego typu bibliotek jest szeroki wybór, ja zdecydowałem się na Google Charts Library, gdyż jest ona prosta w użyciu.
    Poniżej mamy przykładową stronę wyświetlającą wykres:
    Kod: HTML, XML
    Zaloguj się, aby zobaczyć kod

    Warto zwrócić uwagę, że bibliotekę JS załączam z zewnętrznego serwera. Ma to swoje plusy i minusy. Plusem jest to, że nie muszę jej hostować samodzielnie u siebie, lecz minusem jest to, że bez internetu (lub jeśli hosting tej biblioteki wygaśnie) nie otrzymamy wykresu.
    W samej funkcji drawChart widać jak ustawiane są dane. Będziemy musieli wymyśleć, jak je wstawić tam z Arduino. Ale na początek - rezultat działania powyższego pliku HTML:
    Rysowanie wykresów w HTML na Arduino R4 - statystyki, pomiary na mini stronie WWW


    Przenosimy na Arduino R4 WiFi
    Na początek przydadzą się jakieś przykładowe dane. Uznałem, że wygeneruję sobie ich wartości losowo. Nasze dane będą reprezentowane poprzez czas wykonania pomiaru (typ time_t) oraz jego wartość:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Ten czas tutaj to tzw. epoch/unix time, można go odszyfrować chociażby na tej stronie:
    https://www.epochconverter.com/
    Ta liczba to po prostu liczba sekund od 1 stycznia 1970. Wiążą się z tym pewne problemy, np. kwestia przepełnienia integera 32-bitowego (błąd roku 2038), ale to nie temat na teraz. Chyba, że ktoś czyta ten artykuł w 2038 roku? Jeśli tak, to dajcie znać.
    W każdym razie - dane mamy wygenerowane.
    Teraz skopiujmy przykład serwera HTTP z Arduino R4...
    Opisywałem to tutaj:
    Arduino R4 WiFi i ArduinoHttpServer - poprawki, uruchomienie, przykłady użycia
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Najciekawsze, czyli obsługę GET zostawiłem na koniec:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Powyższy kod składa wspomniany wcześniej dokument HTML z części, każda część to osobny fragment tekstu. Jedynie dane pomiarów są generowane dynamicznie. Wartości temperatury oraz czasu z pamięci są zamieniane na tekst. Czas wymaga specjalnej obsługi, ale na szczęście mamy do tego funkcje na Arduino, przykład poniżej:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Przy tworzeniu danych w C należy pamiętać o tym, by nie dać przecinka po ostatnim elemencie tablicy w JSON. Z tego powodu w pętli sprawdzam, czy indeks nie jest zerowy i tylko wtedy umieszczam przecinek przed kolejnym elementem.
    Kompilujemy i wgrywamy - oto rezultat:
    Rysowanie wykresów w HTML na Arduino R4 - statystyki, pomiary na mini stronie WWW
    Dane z pamięci są poprawnie wyświetlane na naszej małej stronie WWW.

    Warto pamiętać, że w zależności od potrzeby można zmienić sam typ wykresu i sposób jego rysowania. W razie pytań odsyłam do dokumentacji użytej biblioteki.

    Podsumowanie
    To był tylko przykład a dane były wygenerowane pseudolosowo, ale w ten sam sposób można by wyświetlać rzeczywiste pomiary, chociażby temperatury i wilgotności z DHT11. Rozmiar tablicy pomiarów trzeba by tu odpowiednio dobrać i pewnie też polecałbym potraktować ją jako bufor kołowy by wygodnie nadpisywać/"zapominać" zbyt stare pomiary, ale idea generowania wykresu i tak byłaby taka sama.
    W przypadku bardziej zaawansowany projektów można by się też pokusić o zapis pomiarów do pamięci EEPROM oraz o możliwość np. ich stronicowania (w zależności od tego na której stronie jest użytkownik odczytywać inne sekcje pamięci), ale o tym innym razem.
    Czy widzicie jakieś praktyczne zastosowanie dla tego typu wykresów? Zapraszam do dyskusji.

    Fajne? Ranking DIY
    Pomogłem? Kup mi kawę.
    O autorze
    p.kaczmarek2
    Moderator Smart Home
    Offline 
  • REKLAMA
    MediaMarkt Black Week
  • #2 20941345
    Sam Sung
    Poziom 33  
    Przerabiałem ten temat ~10 lat temu, bo zachciało się "Web 2.0" i czegoś wektorowego i interaktywnego zamiast wykresów PNG generowanych na serwerze skryptem PHP (biblioteką GD).
    Pamiętam, że zbadałem kilka gotowych bibliotek i owszem - o ile dla kilkunastu punktów na wykresie (jak wyżej) radziły sobie całkiem nieźle i robiły ładne wykresy, to przy pomiarach z całej doby co minutę z kilkunastu czujników renderowanie trwało i trwało w nieskończoność (> 10 minut), co jest oczywiście nie do przyjęcia.
    A jak to obecnie wygląda? Czy na starszym smartfonie da się zobaczyć wykres z np. 70000 punktów w ciągu kilku sekund?
    A wystarczy trochę wyobraźni 2D i można samemu napisać sobie kod renderujący takie wykresy, który będzie działał o niebo szybciej niż znane mi gotowce.
    Ja postawiłem na generowanie poddrzewa SVG. Znając zakres danych wystarczy ustalić skalowanie, wygenerować osie, linie pomocnicze i etykiety, a każda linia z pomiarami z jednego czujnika może być osobną ścieżką czyli <path d="...">, np.:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    tylko, że na taki jeden czujnik jest ~50 kB tekstu, a czujników może być kilkadziesiąt :) Oczywiście te dane w takiej ilości istnieją tylko w pamięci przeglądarki i nie obciąża to w ogóle naszych urządzeń IoT czy serwerka trzymającego historię pomiarów.
    Przy pomocy stylów CSS i elementu <title> można zapewnić podstawową interakcję w postaci pokazania etykiety (tu przykładowo "Kolektor słoneczny @D.O.M.") i pogrubienia danej linii po najechaniu myszą (lub dotknięciu na smartfonie).
    Łatwe do zrobienia i mało obciążające dla przeglądarki jest też rysowanie poziomej i pionowej linii w miejscu kursora myszy, dzięki czemu łatwo odczytać X i Y.
    Nie ma bajerów typu pokazywanie w dymku wartości, ale to właśnie to było jedną z przyczyn niesamowitego przeciążenia przeglądarki, które wykluczyło gotowce z możliwości użycia.

    A do czego się takie wykresy przydają?
    Ano do sprawdzania, jaki był mróz, czy woda się nagrzała, o której godzinie woda grzana słońcem jest najcieplejsza, czy wystąpiły jakieś anomalie w kotłowni lub układach (np. niechciane podgrzewanie wody od C.O., bo ktoś zapomniał zakręcić jakiś zawór; nagrzewanie kolektora słonecznego o kilka stopni o 3 w nocy itd.)
    Oprócz danych z czujników zbieram też dane o załączeniu i wyłączeniu urządzeń i w przypadku urządzeń o pracy cyklicznej (np. lodówka, kocioł gazowy, pompa kolektorów słonecznych) można je przedstawić jednowymiarowo - czyli że pracowało od...do - lub dwuwymiarowo - czyli pole wykresu takie samo, ale rozciągnięte w poziomie na cały cykl pracy - i wtedy widać jaki był procentowo udział pracy i przerwy w każdym cyklu (na ile % urządzenie pracowało); można wtedy oceniać wpływ warunków zewnętrznych albo badać stopień zużycia czy obserwować wszelkie anomalie.

    Czyli moja konkluzja jest taka, że przy pomocy takiego gotowca jak pokazany w tym temacie pozornie łatwo jest zacząć, ale to ślepa uliczka, bo nawet do domowej kotłowni - jak się chce zrobić wykres z jednej doby - żaden gotowiec się nie nadawał i trzeba było wziąć sprawy w swoje ręce.
    Rysowanie wykresów w HTML na Arduino R4 - statystyki, pomiary na mini stronie WWW Rysowanie wykresów w HTML na Arduino R4 - statystyki, pomiary na mini stronie WWW
  • #3 20944292
    kamil3211
    Poziom 10  
    Czy nie lepiej po prostu zrobić aplikacje natywną które robi się prościej i po udp przesłać dane a niech aplikacja robi reszte.
  • REKLAMA
    MediaMarkt Black Week
  • #4 20944630
    zigipl
    Poziom 15  
    kamil3211 napisał:
    Czy nie lepiej po prostu zrobić aplikacje natywną które robi się prościej i po udp przesłać dane a niech aplikacja robi reszte.

    Prościej czyli w czym? Oszacuj czas wykonania rozwiązania zaproponowanego przez OP oraz zrobienie wg pomysłu jaki zaproponowałeś?
  • #5 20944788
    kamil3211
    Poziom 10  
    flutter qt processing ide. jedno z 3 użyłbym flutter(też można strony internetowe) bo jest najbardziej otwarty na inne metody komunikacji i generalnie web wydaje się być jakoś rozpiepszony. Tyle metod tworzenia stron tyle języków a jak dla mnie to robienie dziadostwa na wcześniejszym dziadostwie. Zamiast zrobić porządnie od podstaw(mam namyśli te języki frameworki). Bo czemu nie mógłby być jeden język do backendu i frontendu co dla mnie ten podział wydaje się bezsensowny i tak.
  • #6 20945097
    Sam Sung
    Poziom 33  
    Bez uprzedzeń co do web można stworzyć FE w wybranym frameworku (np. Vue, Svelte czy React) oraz BE w tym samym jednym języku (TypeScript) i mamy produkt używalny w przeglądarce na każdym smartfonie, tablecie, laptopie czy PC bez instalowania na każdym z urządzeń wariantu aplikacji skompilowanej pod daną platformę.
    kamil3211 napisał:
    Bo czemu nie mógłby być jeden język do backendu i frontendu co
    Ależ może być jeden język do backendu i frontendu, np. TypeScript.
    kamil3211 napisał:
    dla mnie ten podział wydaje się bezsensowny i tak.
    Aplikacja rysująca wykres we Flutterze też musi skądś pobrać dane do wykresu, więc nawet, jeśli robi to przez UDP, czy tego chcesz, czy nie, znowu zarysowuje się podział na frontend i backend :)
  • #7 20946000
    zigipl
    Poziom 15  
    kamil3211 napisał:
    Zamiast zrobić porządnie od podstaw(mam namyśli te języki frameworki). Bo czemu nie mógłby być jeden język do backendu i frontendu co dla mnie ten podział wydaje się bezsensowny i tak.

    Nie zawsze chodzi żeby coś było porządne, ale też żeby zrobić w sensownym czasie. Nadal nie napisałeś jak czasowo wyglądałoby zrobienie całości korzystając z różnych rozwiązań.
  • #8 20946032
    kamil3211
    Poziom 10  
    Wczoraj z ciekawości chciałem narysować wykresy za pomocą zmiany kolorów pikseli a nie używać biblioteki. Było to troche prostsze. Jak nie popełnie jakiegoś głupiego błędu typu nie dam aplikacji uprawnień to komunikacji po sieci to z 30 min choć jest pare bibliotek do edycji pikseli a ja wybierałem te najgorsze to w innym projekcie zmarnowałem 5 godzin . W zasadzie pisząc porządne miałem na myśli umożliwia osiągnięcie jak najlepszych rezultatów w jak najkrótszym czasie.
  • #9 20947529
    phanick
    Poziom 28  
    Jestem temu przeciwny. Przez takiego typu zwyczaje i sztuczne "nadmuchiwanie" strony javascriptem, potem skrypty na stronie wykonują się wieki i wszystko zamula przeglądarkę aż do śmierci.
    Przykład::
    https://pogoda.interia.pl/prognoza-dlugoterminowa-warszawa,cId,36917

    Od generowania wykresów powinien być serwer, który wygeneruje odpowiedni obrazek (np. w PHP) i go zwróci przeglądarce, jak za starych dobrych czasów.
    Marzy mi się dzień, aby wreszcie wstal z kolan jakiś wizjoner i wziął za ryje tych wszystkich webowych szpeców z googla, fejsbuka, allegro, jutjuba i wielu innych przez których starsze przeglądarki umierają wykonując kod tych stron.
    Na kilkuletniej przeglądarce kilka lat temu te strony działały bez problemu, obecnie ciężko się z nich korzysta, a wcale nie są bardziej funkcjonalne.
  • #10 20947565
    sq3evp
    Poziom 36  
    phanick napisał:

    Na kilkuletniej przeglądarce kilka lat temu te strony działały bez problemu, obecnie ciężko się z nich korzysta, a wcale nie są bardziej funkcjonalne.


    Postęp wymaga ofiar - ktoś powiedział.

    JS wykonuje się w przegladarce, tylko pokaż mi dewelopera, ktory przetestuje w 100% swoje produkty.
    Nie jest to możliwe - kazdy ma inaczej zutylizowane zasobo w urzadzeniu (różna ilośc RAM, różny rodzaj pamięci, inne CPU, inne wersje OS, itp, itd).
  • #11 20947740
    Sam Sung
    Poziom 33  
    phanick napisał:
    Jestem temu przeciwny. Przez takiego typu zwyczaje i sztuczne "nadmuchiwanie" strony javascriptem, potem skrypty na stronie wykonują się wieki i wszystko zamula przeglądarkę aż do śmierci.
    To jest trochę inna sprawa. Darowanemu koniowi nie zagląda się w zęby. Na własnoręcznie zrobioną stronkę domowej kotłowni raczej nikt sobie nie wrzuci tony skryptów reklamowych, analitycznych i śledzących ;)
    Chciałbyś, żeby ktoś dostarczał prognozę pogody przeliczoną na swoim serwerze na statyczny obrazek? Proszę: https://m.meteo.pl/warszawa/60 :)
    phanick napisał:
    Od generowania wykresów powinien być serwer, który wygeneruje odpowiedni obrazek (np. w PHP) i go zwróci przeglądarce, jak za starych dobrych czasów.
    Da się zrobić stronę, która przy włączonym JavaScripcie będzie pobierała dane i renderowała ładny dynamiczny wektorowy wykres, a przy wyłączonym pobierze brzydki, statyczny PNG z serwera i jego pokaże.
    phanick napisał:
    Na kilkuletniej przeglądarce
    Co to znaczy? Nie aktualizujesz przeglądarki?
    phanick napisał:
    kilka lat temu te strony działały bez problemu, obecnie ciężko się z nich korzysta, a wcale nie są bardziej funkcjonalne.
    To prawda, ale zapewniam, że i dzisiaj da się skryptami rysować wykresy z kilkudziesięciu tysięcy punktów pomiarowych i może to trwać pojedynczne sekundy na najnowszej przeglądarce uruchomionej na 7-letnim smartfonie.
    A ile by trwało generowanie takiego PNG np. na Arduino?
    Trzeba rozsądnie gospodarować mocą obliczeniową wszystkich dostępnych elementów systemu.
REKLAMA