ATNEL tech-forum
https://forum.atnel.pl/

Błędnie działająca pętla for
https://forum.atnel.pl/topic22308.html
Strona 1 z 1

Autor:  r88 [ 4 cze 2019, o 13:08 ]
Tytuł:  Błędnie działająca pętla for

Witam
To mój pierwszy post i jeden z pierwszych programów napisanych w eclipse. Jest to program ,który ma dowolnie wybrany kolor RGB ściemniać a potem rozjaśniać i przechodzić do następnego koloru,jednak dla uproszczenia wkleje kod tylko dla jednego koloru.Zrealizowałem dwie pętle podobnie jak z przykładu bluebooka o sterowaniu pwm,z której to książki aktualnie się uczę.Od razu podkreślam,że korzystam z płytki atb rev 1.05 czyli produktu firmy Atnel,której to forum promuje ;)
Problem polega na tym,że obie te pętle chociaż jedna ma ściemniać a druga rozjaśniać obie ściemniają nieważne jak skonstruuje warunki pętli.
Jestem początkujący i może się to okazać banalnym błędem w kodzie,ale decyduje się tylko dlatego napisać ten post,że kod wydaje mi się jak najbardziej logicznym i takim,który powinien normalnie zadziałać.

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

Autor:  Tom92 [ 4 cze 2019, o 13:48 ]
Tytuł:  Re: Błędnie działająca pętla for

Przy starcie masz włączoną diodę RGB.

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


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


Kolejna rzecz to taka, że w pętli while ustawiasz kolor seledynowy i go ściemniasz, następnie znowu seledynowy i znowu ściemniasz itd. tak mi się wydaje, nie sprawdzałem kodu u siebie bo narazie nie mam jak. Wyrzuć z kodu #define F_CPU 8000000UL.

Autor:  r88 [ 4 cze 2019, o 14:24 ]
Tytuł:  Re: Błędnie działająca pętla for

Biorąc pod uwagę te dwie pętle następujące po sobie z pół sekundową przerwą, dziwne jest to,że jedna realizując dekrementację a druga inkrementację, dioda najpierw zpełnej jasności ściemnia się w pętli kolor_minus a potem od miejsca w którym się poprzednia skończyła ściemnia ponownie tamta wartość do zera w pętli kolor_plus.Nie jestem w stanie pojąć tego,bo chyba podstawiając "jasnosc" do wzorow rgb wartosći w drugiej pętli powinny wzrastać
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Autor:  Adam12 [ 4 cze 2019, o 15:53 ]
Tytuł:  Re: Błędnie działająca pętla for

Pętle jak to zwykle bywa w języku C, działają jak najbardziej poprawnie :) Błędnie podajesz wartości do tych pętli. Do funkcji rgb(...) wpisujesz wartości r,g,b które są następnie w każdym obiegu pętli zmniejszane przez pomnożenie przez jasność i znowu podstawiane czyli zmniejszają się w postępie geometrycznym. W pętli kolor_plus, wartości r,g,b są także z każdym obiegiem pętli zmniejszane przez kolejne podstawienia tylko wolniej.

Powinieneś sobie zapamiętywać początkowe wartości r,g,b przed wejściem do pętli i takie podstawiać do obliczania jasności. Poza tym przed wejściem w kolor_plus musisz podstawić wartości początkowe r,g,b. Inaczej po wejściu do pętli jasność najpierw zmniejsza się do 80% i dopiero od tej wartości rośnie w górę.

Autor:  r88 [ 4 cze 2019, o 16:51 ]
Tytuł:  Re: Błędnie działająca pętla for

Adam12 napisał(a):
Pętle jak to zwykle bywa w języku C, działają jak najbardziej poprawnie :) Błędnie podajesz wartości do tych pętli. Do funkcji rgb(...) wpisujesz wartości r,g,b które są następnie w każdym obiegu pętli zmniejszane przez pomnożenie przez jasność i znowu podstawiane czyli zmniejszają się w postępie geometrycznym. W pętli kolor_plus, wartości r,g,b są także z każdym obiegiem pętli zmniejszane przez kolejne podstawienia tylko wolniej.

Powinieneś sobie zapamiętywać początkowe wartości r,g,b przed wejściem do pętli i takie podstawiać do obliczania jasności. Poza tym przed wejściem w kolor_plus musisz podstawić wartości początkowe r,g,b. Inaczej po wejściu do pętli jasność najpierw zmniejsza się do 80% i dopiero od tej wartości rośnie w górę.



Czy mógłbym prosić z przykładem na moim kodzie? Rozumiem co trzeba zrobić,ale nie mam wyobraźni jak i po za tym wciąż nie rozumiem jak pętla kolor_plus wciąż zmniejsza wartości r,g,b.

Autor:  andrews [ 4 cze 2019, o 19:01 ]
Tytuł:  Re: Błędnie działająca pętla for

Ja bym zaczął od przeniesienia definicji funkcji rgb(), kolor_plus() i kolor_minus() poza funkcję main().
Wewnątrz funkcji main() powinny być tylko wywołania tych funkcji.

Autor:  Adam12 [ 4 cze 2019, o 20:18 ]
Tytuł:  Re: Błędnie działająca pętla for

Tak na szybko napisałem i działało:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Reszta kodu jak u Ciebie.

Co do zmniejszania wartości rgb w pętli kolor plus to możesz sobie rozpisać po kolei obiegi pętli:
1. jasnosc=80, r=172 -> r = r*jasnosc/100 = 172 * 80/100 = 137;
2. jasnosc=81, r=137 -> r = r*jasnosc/100 = 137 * 81/100 = 110;
3. jasnosc=82, r=110 -> r = r*jasnosc/100 = 110 * 82/100 = 90;
itd.

Jak widzisz mimo, że jasnosc wzrasta to r gwałtownie maleje bo cały czas jest podstawiana jej nowa mniejsza wartość.

andrews napisał(a):
Ja bym zaczął od przeniesienia definicji funkcji rgb(), kolor_plus() i kolor_minus() poza funkcję main().
Wewnątrz funkcji main() powinny być tylko wywołania tych funkcji.


Też bym od tego zaczął, chociaż o dziwo to działa. Ale umieszczanie funkcji w ciele innej funkcji nie jest chyba zgodne ze standardem C ?

Autor:  r88 [ 4 cze 2019, o 21:05 ]
Tytuł:  Re: Błędnie działająca pętla for

Dzięki Adam12,wyjaśniłeś mi przebieg pętli, jednak po wklejeniu twojego kodu teraz dioda świeci się jednostajnie z maksymalna jasnością i nic więcej.
Uwzględniłem wszystkie wasze uwagi i teraz mój kod w całości wygląda tak:(oczywiście 0 błędów i warningów)

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

Autor:  mirekk36 [ 4 cze 2019, o 21:18 ]
Tytuł:  Re: Błędnie działająca pętla for

r88 napisał(a):
jednak po wklejeniu twojego kodu teraz dioda świeci się jednostajnie z maksymalna jasnością i nic więcej.

Polecam ci próbę zrozumienia co oznacza termin "pisanie programów/funkcji NIEBLOKUJĄCYCH" ... bo teraz lecisz po równi pochyłej i z yymi delajami - szczególnie - nie znajdziesz rozwiązania.

Myślę że warto zacząć od Bluebooka: https://atnel.pl/mikrokontrolery-avr-jezyk-c.html

Autor:  Adam12 [ 4 cze 2019, o 23:09 ]
Tytuł:  Re: Błędnie działająca pętla for

r88 napisał(a):
teraz dioda świeci się jednostajnie z maksymalna jasnością i nic więcej.

Zmieniaj jasność w większym zakresie np. od 1 do 100 i zmniejsz wtedy czas na 7ms. Po prostu w takim zakresie jak na początku nie widać różnicy w jasności świecenia diody. Poczytaj sobie o korekcji gamma: http://mirekk36.blogspot.com/2013/09/gamma-correction-nowe-narzedzie-w.html
mirekk36 napisał(a):
Polecam ci próbę zrozumienia co oznacza termin "pisanie programów/funkcji NIEBLOKUJĄCYCH" ... bo teraz lecisz po równi pochyłej i z yymi delajami - szczególnie - nie znajdziesz rozwiązania.

Myślę że warto zacząć od Bluebooka: https://atnel.pl/mikrokontrolery-avr-jezyk-c.html

Mirek, ale w tym wypadku te delaye i tak nie mają znaczenia, nic nie blokują. PWM i tak działa w przerwaniu od licznika. A kolega uczy się właśnie z Bluebooka i na ATB. Pisał o tym w pierwszym poście. :)

Autor:  r88 [ 5 cze 2019, o 11:08 ]
Tytuł:  Re: Błędnie działająca pętla for

Cytuj:
Zmieniaj jasność w większym zakresie np. od 1 do 100 i zmniejsz wtedy czas na 7ms. Po prostu w takim zakresie jak na początku nie widać różnicy w jasności świecenia diody.


Masz racje teraz działa idealnie jak zwiększyłem przedział, wcześniej mogła być mała rozpiętość ,bo malało wykładniczo.Wielkie dzieki Adam12 i innym za rady. Problem rozwiązany :)

Autor:  andrews [ 5 cze 2019, o 17:40 ]
Tytuł:  Re: Błędnie działająca pętla for

Ostatnio nawał pracy, więc nie miałem czasu odpowiedzieć, ale chyba jeszcze coś bym musiał wyjaśnić, pomimo tego, że autor wątku już zastosował się do mojej porady.
Adam12 napisał(a):
andrews napisał(a):
Ja bym zaczął od przeniesienia definicji funkcji rgb(), kolor_plus() i kolor_minus() poza funkcję main().
Wewnątrz funkcji main() powinny być tylko wywołania tych funkcji.

Też bym od tego zaczął, chociaż o dziwo to działa. Ale umieszczanie funkcji w ciele innej funkcji nie jest chyba zgodne ze standardem C ?

Ja nie napisałem, że to nie będzie działać, ani że to jest przyczyna problemów. To, że działa, w sumie też wcale nie jest dziwne. GCC akurat udostępnia taką funkcjonalność (i może jeszcze inne kompilatory, ale raczej nie wszystkie), jednak jest to rozszerzenie, bo standard C nie dopuszcza takiej sytuacji.

Jeśli już zagnieżdżanie funkcji jest wspierane przez kompilator, funkcje zdefiniowane wewnątrz innej funkcji będą miały zasięg lokalny, czyli będą mogły być tylko wewnątrz tej funkcji wywołane. Gdyby została napisana dodatkowa funkcja, poza funkcją main(), która chciałaby z tych funkcji korzystać, to kompilacja zakończy się błędem undefined reference, nawet jeśli będzie wywołana z funkcji main().
Gdybyśmy przykładowo stworzyli poza funkcją main() taką funkcję
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

i próbowali ją wywołać z funkcji main(), to podczas kompilacji otrzymamy błąd undefined reference to rgb.

Stosowanie zagnieżdżania jest więc moim zdaniem uzasadnione tylko wtedy, kiedy chcemy "ukryć" jakąś funkcję i ograniczyć jej używanie tylko wewnątrz innej funkcji, ale taki sam efekt można uzyskać np. poprzez stosowanie budowy modułowej programu i definiowaniu funkcji jako static, co jest (IMHO) bardziej eleganckim rozwiązaniem i w dodatku zgodnym ze standardem.

W tym przypadku zagnieżdżanie jest moim zdaniem nieuzasadnione i nie przynosi żadnej korzyści, za to zmniejsza czytelność kodu oraz utrudnia analizę. Poza tym kompilator i tak najprawdopodobniej przekształci to na funkcje inline, czyli umieści kod tych funkcji w miejscu wywołania, więc równie dobrze możemy to zrobić sami. Dlatego zasygnalizowałem, że dobrze byłoby zdefiniować funkcje w standardowy sposób.

Ogólnie osobiście nie polecam takiego stylu pisania programu, nawet jeśli "o dziwo działa" ;), szczególnie, jeśli ktoś chce zająć się programowaniem bardziej "na poważnie".

Strona 1 z 1 Strefa czasowa: UTC + 1
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/