• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Dobre zasady programowania w Arduino...
#31
Ja pół dnia straciłem szukając powodu dlaczego PID mi wpada w dziwne stany.
Dopiero gdy nawstawiałem serial.printow ile sie da i sprawdzalem zmienne okazalo
sie, ze co kilka sekund pojawiaja sie nany i wszystko sie wali...

Na szczescie udalo mi sie to obejsc zmieniajac troche obliczenia, ale zebym
wiedzial dlaczego tak sie dzialo to co to to nie Wink

PWL
 
Odpowiedź
#32
(16-05-2019, 10:58)PierwszyWolnyLogin napisał(a): Podziel się tym algorytmem na intach jeśli możesz...
Jest mały problemik. Cały sterownik jest urządzeniem komercyjnym i raczej nie jestem w stanie udostępnić źródeł.

Ale mam taki pomysł. Pokaż swoją funkcję PID oraz sposób sterowania, a postaram się pomóc.
Drugi pomysł jest taki, że dziś napiszę do mojego zleceniodawcy, aby zapłacił resztę kasy za program i jak się nie odezwie, co ma w swoim zwyczaju, to udostępnię cały kod (lub jego większość). 

(16-05-2019, 14:02)PierwszyWolnyLogin napisał(a): co kilka sekund pojawiaja sie nany i wszystko sie wali...

Można sprawdzać co jest zwracane.
Jest taka funkcja isnan().
Jeśli chcesz sprawdzić czy zmienna jest liczbą, piszesz na przykład:

Kod:
if(!isnan(zmienna)) cośtamcośtam;
I wszystkie NAN'y będą ignorowanie.
W Arduino chyba trzeba dołączyć bibliotekę math.h, nie wiem , nie sprawdzałem.


(16-05-2019, 14:02)PierwszyWolnyLogin napisał(a): ale zebym
wiedzial dlaczego tak sie dzialo to co to to nie Wink
Pewnie pierwiastek z liczby ujemnej. No ale PID na pierwiastkach?
Zapodaj trochę kodu, chyba że Twój projekt też jest komercyjny.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#33
Zaraz tam komercyjny, żadne takie Smile

Przykład który wyłapałem to: 0.00x-40.81=nan Smile A powinno chyba zero Wink

Tak, isnan() jest, ale to leczenie wysypki pudrem Wink
Wykombinowałem, że jak trochę zmienię kolejność operacji (efekt ten sam) to nany
już się nie pojawiają... Narazie tyle wystarczy.

"Ale mam taki pomysł. Pokaż swoją funkcję PID oraz sposób sterowania, a postaram się pomóc.
Drugi pomysł jest taki, że dziś napiszę do mojego zleceniodawcy, aby zapłacił resztę kasy za program
i jak się nie odezwie, co ma w swoim zwyczaju, to udostępnię cały kod (lub jego większość). "

hehe

W niedzielę wydłubię PIDa i zamieszczę. Żadne cudo - kod który znalazłem w sieci.

Ps. Chętnie pogadam o wersji PIDa do stabilizacji temperatury w układach z TAKIM LAGIEM Smile
Typu ciężka grzałka i woda. Wyłączasz grzałkę, a temperatura rośnie jeszcze kilka minut Wink

PWL

PWL
 
Odpowiedź
#34
(16-05-2019, 19:57)PierwszyWolnyLogin napisał(a): Przykład który wyłapałem to: 0.00x-40.81=nan Smile A powinno chyba zero Wink

U mnie wychodzi 0.00 .

(16-05-2019, 19:57)PierwszyWolnyLogin napisał(a): Chętnie pogadam o wersji PIDa do stabilizacji temperatury w układach z TAKIM LAGIEM Smile
Typu ciężka grzałka i woda. Wyłączasz grzałkę, a temperatura rośnie jeszcze kilka minut Wink

No regulatory PID właśnie po to stworzono.
Człon różniczkujący przewiduje przyszłą wartość i wpływa na człon proporcjonalny w taki sposób, aby nie przeskoczyć zadanej wartości.

Niedobrane parametry mogą dać nam coś takiego:

[Obrazek: 9nZE7hn.png]


Przy odpowiednio dobranych parametrach będzie tak:

[Obrazek: Xbii7v8.png]
Pierwszy wykres jest dla regulacji PI (wyłączone D), drugi dla PID.
To są rzeczywiste wyniki pomiarów z mojego sterownika. Ta czerwona linia, to sygnał sterujący zwracany z funkcji PID, niebieska to zmierzona wartość (sterowana).
Regulator PID jest idealny do sterowania temperaturą cieczy, ponieważ likwiduje oscylacje i nie pozwala przekroczyć zadanej temperatury, czyli nie zagotuje oraz nie zamrozi obwodu.
Wszystko zależy od doboru nastaw. Przy idealnie dobranym członie różniczkującym, możesz się naprawdę zdziwić, że to tak pięknie pracuje. Jest kilka metod strojenia regulatorów PID. Proponuję poczytać o eksperymencie Zieglera-Nicholsa oraz o implementacji programowej. Tak, są programy do dobierania parametrów PID.
Można też zaimplementować algorytm autotuningu, ale to już na dłuższą pogadankę przy piwku w weekend, bo jest sporo teorii do opanowania.
Z chęcią pogadam, bo jest to temat iście fascynujący.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#35
Tak, podobne wykresy mam u siebie. Problem z ustawieniem poprawnych PIDow jest taki, ze przy sporym
zbiorniku wody pierwsze zagrzanie do okolic temp. docelowej trwa dluuuugo. Mozna sie zniecierpliwic Wink

Autotuningu próbowałem - znalazłem jakieś biblioteki w sieci. Nawet działały.

Masz przemyślenia co do algorytmu autotuningu?

Na moje oko wstępnie mogłoby to tak wyglądać:

P=I=D=0
- Zwiększam powoli P obserwując temperaturę, aż do momentu gdy temp dochodzi ciut poniżej
temp. docelowej.
- Teraz ten sam manewr z I - zwiększam powoli, aż temperatura dojdzie do docelowej,
- Parametr D zwiekszamy aż znikną oscylacje. Z tym, że tu trzebaby grzać od niższej temperatury,
żeby układ mógł się rozpędzić.

PWL
 
Odpowiedź
#36
Wracając do wątku...

Mam temat do którego nie bardzo wiem jak się zabrać.
Robię sobie sterownik procesu technologicznego, powiedzmy dla uproszczenia sterownik
zarządzający pieczeniem chleba w piekarniku. To tylko przykład dla zobrazowania.

Problem w każdym razie jest taki, ze proces nie biega w koło jak pętla loop()
tylko są to kroki jeden po drugi, aż do zakończenia i wtedy stop.

Normalnie pisząc cokolwiek na Arduino dla każdego "zjawiska" jak obsługa PID, miganie LEDami,
aktualizacja LCD, zapis na SD etc piszę funkcję do której wpadam co jakiś czas (regulowany
millisami()), robie swoje i wypadam.

Nie bardzo mam pomysł jak biegając w pętli mógłbym zrobić np. taki proces:

- sprawdź czy do piekarnika coś włożono ważąc zawartość,
- jeśli wsad zgadza się z oczekiwanym grzejemy piekarnik (PID),
- po osiągnięciu określonej temp. puszczamy parę wodną żeby chleb nie wysechł,
- mierzymy jak chleb rośnie sprawdzając jego ...wysokość Wink,
- po założonym czasie i gdy chleb jest odpowiednio wysoki wyłączamy grzanie,
- gdy piec ostygnia wzywamy obsługę. koniec.

Przykład od czapy, ale obrazuje problem. Do obsłużenia jest lista zadań następujących
po sobie, nie jednoczesnych, do kolejnego przechodzimy gdy poprzednie jest zakończone.

Oczywiście mogę napisać funkcję robiącą to wszystko po kolei, ale to zablokuje mi
inne funkcje jak przykładowe miganie LEDami Wink Dopóki nie opuszczę funkcji głównej
procesor nie uruchomi kolejnych w pętli.

Pewnie mógłbym zapisywać stan głównej funkcji - gdzie jest i co robi, wyskakiwać z niej
po paru millisach() a następnie wywoływać ją z parametrami opisującymi ostatnie miejsce
procesu... Mam nadzieję, że istnieje lepszy pomysł Wink
Dość łatwo byłoby podzielić proces na minimalne możliwe etapy, ale niewiele to nie da -
etap, żeby był wykonany może trwać np. kilka sekund, jeśli zostanie przerwany musi być
rozpoczęty od początku. Nie mogę zablokować loop() na ten czas...

Liczyłem trochę na RTOS ale coś mi się wydaje, że nie załatwi sprawy za mnie, 
a poza tym pewnie natknę się na wiele problemów których teraz nie znam Wink

Będę wdzięczny za jakiś pomysł jak zabrać się do jeża Smile

PWL
 
Odpowiedź
#37
(03-07-2019, 19:27)PierwszyWolnyLogin napisał(a): Nie bardzo mam pomysł jak biegając w pętli mógłbym zrobić np. taki proces:
- sprawdź czy do piekarnika coś włożono ważąc zawartość,
- jeśli wsad zgadza się z oczekiwanym grzejemy piekarnik (PID),
- po osiągnięciu określonej temp. puszczamy parę wodną żeby chleb nie wysechł,
- mierzymy jak chleb rośnie sprawdzając jego ...wysokość Wink,
- po założonym czasie i gdy chleb jest odpowiednio wysoki wyłączamy grzanie,
- gdy piec ostygnia wzywamy obsługę. koniec.
Proste, wręcz banalne dla takiego fachowca jak Ty. Aż dziwię się, ze pytasz, czyżby prowokacja?
Zmiany stanów procesów nie trwają długo, można użyć banalnych millis i synchronizacji zadań. Jak nie chcesz "walczyć" z millis, to użyj RTOS, ale spodziewaj się problemów większych niż w wielowątkowości.
Sens RTOS dla Arduino może i jakiś jest, przykładowo wysyłanie danych do serwera z użyciem TCP może trwać 5 a nawet 30 sekund. Wtedy RTOS umożliwi działanie innych wątków ale nie oszukujmy się, biblioteki arduino sa skopane i "blokują" CPU. Dobrze napisane nie robiły by tego i RTOS nie byłby potrzebny. Ponadto RTOS lubi RAM, jak nie masz z 20 k to raczej RTOS nie ma sensu. Ponadto to będzie jak pudrowanie trupa, źle napisanych bibliotek Arduino, RTOS cudownie nie naprawi!
 
Odpowiedź
#38
Jak masz do 255 etapów jakiegoś procesu to bierzesz zmienną bajt, potem te swoje 255 funkcji obsługujących układasz jedną po drugiej i w loop:
{
obsługaCzasuZMillis();
obsługaPrzycisków();//co np.10ms
obsługaEkranów(); //co np.100ms
obsługaCzujników(); //co np.500ms
ICoTamJeszczePotrzebne();//z sensownym interwałem czasowym
if (etap ==0) obslugaEtapu0();
if (etap==1) obsługaEtapu1();
...
if (etap==255) obsługaEtapu255();
}
Lub oczywiście w układzie switch case.
No i pamiętaj, by chleba używać z głową i umiarem Big Grin.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#39
Umiar to podstawa we wszystkim Smile

Muszę sobie narysować na papierze graf dzieląc proces na kawałeczki, może mi się
rozjaśni Wink Na razie sceptycznie o tym myśle Wink


W desperacji zacząłem myśleć o drugim procesorze Smile Zepchnąć na niego obsługę
wszystkiego co lata w pętli - LEDY, termometry, piszczek, zawory etc niech to mieli
i wysyła przez RS statusy, odbierając polecenia.
A główny procesor spokojnie krok po kroku realizuje swoje... hmm

PWL
 
Odpowiedź
#40
Big Grin 
(04-07-2019, 05:47)PierwszyWolnyLogin napisał(a): Muszę sobie narysować na papierze graf dzieląc proces na kawałeczki, może mi się
rozjaśni Wink Na razie sceptycznie o tym myśle Wink
Jak się czegoś nie rozumie to się o tym sceptycznie myśli.

(04-07-2019, 05:47)PierwszyWolnyLogin napisał(a): W desperacji zacząłem myśleć o drugim procesorze Smile 
To jest dopiero amatorszczyzna! To co można zrobić na jednym uC a i tak będzie się on "nudził" realizować na kilku uC. Kolejna rzecz, której do CV nie należy wpisywać. Bez problemu "LEDY, termometry, piszczek, zawory " można obsłużyć w przerwaniach nawet na 8051 czy , Z-80, Z-8 i innych archaicznych uC/CPU. Pętla główna może wyglądać tak:
Kod:
while( true ) ;
no ale do tego, trzeba umieć programować a nie tylko pisać, że inni nie potrafią, nie znają się i dają złe rady. Namiastką dobrego programowania w tym przypadku będzie słynne millis i wielowątkowość, z którą można zapoznać się np tu https://forbot.pl/blog/kurs-arduino-ii-w...is-id18418
Nie jest to panaceum na wszystko ale w większości wypadków amatorskich konstrukcji wystarcza.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości