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



Teraz jest 28 mar 2024, o 21:18


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 9 ] 
Autor Wiadomość
PostNapisane: 21 cze 2018, o 08:15 
Offline
Nowy

Dołączył(a): 18 kwi 2018
Posty: 17
Pomógł: 0

Witam!

Zrobiłem sobie kontroler do silnika bezszczotkowego.

Projekt jest oparty na dwóch układach atmega 328P, spiętych ze sobą. Jeden zajmuje się wyłącznie komutacjami silnika, drugi natomiast obsługuje pomiary, zabezpieczenia, wyświetlacz, manetkę gazu.

Spięte są ze sobą 5 liniami, z czego 4 odpowiadają za przesyłanie sygnału o ustawionej mocy, natomiast 5 wysyła impulsy do przerwań prędkościomierza.

uC od komutacji generuje zmianę stanu pinu co każdy cykl obrotu. im koło kręci się szybciej, tym gęściej zmienia stan pinu. I tutaj błędu ani filozofii nie ma.

Problem jest natomiast z drugim uC, tym od wyświetlacza. Na nim są generowane przerwania zewnętrzne zliczające impulsy, oraz wewnętrzne, które te impulsy zerują i "przesyłają" dalej.

Problem jest taki, że po ruszeniu silnikiem zawsze pokazuje podobną wartość(ok40kmh), nawet jak silnik ledwo się rusza. Jak się zatrzyma, poprawnie pokazuje 0.

Gdzie jest błąd?

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.



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



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 21 cze 2018, o 18:40 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 04 paź 2013
Posty: 485
Lokalizacja: Siedlce
Pomógł: 9

w 10 linijce Dzielisz przez 5.2 ? wiesz o tym że tak naprawdę dzielisz tylko przez 5 ? i nie powinno to być w nawiasie ?

_________________
Ucz się ucz ,bo po to tutaj jesteś...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 21 cze 2018, o 20:35 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

RadekB86 napisał(a):
w 10 linijce Dzielisz przez 5.2 ? wiesz o tym że tak naprawdę dzielisz tylko przez 5 ?

Obawiam się, że nie masz racji. Obliczenia będą wykonane na liczbach typu float, a wynik zostanie dopiero zaokrąglony do liczby całkowitej.

Większym problemem może być czas potrzebny na takie obliczenia. Taka operacja może zająć kilkaset taktów zegara, co w procedurze obsługi przerwania może być niewskazane, bo np. w czasie obsługi przerwania od timera przerwania zewnętrzne są wyłączone, więc można zgubić impulsy (choć tu raczej wygląda, że jest ich za dużo). Wszystko tu zależy od tego, jaka jest maksymalna częstotliwość tych impulsów z silnika. Może to nie jest tutaj problemem, ale i tak dobrze byłoby skrócić czas obsługi przerwania np. tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

To powinno znacząco skrócić czas wykonania procedury obsługi przerwania (która zawsze powinna być jak najkrótsza), a wynik obliczeń będzie taki sam. W sumie nie bardzo widzę sensu stosowania dodatkowej zmiennej. Wystarczyłoby:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Generalnie w tym, co przedstawiłeś nie widzę raczej żadnego błędu, jeśli chodzi o logikę programu. Nie wiem, skąd wziąłeś tę wartość 5.2, ani jaki jest zakres obrotów silnika, więc nie wiem, czy obliczenia są prawidłowe. Na wszelki wypadek mógłbyś spróbować wyświetlić zamiast prędkości wartość zmiennej count i sprawdzić, czy zliczona ilość impulsów zgadza się z założeniami. Może masz problem sprzętowy np. jakieś zakłócenia od silnika powodują, że impulsów jest więcej niż oczekujesz? Jeśli masz możliwość, mógłbyś też sprawdzić te impulsy oscyloskopem.

Najlepiej byłoby wydzielić minimum kodu niezbędnego tylko do samego pomiaru prędkości usuwając wszystkie inne zadania programu i sprawdzić, czy to działa. Jeśli nie, łatwiej będzie znaleźć błąd. Jeśli będzie działać, to będzie oznaczało, że problem leży w innym fragmencie kodu.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 cze 2018, o 00:26 
Offline
Nowy

Dołączył(a): 18 kwi 2018
Posty: 17
Pomógł: 0

Wartość przez którą dzielę impulsy wynika z typu silnika. Ten ma chyba ze 24 zęby i takich pełnych cykli sześciu komutacji podczas jednego obrotu wykonuje kilka, czy kilkanaście. Silnik ma bardzo niskie obroty, gdyż siedzi w piaście koła od roweru. Przenosi moment bezpośrednio na obręcz, bez żadnej przekładni.

Przyjmijmy, że ta wartość dzielnika jest prawidłowa. Będę to jeszcze kalibrował z GPS, żeby pokazywało perfekt.
A póki co chcę osiągnąć chociaż jakąś zależność pomiędzy obrotami a wskazaniem :P

Impuls przerwania generuje uC odpowiedzialny za komutacje. Wszelkie zakłócenia są odfiltrowane, nie ma o tym mowy. Kilkadziesiąt kondensatorów(w tym nie jeden byk elektrolit), diod i transili dba o to, żeby komputerki były stabilne. W dodatku są zasilane z dwupoziomowego zasilacza liniowego.

Łapcie kawałek kodu z uC który robi silnik:

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


Jak widzicie warunek wysłania impulsu jest taki sam, jak warunek pierwszej komutacji. Nie wrzuciłem go tam, ponieważ komutacje wykonują się tylko gdy jest sygnał z kontrolera, że ma przyspieszyć. Jeżeli zakręcimy przepustnicę, PWM nie ustawia się na 0, tylko całkowicie wyłącza.

Aww. mówiąc prosto gdy impuls był w warunku komutacji, prędkościomierz działał tylko gdy był odkręcony gaz. W momencie zamknięcia przepusnicy pokazywał 0 mimo iż silnik się obracał.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 cze 2018, o 09:11 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

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


Rozumiem, że te 3 sensory dają 6 kombinacji na cykl. W związku z tym kombinacja 101 trwa przynajmniej 1/6 cyklu.
Ile razy pętla while zdąży zrobić obiegów, w czasie gdy powyższy warunek będzie spełniony?
Obawiam się, że impulsów będzie dużo więcej niż jeden na cykl, szczególnie przy niższych obrotach.

Może lepiej byłoby np. jakoś tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 cze 2018, o 22:43 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

witam,
widzę mała kolizję w kodzie, może ma wpływ na działanie programu.
Bart92 napisał(a):
                if ((sensor1 == 1) && (sensor2 == 0) && (sensor3 == 1)){
                        PORTB ^= (1<<PB6);///speedo pulse
                }
 
                if (enable == 1) {
                        if ((sensor1 == 1) && (sensor2 == 0) && (sensor3 == 1)) {
                                rotation(1);
                                phase = 1;
                        }

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

bo przy obecnym kodzie, czy enable jest 1 czy nie, to pierwszy if jest spełniony dla odpowiednio ustawionych sensorów.
?
pozdrawiam.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 cze 2018, o 00:38 
Offline
Nowy

Dołączył(a): 18 kwi 2018
Posty: 17
Pomógł: 0

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


Rozumiem, że te 3 sensory dają 6 kombinacji na cykl. W związku z tym kombinacja 101 trwa przynajmniej 1/6 cyklu.
Ile razy pętla while zdąży zrobić obiegów, w czasie gdy powyższy warunek będzie spełniony?
Obawiam się, że impulsów będzie dużo więcej niż jeden na cykl, szczególnie przy niższych obrotach.

Może lepiej byłoby np. jakoś tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Masz rację kolego. Polecę w tą stronę.

------------------------ [ Dodano po: 1 minucie ]

Daro69 napisał(a):
witam,
widzę mała kolizję w kodzie, może ma wpływ na działanie programu.
Bart92 napisał(a):
                if ((sensor1 == 1) && (sensor2 == 0) && (sensor3 == 1)){
                        PORTB ^= (1<<PB6);///speedo pulse
                }
 
                if (enable == 1) {
                        if ((sensor1 == 1) && (sensor2 == 0) && (sensor3 == 1)) {
                                rotation(1);
                                phase = 1;
                        }

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

bo przy obecnym kodzie, czy enable jest 1 czy nie, to pierwszy if jest spełniony dla odpowiednio ustawionych sensorów.
?
pozdrawiam.


Tak powinno być, gdyż impulsy powinny być zliczane gdy silnik jest wyłączony, ale również wtedy kiedy jest włączony. Powinny być niezależne od "enable" które odpala silnik.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 cze 2018, o 16:00 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

witam,

Bart92 napisał(a):
 
                if (enable == 1) {
                        if ((sensor1 == 1) && (sensor2 == 0) && (sensor3 == 1)) {
                                rotation(1);
                                phase = 1;
                        }
 
                        if ((sensor1 == 1) && (sensor2 == 0) && (sensor3 == 0)) {
                                rotation(2);
                                phase = 2;
                        }
 
                        if ((sensor1 == 1) && (sensor2 == 1) && (sensor3 == 0)) {
                                rotation(3);
                                phase = 3;
                        }
 
                        if ((sensor1 == 0) && (sensor2 == 1) && (sensor3 == 0)) {
                                rotation(4);
                                phase = 4;
                        }
 
                        if ((sensor1 == 0) && (sensor2 == 1) && (sensor3 == 1)) {
                                rotation(5);
                                phase = 5;
                        }
 
                        if ((sensor1 == 0) && (sensor2 == 0) && (sensor3 == 1)) {
                                rotation(0);
                                phase = 0;
                        }
                } else

tak sobie pomyślałem czy nie szybciej by się wykonało gdyby zastosować coś w tę stronę.

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



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 cze 2018, o 19:37 
Offline
Nowy

Dołączył(a): 18 kwi 2018
Posty: 17
Pomógł: 0

Szybkość nie ma tu znaczenia. Ale dziękuję za poprawkę :)

Problemem były trzaskające bez przerwy przerwania. Pomogła sugestia kolegi andrews. Temat do zamknięcia :)



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: 9 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 10 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