Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 20 kwi 2024, o 04:49


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 
Autor Wiadomość
PostNapisane: 30 maja 2017, o 15:35 
Offline
Nowy

Dołączył(a): 28 mar 2017
Posty: 7
Pomógł: 0

Witam, chciałem zaimplementować do mojego układu regulator PID zgodnie z dokumentacją atmela
http://www.atmel.com/Images/Atmel-2558-Discrete-PID-Controller-on-tinyAVR-and-megaAVR_ApplicationNote_AVR221.pdf
Nie wiem czemu ale w nieskończonej pętli program wchodzi do ifa za każdym razem, a powinien zgodnie z czasem próbkowania. Próbkowanie powinno odbywać się z co 50ms, Time_interver został wyliczony zgodnie ze wzorem którym był w przykładowym pliku źródłowym main.c.
Cytuj:
* Specify the desired PID sample time interval
* With a 8-bit counter (255 cylces to overflow), the time interval value is calculated as follows:
* TIME_INTERVAL = ( desired interval [sec] ) * ( frequency [Hz] ) / 255


Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Obrazek


W listingu zostawiłem tylko znaczącą część. Czy ktoś potrafi mi wyjaśnić w czym tkwi problem?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2017, o 17:53 
Offline
Użytkownik

Dołączył(a): 06 maja 2014
Posty: 415
Lokalizacja: Kraków
Pomógł: 26

Po wykonaniu warunku musisz wyzerować flagę gFlags.pidTimer - inaczej cały czas będzie jedynką, więc cały czas się będzie wykonywać.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2017, o 18:28 
Offline
Nowy

Dołączył(a): 28 mar 2017
Posty: 7
Pomógł: 0

Faktycznie zapomniałem wyzerować flagi, jednak nawet po wyzerowaniu program w każdej iteracji wchodzi do ifa.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2017, o 14:10 
Offline
Nowy

Dołączył(a): 28 mar 2017
Posty: 7
Pomógł: 0

Obrazek

'A' jest wyświetlane poza ifem, jedynka gdy program znajduje się w ifie. Nie wiem jak to zinterpretować ale wydaje mi się, że program nie powinien tak często wchodzić w tego ifa. Układ taktowany jest kwarcem 16MHz czyli cykl zegarowy trwa mniej niż 1/10 us.
No chyba, że problem jest w ustawianiu flagi i nie ustawiłem jej jak założyłem na 50ms.
Ustawienia timera:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

F_CPU = 16Mhz, preskaler = 32, czyli zliczamy impulsy co 2us. Jest to licznik 8bit czyli przerwanie nastąpi co 510us.

Natomiast w przerwaniu mamy:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Każde przerwanie inkrementuje licznik, po 98 przerwaniach (0,51ms*98 w przybliżeniu daje 50ms) ustawiamy flagę.

Dokonałem paru zmian w tym co zaproponował atmel (ze względu na kompatybilność z kompilatorem)
w oryginaly jest:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

U mnie:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


oraz
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

zamnienilem na
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Czy ktoś może wyjaśnić mi dlaczego program ustawia mi wartość flagi na TRUE tak często?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2017, o 14:23 
Offline
Użytkownik

Dołączył(a): 06 maja 2014
Posty: 415
Lokalizacja: Kraków
Pomógł: 26

Cytuj:
No chyba, że problem jest w ustawianiu flagi i nie ustawiłem jej jak założyłem na 50ms.

Podepnij sobie jakiegoś leda i zmieniaj jego stan co te 50ms. Gołym okiem ocenisz, czy częstotliwość mniej więcej się zgadza.

Kolejna możliwość: zmienne z których korzystasz w programie głównym oraz przerwaniu (czyli tutaj flaga) spróbuj zadeklarować jako "volatile".



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2019, o 21:42 
Offline
Nowy

Dołączył(a): 28 wrz 2014
Posty: 1
Pomógł: 0

struct GLOBAL_FLAGS {
//! True when PID control loop should run one time
uint8_t pidTimer:1;
uint8_t dummy:7;
} volatile gFlags = {0, 0};



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2019, o 18:45 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 cze 2013
Posty: 988
Lokalizacja: Byram, MS 39272
Pomógł: 55

krzysssztof napisał(a):
Podepnij sobie jakiegoś leda i zmieniaj jego stan co te 50ms. Gołym okiem ocenisz, czy częstotliwość mniej więcej się zgadza.

Serio? Człowiek widzi z częstotliwością 25Hz co daje klatkę czasową o długości 0.04 sekundy czyli jakieś 40 ms. 50 ms jest tylko niewiele więcej. Naprawdę wierzysz, że zauważy?

_________________
Pomysły na podpis - wyślij SMSa +1 769 243 0011



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 5 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO