optymalizacja kodu - Wersja do druku +- Arduino Polska Forum (https://forum.arduinopolska.pl) +-- Dział: Korzystanie z Arduino (https://forum.arduinopolska.pl/dzial-korzystanie-z-arduino) +--- Dział: Programowanie w Arduino (https://forum.arduinopolska.pl/dzial-programowanie-w-arduino) +--- Wątek: optymalizacja kodu (/watek-optymalizacja-kodu) |
optymalizacja kodu - nebari - 12-03-2018 Witajcie Chciałbym prosić bardziej doświadczonych formumowiczów o pomoc w optymalizacji kodu. Jest to moja kolejna wersja/modernizacja sterownika akwarystycznego. Poprzednia bazowała na wyświetlaczu LCD 64x20 i generalnie było OK. Na chwilę obecną chciałem rozbudować ten sterownik o parę nowych opcji plus możliwość sterowania z pozycji klawiszy zamiast za każdym razem wgrywania kodu. Moje obecnie problemy to zbyt wolno działający kod co widać szczególnie w godzinach gdzie sekundy przeskakują co 7 sekund :-( . temperatury a raczej cyfry są zniekształcone (czasami). Całość jakoś działa ale moim celem jest dodanie do programu menu z pozycji którego mógłbym ustawiać: - bieżącą godzinę i datę (jak się rozkoduje zegar), - zmieniać godzinę/ minuty świtu oraz zmierzchu, - ustawiać temperaturę dla której miałby się włączać wentylator (plus histereza), - wprowadzać wartość KH wg. której będzie wyliczana zawartość Co2. Całość obsługiwana jest przez arduino nano (ze względu na rozmiar), wyświetlacz to graficzny LCD 128x64 ST7920, termometry dwa na jednym kablu w funkcji złodzieja (bez pełnego zasilania), obsługa dwóch styczników (na razie sterowany jest tylko jeden - drugi w zapasie), zegar RTC DS1307, Sonda pH, i do tego przetwornica step-down, klawisze na chwilę obecną podpięte do pinów 9,8,7,4. RE: optymalizacja kodu - kaczakat - 13-03-2018 Wróć do przykładu blinkWhithoutDelay i zerknij tutaj https://forum.arduinopolska.pl/watek-nak%C5%82adanie-si%C4%99-funkcji-komunikacja-przez-bt, zastanów się jak często musisz wykonywać poszczególne rzeczy i rozdziel między nie czas procesora. Np. mierzenie temperatury, można robić co 10s, odpowiednio robione zajmie 27 + 3ms, jak robisz to zgodnie z najprostszym przykładem i co 1s to zajmie 7,5s w każdych dziesięciu. Czasami mierzenie trzeba robić co 0,1s, ale wtedy przy ds trzeba zrezygnować z 12bitów. Do tego parę rzeczy robionych wg takiej fizolowi z delayami i czekasz 7s na zmianę wartości na ekranie. Właściwie OK masz napisaną funkcję drawPH(void). Powiel to na inne. A wywoływać poszczególne pomiary w 1, 2, 3 sekundzie, tak by w między czasie była moc obliczeniowa na inne rzeczy. Do ustawień potrzebne jest menu, temat rzeka. Trzeba też poznać dobrze biblioteki, np. domyślnie funkcja DS czeka na skończenie pomiaru i jej wywołanie trwa 750ms. Trzeba włączyć tryb asynchroniczny i samemu dbać o to kiedy pomiar zlecić, a kiedy odczytać. Całości nie przetestuję, nie mam tego sprzętu. RE: optymalizacja kodu - nebari - 13-03-2018 (13-03-2018, 04:37)kaczakat napisał(a): Wróć do przykładu blinkWhithoutDelay i zerknij tutaj https://forum.arduinopolska.pl/watek-nak%C5%82adanie-si%C4%99-funkcji-komunikacja-przez-bt, zastanów się jak często musisz wykonywać poszczególne rzeczy i rozdziel między nie czas procesora. Np. mierzenie temperatury, można robić co 10s, odpowiednio robione zajmie 27 + 3ms, jak robisz to zgodnie z najprostszym przykładem i co 1s to zajmie 7,5s w każdych dziesięciu. Czasami mierzenie trzeba robić co 0,1s, ale wtedy przy ds trzeba zrezygnować z 12bitów. Do tego parę rzeczy robionych wg takiej fizolowi z delayami i czekasz 7s na zmianę wartości na ekranie. Właściwie OK masz napisaną funkcję drawPH(void). Powiel to na inne. A wywoływać poszczególne pomiary w 1, 2, 3 sekundzie, tak by w między czasie była moc obliczeniowa na inne rzeczy. Do ustawień potrzebne jest menu, temat rzeka. Trzeba też poznać dobrze biblioteki, np. domyślnie funkcja DS czeka na skończenie pomiaru i jej wywołanie trwa 750ms. Trzeba włączyć tryb asynchroniczny i samemu dbać o to kiedy pomiar zlecić, a kiedy odczytać. Całości nie przetestuję, nie mam tego sprzętu.Dzięki za sugestię co i gdzie szukać - będę dzisiaj walczył z tematem. Z tego co rozumię to funkcja delay jest najgorszym rozwiązaniem i raczej starać się jej używać jak najmniej? Menu - i tu jest problem - bo niby jak zauważyłeś temat rzeka ale tak naprawdę nigdzie nie ma dostępnych różnych konstruktów na bazie których można by się oprzeć i coś zmajstrować (jakie komendy/funkcje, co za co odpowiada i kiedy użyć) - do tego dochodzi sterowanie takim wyświetlaczem jak ten 128x64 ST7920 i jak dla mnie problem gotowy :-). RE: optymalizacja kodu - kaczakat - 14-03-2018 Najprościej dane zaktualizować wysyłając je komendą przez UART. Podłączanie kablem nie jest koniczne, teraz w każdym domu jest laptop z BT, telefon z BT (a na androida mnóstwo terminali, nakładek Arduino które wyślą Ci całą komendę po wpisaniu danych w okienka) moduł HC-05 to koszt 20zł, 10zł z Chin. W bibliotece do zegarka by Eric Ayars jest przykład z ustawieniem czasu przez Uart, wystarczy go wysłać w formacie YYMMDDwHHMMSS. Ja to robię inaczej, przykład zabawy z silniczkiem krokowym: Kod: #include <AccelStepper.h> RE: optymalizacja kodu - nebari - 14-03-2018 teoretycznie wydaje się to proste i rozumiem o mechanizm działania ale ni czorta nie potrafię tego przełożyć na kod. Po kilku próbach nie uciekłem z interwału 7 sekund na zegarze i obawiam się, że zaśmieciłem sobie kod. Dzięki za wyjaśnienie. Mam jeszcze jedno pytanie odnośnie zegara. A mianowicie - obsługa LCD wymaga stosowania bloków void draw (void), void drawCzas(void) itd. Aby pomóc w obliczeniach rozbiłem główny blok z czasem na blok zegara void drawCzas(void) i blok sterowania PWM void drawPWM (void). W obu blokach muszę wywołać: < tmElements_t tm; > gdyż inaczej nie zadziała program w bloku. Czy jest inny sposób (deklaracji) na początku programu aby nie powtarzać tej czynności w każdym bloku tylko odwołanie samo zadziała? Odnoszę wrażenie, że przez to dublowanie sam zegar jest wyświetlany z tym opóźnieniem 7s. RE: optymalizacja kodu - Robson Kerman - 15-03-2018 Dla czego musisz wywoływać cośtam? Tworzysz sobie taki obiekt z obiektu, który dla niepoznaki nazywa się w języku noobów inicjalizacją. tmElements_t, jest już obiektem typu zdefiniowanego struktury anonimowej: typedef struct { uint8_t Second; uint8_t Minute; uint8_t Hour; uint8_t Wday; uint8_t Day; uint8_t Month; uint8_t Year; } tmElements_t, TimeElements, *tmElementsPtr_t; Struktury anonimowe, to taki wymysł GCC, który normalnie nie powinien istnieć, bo według mnie właśnie są z nim takie problemy, jak powyższy. Nie możesz zadeklarować obiektu tm poza funkcją go używającą. tm pobiera z zegara zmienną czasu i rozkłada ją na składowe, przypisując do zmiennych wewnątrz struktury, a potem sobie pobierasz tm.Minute, tm.Second Można oczywiście kombinować. Ja bym pogrzebał w pliku TimeLib.h i zrobił z tego normalną strukturę albo klasę. Wywołanie obiektu pobierało by aktualny czas, bo teraz linijka tmElements_t tm przypisuje czas do tm i czas się nie zmienia aż do następnej "inicjalizacji" zegara, czy tam obiektu go obsługującego. A co się tyczy kodu, to deklarujesz sobie znak stopni Celsiusza, a biblioteka U8Glib ma sporo znaków specjalnych. Więc zamiast tej bitmapy piszesz "\xb0". Na stronie https://github.com/olikraus/u8glib/wiki/fontgroupadobex11 masz tablice znaków. Jak byś miał problem z ich użyciem, to mogę wyjaśnić. RE: optymalizacja kodu - Robson Kerman - 15-03-2018 A cha, i jeszcze jedno. Nie powinno się odświeżać ekranu, jeśli to nie jest konieczne. Odświeżaj tylko elementy które zostały zmienione. Na przykład, w Twoim przypadku, powinieneś odświeżać tylko zegar. Nie musisz sprawdzać millis, bo mając RTC to było by dziwne, że nie korzystasz akurat z niego. Jak chcesz aby parametry odświeżały się co 10 sekund, to w funkcji wyświetlającej czas, sprawdzaj czy minęło 10 sekund i wywołuj funkcję sprawdzającą te parametry i je wyświetlającą. Dzięki temu nie musisz liczyć millis, tylko liczysz tiki z funkcji tm.Second. |