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



Teraz jest 30 mar 2026, o 22:37


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 
Autor Wiadomość
PostNapisane: 3 sty 2015, o 19:17 
Offline
Nowy

Dołączył(a): 14 wrz 2014
Posty: 18
Pomógł: 0

Witam

Przygotowuję dość prosty projekt zgodnie z opisem z tematu. Mam wentylator 12V, czujnik DS18B20. Wszystko jest podłączone i działa poprawnie (sprawdzałem oczywiście osobno na wszelakie sposoby). Czujnik temperatury obsługuję przez bibliotekę z Bluebooka, także nie będę podawał tutaj jej kodu. Dodam tylko, że temperatura odczytywana jest raz na 3 sekundy.

Problem, który mam, pojawia się przy próbie płynnego sterowania obrotami wentylatora. Realizuję ją oczywiście przez PWM.
Utworzyłem sobie pomocniczą zmienną:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Dla wyjaśnienia, zmienna cel to wartość całkowita temperatury, a zmienna cel_fract_bits to wartość dziesiętna temperatury.

Gdy temperaturę zmieniam skokowo za pomocą tego fragmentu kodu, to wszystko działa prawidłowo, co potwierdza zarówno fizyczne działanie wentylatora, jak i wyświetlacz:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Zaznaczam, że obroty rosną wraz ze wzrostem temperatury powyżej 20, 23 i 26 stopni C, i odpowiednio spadają.
Zmienna i jest typu uint16_t. Timer2 działa prawidłowo.

Jednak gdy próbuję regulować temperaturę stopniowo, aby szerokość impulsu rozkładała się pomiędzy 0, a 255 dla zakresu temperatur 20-40 C, to program nie działa już prawidłowo:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

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

powodujące nieprawidłowe przypisanie wartości do rejestru OCR2. Efekt jest taki, że OCR2 zawsze przyjmuje wartość 0 (widoczne na wyświetlaczu).

Rozwiązanie jest zapewne proste, ale nie mogę na nie wpaść, także bardzo proszę o pomoc.



Ostatnio edytowano 4 sty 2015, o 09:02 przez alkorinio, łącznie edytowano 2 razy

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2015, o 19:45 
Offline
Użytkownik

Dołączył(a): 22 lut 2014
Posty: 205
Lokalizacja: Poznań
Pomógł: 22

Tak jak się domyślasz winna jest ta linia:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


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

będzie liczba po przecinku. Która zostanie potraktowana jako 0. Wtedy:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

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

Aby część po przecinku nie została "utracona" musiałbyś wykonać jawne rzutowanie na typ float lub double. Ale gdzieś czytałem, że lepiej unikać tych typów.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2015, o 19:53 
Offline
Nowy

Dołączył(a): 14 wrz 2014
Posty: 18
Pomógł: 0

Tak też podejrzewałem. Ale jeśli wynikiem tego działania byłoby np. 25,81, to czy fakt, że zmienna jest typu uint16_t, nie powinien rzutować jej właśnie na typ uint16_t i pozostawić wartość 25?

Jeśli nie, to jak to ominąć?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2015, o 19:57 
Offline
Użytkownik

Dołączył(a): 22 lut 2014
Posty: 205
Lokalizacja: Poznań
Pomógł: 22

Ale nigdy z tego działania ((cel_d-200) / (400-200)) nie uzyskasz liczby większej od 1. cel_d jest pewnie typu uint8_t. Więc cel_d może być max 255. (255-200)/(400-200)=55/200<1.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2015, o 20:05 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 sty 2013
Posty: 1760
Pomógł: 196

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

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


Pozdr.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2015, o 20:21 
Offline
Nowy

Dołączył(a): 14 wrz 2014
Posty: 18
Pomógł: 0

Zmienna cel_d jest typu uint16_t (przepraszam, nie napisałem).

Ale rozumiem już, o co chodzi - MCU podczas żadnego działanie nie będzie widział liczby <1. Spróbuję to obejść.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 sty 2015, o 09:00 
Offline
Nowy

Dołączył(a): 14 wrz 2014
Posty: 18
Pomógł: 0

@kicajek
Ta część programu działa akurat dobrze (patrz pierwszy post), ale dzięki za pomysł.

Odnośnie płynnej regulacji rozwiązałem to tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Działa bez zarzutu.

Druga sprawa to taka, że większość wentylatorów (o ile nie wszystkie) ma taką przypadłość, że nie załącza się, gdy wypełnienie impulsu wynosi np. 1/255, ale gdy jest to dopiero 80/255. Wziąłem na to poprawkę pozostawiając nawet 100/255, także ostateczny kod wygląda tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Należy pamiętać, że dolna granica, przy której obroty mają się zwiększać, to 20C (stad liczba 200 w algorytmie), a górna 40C.

Temat zakończony, dzięki za pomoc! Gumeni dostaje plusa.



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 4 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