Skocz do zawartości

[Kurs] Turbinki - napędy tunelowe w robotyce. Część 2 - uruchomienie napędu


Treker

Pomocna odpowiedź

Jest to druga część artykułu dotyczącego zastosowania turbinek bezszczotkowych w robotyce. Dla przypomnienia, chodzi o modelarskie napędy tunelowe (EDF), które swoje zastosowanie znalazły w linefollowerach jako wydaje "pompy" powietrza tworzące podciśnienie między robotem, a trasą. Tydzień temu omówiłem budowę turbinki oraz zasadę sterowania takim napędem. Jeśli ktoś nie czytał pierwszej części to powinien od niej zacząć.

Tym razem zajmiemy się uruchomieniem napędu na dwóch mikroprocesorach o różnych architekturach. Przykłady zostały przygotowane dla AVR oraz STM32 W obu przypadkach wykorzystamy timery do generowania odpowiedniego przebiegu.

5. Programowanie

Nadszedł czas na przełożenie algorytmu w praktykę. Przedstawię dwa programy, oba w C – jeden dla ATmegi128 oraz drugi dla STM32103RB. Zakładam, że osoba zajmująca się zagadnieniem EDF'ów ma już podstawowe umiejętności programistyczne. Dlatego nie będę się rozwodził zbyt długo nad opisem kodu. Do uruchomienia turbinek trzeba wykorzystać timer oraz PWM. Należy zapomnieć o metodach z pętlami for i sztucznymi opóźnieniami. Może to zniszczyć turbinkę lub w najlepszym wypadku, będzie strasznie niewygodne w implementacji przy rozbudowanym programie.

5.1. Programowanie - Atmega128

Po pierwsze, musimy wygenerować sygnał 50Hz – i tutaj uwaga przy projektowaniu, trzeba pamiętać, aby wybrać Timer16 bitowy, na 8 bitach będzie bardzo ciężko uzyskać potrzebną częstotliwość. Do wyjścia generującego PWM podpinamy biały przewód z regulatora. W moim przypadku używając mikroprocesor ATmega128 jest to PORTE.3. Poniższy program działa poprawnie dla zegara ustawionego na 8Mhz:

DDRE |= (1<<PE3);//Turbina jako wyjście
TCCR3B |= (1 << CS31);//Preskaler
TCCR3A |= (1 << COM3A1) | (1 << COM3B1); //Fast PWM
TCCR3A |= (1 << WGM31);
TCCR3B |= (1 << WGM33) | (1 << WGM32);
ICR3 = 20500; //50Hz

Są to standardowe ustawienia Timera dla PWM. Wyjaśnienia wymaga ostatnia linijka, czyli wpisanie wartości 20 500. Powinno tutaj być 20 000, jednak albo mój oscyloskop fałszuje odczyt, albo co bardziej prawdopodobne - stosując wewnętrzny rezonator kwarcowy, który może mieć spore odchyły, ten konkretny egzemplarz uC generuje idealne 50Hz przy wartości 20 500. To najlepiej sprawdzić samemu.

Następnie tworzymy funkcję do obsługi turbiny, która zajmuje się również zabezpieczeniem regulatora przed podaniem wartości ze złego zakresu:

void turbina(int speed) {
       speed = (speed >2000 ) ? speed  : 2000;
       speed = (speed <1000 ) ? speed  : 1000;	

       OCR3A = speed;
}

Zgodnie z procedurą startową opisaną w poprzedniej części, aby silnik zaczął poprawnie pracować funkcję należy wywołać przykładowo tak:

turbina(1000);
_delay_ms(4000);
turbina(1300);

Późniejsza zmiana prędkość turbiny nie wymaga już odczekiwania czasu potrzebnego do inicjalizacji.

5.2. Programowanie - STM32103RB

Przykład dla STM32103RB, ustawionego do pracy na 72Mhz. Wybieramy Timer2 oraz jego kanał numer 1, którego wyjście znajduje się na pinie A0. ładujemy odpowiednie ustawienia do rejestrów timera:

void TIMER_config(void)
{
   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
   TIM_OCInitTypeDef TIM_OCInitStructure;

   //Konfiguracja Timera
   TIM_TimeBaseStructure.TIM_Prescaler = 3550;
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
   TIM_TimeBaseStructure.TIM_Period = 200;
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

   //Drugi kanał timera jako wyjscie PWM
   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
   TIM_OCInitStructure.TIM_Pulse = 0;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

   TIM_OC1Init(TIM2, &TIM_OCInitStructure);

   //Włączenie Timera2
   TIM_Cmd(TIM2, ENABLE);
   //Włączenie wyjć Timera2
   TIM_CtrlPWMOutputs(TIM2, ENABLE);
}

Oraz tworzymy funkcję, która pozwala na regulację prędkości turbiny w przykładzie jak poprzednio.

//Sterowanie turbiną
void Set_PWM_EDF(uint16_t pwm)
{
pwm = (pwm < 1000) ? 1000 : pwm;
pwm = (pwm > 2000) ? 2000 : pwm;

PWM_EDF=(int)pwm/100;
}

Filmik zamieszony poniżej prezentuje uruchomienie turbiny z użyciem płytki ZL31ARM.

Cały program dla STM-a wraz ze wszystkimi konfiguracjami znajduje się poniżej:

#include "stm32f10x.h"
#define PWM_EDF TIM2->CCR1

void RCC_Conf(void);
void GPIO_Conf(void);
void Set_PWM_EDF(uint16_t pwm);
void TIMER_config(void);

volatile int sys_tick = 0;

int main(void)
{

   RCC_Conf();
   GPIO_Conf();
   TIMER_config();
   SysTick_Config(72000); //Przerwanie co 1ms

   Set_PWM_EDF(1000); //Wypełnienie 1ms

   do {} while (sys_tick < 4000); //Czekamy 4s
   sys_tick = 0;
   Set_PWM_EDF(1500); //Wypełnienie 1,5ms

   while (1);

}

//Sterowanie turbiną
void Set_PWM_EDF(uint16_t pwm)
{
pwm = (pwm < 1000) ? 1000 : pwm;
pwm = (pwm > 2000) ? 2000 : pwm;

PWM_EDF=(int)pwm/100;
}

//Konfigruacja zegarów
void RCC_Conf(void)
{
 	ErrorStatus HSEStartUpStatus;

 	// Reset ustawien RCC
 	RCC_DeInit();
 	// Wlacz HSE
 	RCC_HSEConfig(RCC_HSE_ON);
 	// Czekaj za HSE bedzie gotowy
 	HSEStartUpStatus = RCC_WaitForHSEStartUp();

 	if(HSEStartUpStatus == SUCCESS)
 	{
   	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

   	// zwloka dla pamieci Flash
   	FLASH_SetLatency(FLASH_Latency_2);

   	// HCLK = SYSCLK
   	RCC_HCLKConfig(RCC_SYSCLK_Div1);

   	// PCLK2 = HCLK
   	RCC_PCLK2Config(RCC_HCLK_Div1);

   	// PCLK1 = HCLK/4
   	RCC_PCLK1Config(RCC_HCLK_Div4);

   	// PLLCLK = 8MHz * 9 = 72 MHz
   	RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

   	// Wlacz PLL
   	RCC_PLLCmd(ENABLE);

   	// Czekaj az PLL poprawnie sie uruchomi
   	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

   	// PLL bedzie zrodlem sygnalu zegarowego
   	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

   	// Czekaj az PLL bedzie sygnalem zegarowym systemu
   	while(RCC_GetSYSCLKSource() != 0x08);
 	}

 	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
}

//Konfiguracja wyjcia
void GPIO_Conf(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//Przerwanie czasu co 1ms
void SysTick_Handler(void) {
sys_tick++;

return;
}

void TIMER_config(void)
{
   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
   TIM_OCInitTypeDef TIM_OCInitStructure;

   //Konfiguracja Timera
   TIM_TimeBaseStructure.TIM_Prescaler = 3550;
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
   TIM_TimeBaseStructure.TIM_Period = 200;
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

   //Drugi kanał timera jako wyjscie PWM
   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
   TIM_OCInitStructure.TIM_Pulse = 0;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

   TIM_OC1Init(TIM2, &TIM_OCInitStructure);

   //Włączenie Timera2
   TIM_Cmd(TIM2, ENABLE);
   //Włączenie wyjć Timera2
   TIM_CtrlPWMOutputs(TIM2, ENABLE);
}

Dla formalności dodam tylko, że oba przykłady na pewno działają. Nie skupiałem się na zbytniej optymalizacji kodu (szczególnie w drugim przypadku), ponieważ sam dopiero poznaje STM-y. Jeśli komuś się to nie podoba, to na pewno będzie wstanie stworzyć własny kod. Moje kody można używać jako tester połączenia całego układu - jeśli wszystko jest ok, to turbina się na pewno uruchomi.

6. Uwagi

Tak naprawdę regulator reaguje do trochę większych wartości wypełnienia. Moje egzemplarze pracują do 2,5ms, jednak jest to niezgodne ze standardami aparatur RC, a przecież dla nich przygotowano te sterowniki. Dla bezpieczeństwa jako maksymalną wartość warto przyjąć jednak 2ms. Podając wartości większe od 2ms prędkość obrotów (oceniania na podstawie poboru prądu) zmienia się już nieznacznie.

Często pojawiający się problem, który może wywołać spore zamieszanie: turbina kręci się w złą stronę! I co teraz? Regulatory nie są przystosowane do zmiany kierunku obrotu silnika, aby tego dokonać należy zamienić miejscami dowolne dwa przewody łączące silnik z regulatorem. To odwróci obroty.

Turbinki pobierają stosunkowo spory prąd, dlatego pamiętajcie o odpowiedni grubych ścieżkach i wydajnych źródłach zasilania.

Elementy w napędzie wirują bardzo szybko dlatego nie próbujcie ich dotykać, przyglądać się im z bliska. Może to się dla Was źle skończyć.

Napędy EDF nie są bardzo awaryjne, jednak usterki się zdarzają. Przy odpowiednim ich traktowaniu oraz regularnej kontroli całości, napęd może służyć nam bardzo długo. Najłatwiej uszkodzić EDF-a, gdy robot najedzie na brudną powierzchnię, a turbinka wciągnie jakiś kamyczek, kawałek plastiku/plexi – urwanie łopat gwarantowane. Miałem taki przypadek w Wiedniu.

Nowa turbina wraz z wirnikiem wygląda przeważnie na dobrze dopasowaną. Jednak po pewnym czasie, gdy turbina pracuje okazuje się, że wirnik zahacza i od tarcia topi się na ściankach. Jest to rzecz całkiem normalna i nie ma co się przejmować. Siła odśrodkowa jest tak duża, że nie można tego uniknąć. Po dłuższej chwili łopaty wirnika skrócą się na tyle, że nie będą już dalej zahaczać o tunel. Efekt takiego stapiania łopat widoczny jest poniżej. Turbinka może trochę hałasować - to też normalne. Moja na filmiku zamieszczonym powyżej pracuje cichutko bo jest nowa, wyjęta prosto z pudełka i zasilana tylko z 6V.

Łopaty stopione o tunel

7. Częste usterki

Nie ma co ukrywać, że tanie turbinki są wykonane po prostu „tanio”. Zdarzają się wadliwe egzemplarze lub mogą się uszkodzić podczas używania. Jak zaradzić prostym usterkom:

7.1. Uszkodzenie wirnika. Delikatnie staramy się usunąć wirnik z napędu, tak aby nie wykrzywić ośki. Skro wirnik jest już uszkodzony to najlepiej wziął jakieś precyzyjne narzędzie i połamać/pociąć go tak aby odszedł w kawałkach. Na tak oczyszczony wał możemy nasunąć nowy wirnik. Wchodzi ciasno, jednak warto użyć odrobiny kleju.

Nowy wirnik

7.2. Silnik lata w mocowaniu. Tutaj jest gorsza sytuacja. Nie da się zdemontować silnika z założonym wirnikiem. Dlatego musimy go usunąć. Jeśli nie mamy czasu lub nie chce się nam bawić w delikatne zdejmowanie, to można go również po prostu złamać. Jeśli jednak chcemy wydobyć go w całości to musimy działać delikatnie. Ja robię to zakrzywioną pincetą. Wsuwam ją od góry lub od dołu. Tak aby zakrzywienie weszło miedzy silnik, a wirnik. Następnie staram się siłą ściągnąć wirnik. Uwaga, łatwo uszkodzić wirnik lub ośkę silnika. Taka sztuczka udała mi się w około 1/3 przypadków.

Po zdjęciu wirnika znajdziemy 3 śrubki, które należy dokręcić, aby silnik mocniej się trzymał. Jeśli raz już się nam poluzowały to pewnie będą robiły to również później. Po przykręceniu śrubek warto zalać je delikatnie klejem cyjanoakrylowym.

7.3. Pęknięcie mocowania silnika widocznego od góry. Zaznaczone na zdjęciu poniżej. Tutaj pozostaje nam jedynie delikatne przyklejenie go do tunelu klejem cyjanoakrylowym. Trzeba uważać tylko, aby nie przykleić elementów ruchomych do tunelu. Należy się również w tym momencie zacząć rozglądać za nową turbinką na wymianę, ponieważ aktualna długo nie podziała.

Mocowanie silnika do tunelu

8. Podsumowanie

Podzieliłem się z Wami moim doświadczeniem zdobytym w praktyce. Mam nadzieję, że komuś się ono przyda. Pozostaje jeszcze kwestia, gdzie nabyć taka turbinkę. Najprościej zakupić ją w HobbyKingu - duży sklep modelarski, sprawdzony przez wielu. Nie ma co obawiać się wysyłki z innego kraju. W sklepie tym można znaleźć turbinkę oraz regulator. Regulatory dostępne są również w polskich sklepach np.: w Botlandzie. Jeśli macie pytanie to pytajcie, jeśli znajdziecie błędy to zgłaszajcie. Zachęcam też do dyskusji na temat EDF’ów. Używacie, będziecie używać? Gotowe rozwiązania czy własne?

Untitled-52.jpg

Link do komentarza
Share on other sites

turbinka wciągnie jakiś kamyczek, kawałek plastiku/plexi – urwanie łopat gwarantowane. Miałem taki przypadek w Wiedniu.
Może warto pomyśleć nad jakąs siatką na wlocie turbiny. Niezbyt gęsta nie powinna jakoś dramatycznie zmniejszyć ciągu, a pozwoli uniknąć takich sytuacji.
Link do komentarza
Share on other sites

void turbina(int speed) {
       speed = (speed >2000 ) speed  : 2000;
       speed = (speed <1000 ) speed  : 1000;	

       OCR3A = speed;
}
void turbina(int speed) {
       speed = speed > 2000 ? speed  : 2000;
       speed = speed < 1000 ? speed  : 1000;	

       OCR3A = speed;
}
Często pojawiający się problem, który może wywołać spore zamieszanie: turbina kręci się w złą stronę! I co teraz? Regulatory nie są przystosowane do zmiany kierunku obrotu silnika, aby tego dokonać należy zamienić miejscami dowolne dwa przewody łączące silnik z regulatorem. To odwróci obroty.
"Lotnicze" nie, ale "samochodowe" i "wodne" są 🙂 Ale jasne, że takie są tańsze i najczęściej kupowane.
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Nowa turbina wraz z wirnikiem wygląda przeważnie na dobrze dopasowaną. Jednak po pewnym czasie, gdy turbina pracuje okazuje się, że wirnik zahacza i od tarcia topi się na ściankach. Jest to rzecz całkiem normalna i nie ma co się przejmować.

To akurat nie jest normalne i świadczy o tym że jest to jak sam napisałeś tanio wykonane.

Turbinka pracująca na tak wysokich obrotach powinna być wyważona. tak samo silnik. Brak wyważenia najpierw powoduje starcie krawędzi wentylatora, to powoduje że podczas pracy coraz bardziej drga, wybija oś silnika, i znowu się ściera, a to z czasem zabija cały napęd.

Oczywiście to nie silniki odrzutowe samolotów, ale jednak małą żywotność trzeba wkalkulować w koszty użytkowania, co można zaliczyć do wady tych napędów.

Link do komentarza
Share on other sites

To akurat nie jest normalne i świadczy o tym że jest to jak sam napisałeś tanio wykonane.

Miałem na myśli, że jest to normalne dla konkretnie tego modelu. Miałem ich już z 5-7 i w każdej występował taki efekt. W mniejszym lub większym stopniu, jednak zawsze.

Link do komentarza
Share on other sites

Należy zapomnieć o metodach z pętlami for i sztucznymi opóźnieniami. Może to zniszczyć turbinkę lub

Dla mnie to brzmi jak "naciskanie na pedał gazu ręką może zniszczyć silnik.".

Częstotliwość nie musi być 50Hz, dla regulatora liczy się czas impulsu, większość będzie działać na większej częstotliwości. Regulator można też sterować przez I2C.

Jak turbina ociera o tunel to jest po prostu źle zamocowana.

Link do komentarza
Share on other sites

Zdajesz sobie chyba sprawę, że ciężko będzie wygenerować odpowiednie sygnały na jakiś for-ach i delay-ach. Szczególnie biorąc pod uwagę, że takie sztuczki próbować będą początkujący, którzy pewnie nie zdają sobie sprawy nawet jak ten sygnał ma wyglądać. Po co uczyć czegoś co jest złe?

Od generowania PWM są timery, więc trzeba ich używać. Równie dobrze mógłbyś sobie zbudować jakiś układ na NE555 to sterowania regulatorem, tylko po co skoro procesor ma do tego gotowe peryferia. Po drugie uciąłeś moją wypowiedź w połowie 😉

Jak turbina ociera o tunel to jest po prostu źle zamocowana.

To już nie moja wina - pisałem to, co zaobserwowałem w praktyce.

Link do komentarza
Share on other sites

Nie chodzi mi o to w jaki sposób generujemy sygnał, tylko o brak związku między sygnałem na wejściu regulatora a możliwością uszkodzenia silnika. Wypowiedź uciąłem, bo moje wątpliwości dotyczyły tylko tej części.

Link do komentarza
Share on other sites

Generowanie jakichkolwiek sygnałów o stosunkowo wysokich częstotliwościach za pomocą pętli opóźniających, a także i biblioteki _delay_ms dla AVR( która także jest oparta o puste pętle) jest niewskazane. Różne kompilatory, inne poziomy kompilacji, wystąpienie w miedzy czasie przerwań mogą sprawić, że czasy się rozjadą. Do tego zostały stworzone sprzętowe Timery.

Dla mnie to brzmi jak "naciskanie na pedał gazu ręką może zniszczyć silnik.".

Na pewno w ręce będziesz miał mniejsze wyczucie niż w nodze. Samochód będzie szarpał, pojedziesz mniej oszczędnie i spalisz więcej paliwa, a i dla silnika zbyt zdrowe to nie będzie. 😉

Link do komentarza
Share on other sites

Fajnie było by gdybyś dodał wykres, który pokazywał by zależność między sygnałem PWM(wypełnienie 0-100%) a ciągiem turbiny jaki wytworzy 🙂. Myślę, że do tego eksperymentu wystarczyła by waga kuchenna. Ale to tylko moje fanaberie

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.