Skocz do zawartości

Sterowanie serwem sg90


r_bot

Pomocna odpowiedź

Chciałem dziś się pobawić serwem sg90. Używam mikrokontrolera Atmega 644p. Napisałem taki mały program.

/*
* SG90.c
*
* Created: 2014-11-28 21:17:43
*  Author: Mateusz
*/ 

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
DDRD |= (1<<PD5);
TCCR1A |= (1<<WGM10);
TCCR1A |= (1<<COM1A1);
TCCR1B |= (1<<CS12);//presklaer 256
ICR1 = 1249; //ICR1=16000000/50/256 - 1;
OCR1A = 94; //serwo w pozycji neutralnej 94/1249 ~ 1.5/20

   while(1)
   {
	_delay_ms(1000);
	OCR1A = 62; //serwo wychylone 62/1249 ~ 1/20
	_delay_ms(1000);
	OCR1A = 94;

   }
}

Częstotliwość procesora to 16MHz zdefiniowana w ustawieniach. Serwo zamiast co sekundę zmieniać swoje położenie lekko się przekręci i dalej stoi w miejscu i buczy. Jest popsute, czy ja źle coś zrobiłem?

Link do komentarza
Share on other sites

Nie odpowiem Ci wprost, ale możemy nad tym popracować tak jakbyś miał pod ręką oscyloskop. Odpaliłem Twój program na AVR taktowanym z 20MHz i oto wyniki. Dostaję przebieg prostokątny o okresie powtarzania 6.5ms. Długość impulsów zmienia się skokowo co sekundę: raz mamy ok. 1.6ms a raz ok. 2.4ms. Takie parametry są dość odległe od prawidłowego przebiegu PPM i na razie możemy założyć, że serwo jest OK.

Teraz Ty przelicz czasy na takie jakie byś dostał przy zegarze 16MHz i pomyśl co może być nie tak. Proponuję analizę zacząć od trybu timera oraz okresu PWM i uzyskać prawidłową częstotliwość powtarzania. Potem możesz przejść do wypełnienia.

Może napisz własnymi słowami jak to miało działać. Takie tłumaczenie komuś niekumatemu daje rewelacyjne wyniki, spróbuj.

Link do komentarza
Share on other sites

Przyjrzyj się uważnie tabeli 13-5 z datasheet. Ustawiasz tylko bit WGM10, więc wybierasz tryb 'PWM, Phase Correct, 8-bit', który ma na stałe ustawioną wartość maksymalną na 0xFF czyli 255 - nie używa wcale rejestru ICR1. Jeśli chcesz używać tego rejestru jako maksimum musisz wybrać tryb, który w kolumnie 'TOP' ma wpisany właśnie ten rejestr.

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

int main(void)
{
DDRD |= (1<<PD5);
TCCR1A |= (1<<WGM11);
TCCR1B |= (1<<WGM13);
TCCR1A |= (1<<COM1A1);
TCCR1B |= (1<<CS12);//presklaer 256
ICR1 = 1249; 50Hz
OCR1A = 94; //serwo w pozycji neutralnej 94/1249 ~ 1.5/20
   while(1)
   {
  _delay_ms(1000); 
        OCR1A = 62; //serwo wychylone 62/1249 ~ 1/20 
        _delay_ms(1000); 
        OCR1A = 94; 	
   }
}

Tak ma wyglądać? Chyba jednak nie bo serwo wychyla się maksymalnie i "buczy".

Link do komentarza
Share on other sites

Niedobrze. Nie widzę u Ciebie żyłki ciekawości i dociekliwości. W ogóle nie czytałeś tego co napisałem i/lub nie wyciągnąłeś wniosków z liczb. Smuci to tym bardziej, że nawet mając oscyloskop - potężne narzędzie, nie miałbyś z niego pożytku. Nadal nie dostaniesz nic na tacy. Tym razem proponuję przeczytanie rozdziału "Phase Correct PWM Mode". Wybrałeś go to pewnie wiesz dlaczego (choć prostszy jest Fast PWM i tutaj taki wystarcza), ale chyba dobrze jest wiedzieć jak to działa naprawdę. A podpowiem, że nie tak jak sobie wyobrażasz.

Link do komentarza
Share on other sites

Być może nie potrafię myśleć. Teraz chciałbym zapytać o co innego. Czy taki kod powinien utrzymać serwo w pozycji wychylonej?

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define SERWO (1<<PC7)
#define SERWO_L PORTC &= ~ SERWO
#define SERWO_H PORTC |= SERWO;

int main(void)
{

DDRC |= SERWO;

   while(1)
   {
	SERWO_H;
	_delay_ms(2);
	SERWO_L;
	_delay_ms(18);
   }
}

Wiem, że to nie ładnie tak zajmować pętle główną, ale w ramach testów tak mogę zrobić.

Link do komentarza
Share on other sites

No to moje serwo jest popsute, ponieważ po wgraniu programu, obróci się maksymalnie i słychać "buczenie", a dalej już nie może się kręcić, bo jest blokada.

Link do komentarza
Share on other sites

Wiem, że już to pisałeś, ale upewnij się czy rzeczywiście masz dobrze ustawione zegary. Zarówno ten w programie (F_CPU) jak i fuse bity w procku. Niezwykle rzadko zdarzają się takie awarie. Mostek wyjściowy, ew. tranzystory lub sam silnik to jeszcze, ale sterowanie? Hm, to może być potencjometr. Jeżeli masz multimetr, to sprawdź wypełnienie przebiegu. Podłącz woltomierz DC do sygnału i powinien pokazywać wartość średnią 5V*(2/20)=0.5V. Zmieniając wypełnienie powinieneś otrzymywać odpowiednio inne wartości. Jeżeli masz pomiar częstotliwości - powinno być ok. 50Hz. Ew. możesz podłączyć do portu jakiś mały głośniczek lub słuchawki od kompa i posłuchać dźwięku. 50Hz jest charakterystyczne.

Link do komentarza
Share on other sites

Mam multimetr, zmierzyłem napięcie, i nie wynosi ono 0,5V tylko 0,75V. W ustawieniach F_CPU mam 16MHz(sprawdzone po raz n-ty) Wydaje mi się, że procesor na 99% jest taktowany z zewnętrznego kwarcu 16MHz. jeśli go wyciągnę to napiecie na PC7 wynosi 3,3V.

Odcztane Fusebity

hFuse d0

lFuse EF

eFuse FF

Lockbit 3F

Link do komentarza
Share on other sites

Oj, to bardzo dziwne. Przy tej częstotliwości multimetr nie powinien mieć żadnych kłopotów z uśrednianiem i pomiar przebiegu o amplitudzie Vcc=5V i wypełnieniu 10% (2ms/20ms) powinien dać 0.50V z dokładnością do dwóch miejsc po przecinku. Mam kilka pomysłów:

- Sprawdź zasilanie - czy na pewno 5V.

- Sprawdź bez serwa - jego wejście może być tak uszkodzone, że przywiera pin procesora do plusa albo przynajmniej ciągnie do góry na tyle mocno, że z 0.5V robi się 0.75V.

- Czy są wspólne masy serwa i procka i jak całość jest podpięta do zasilacza - może to narysuj?

- Z czego zasilasz serwo - czy z tego samego źródła co procesor i czy wydajność prądowa zasilacza jest wystarczająca do napędzania serwa bo jeśli tak, to mogą być "zapady" przy starcie. Jeżeli korzystasz np. ze stabilizatora 7805 lub jakiejś wtyczkowej "ładowarki" a serwo (nawet nieobciążone) przy starcie może brać w impulsie ponad 1A, to zasilanie przysiada, procesor się resetuje po czym zaczyna program od nowa, generuje pierwszy impuls PPM, reset chwila przerwy, znów impuls lub kilka, reset i tak w kółko. Wtedy miałbyś na wyjściu ciąg impulsów związany bardziej z systemem zerowania procesora i kondensatorami na Vcc niż z samym przebiegiem programu. Z fusebitów wynika, że BOD masz wyłączony - dlaczego? Przecież mając takie coś w procesorze warto z tego korzystać. Nie zawsze zasianie narasta monotonicznie od zera a nawet krótkie impulsy i zaniki Vcc mogą rozwalić działanie każdego programu bo przestawiają przypadkowe przerzutniki w scalaku. Dobre zasilanie i RESET to podstawa. Spróbuj zapalać jednorazowo po starcie, zaraz na początku main() jakąś diodkę LED np. na 0.2s. Wtedy zobaczysz, czy i kiedy procek przechodzi przez stan reset.

Link do komentarza
Share on other sites

Dzisiaj trochę przy tym posiedziałem, i rzeczywiście napięcie wynosi 0,5V. Nie wiem dlaczego wtedy było 0,75V, chyba miałem wgrany inny wsad. Pod pin pc7 podłączyłem buzzer, i uruchomiłem aplikacje pod androida Osciloscoppe(wiem że to nie jest dokładne), sygnał powtrzał się co ok. 20ms, więc raczej powinno być 50Hz. Podłączyłem też diodę pod pin PC6, i załączam ją na 200ms w main(), i miga tylko jeden raz. Wszystko mam podłączone tak jak na rysunku, zestaw testowy zasilany z portu USB, serwo ze starej ładowarki od telefonu 4.9V 590mA, masy połączone. Dlaczego mam wyłączony BOD? Dlatego, że jeszcze nie zmieniałem nigdy fusebitów w procesorze. Wg mnie albo jest uszkodzone serwo, albo zasilacz za słaby, będę musiał poszukać inny. Dziś chcę zamówić nowe serwo, SG90 i tak było by za słabe do mojego projektu. Które z tych trzech najlepiej wziąć, zależy mi na metalowych zębatkach.

1. Serwo TowerPro MG-945R http://botland.com.pl/serwa-typu-standard/2227-serwo-tower-pro-mg-945r.html

2. Serwo TowerPro MG-995R http://botland.com.pl/serwa-typu-standard/819-serwo-tower-pro-mg-995r.html

3. Serwo TowerPro MG-995 http://botland.com.pl/serwa-typu-standard/817-serwo-tower-pro-mg-995.html

Które będzie najmniej awaryjne?

Przy okazji jeszcze spytam o ten kod:

/*
* SG90.c
*
* Created: 2014-11-28 21:17:43
*  Author: Mateusz
*/ 

#include <avr/io.h>
#include <util/delay.h>


int main(void)
{
DDRD |= (1<<PD5);

TCCR1A |= (1<<WGM11);
TCCR1B |= (1<<WGM13)|(1<<WGM12);
TCCR1A |= (1<<COM1A1)|(1<<COM1B1);
TCCR1B |= (1<<CS11)|(1<<CS10);//presklaer 64
ICR1 = 4999; //50Hz
OCR1A = 500; 

   while(1)
   {

   }
}

Powinien on chyba dawać takie same wyniki jak kod w poście 7? Też na pinie PD5 jest 0,5V i około 50Hz pokazuje aplikacja Osciloscoppe.

Link do komentarza
Share on other sites

Wszystkie trzy serwa są podobnej klasy, w podobnej cenie i tej samej firmy. Nie oczekiwałbym dużych różnic w niezawodności. Jedno z nich jest podwójnie łożyskowane co pozwala na większe obciążenia wałka wyjściowego - i to jest mechanika której elektroniką nie da się nadrobić. Unikaj tego 995 - mimo reklamowanego dużego momentu w niewielkiej objętości, zebrało bardzo złe recenzje (wykonanie, kultura pracy, potencjometr, trwałość):

http://www.rcmodelreviews.com/mg995review.shtml

Z tych trzech wybrałbym właśnie 945R. Nie wiem ile momentu potrzebujesz, ale zawsze projektuj i wybieraj napędy (podobnie jak zasilanie systemu, moc obliczeniową procesora i wiele innych założeń projektowych) z pewnym zapasem. Przy serwach ważne jest napięcie zasilania - momenty są określane przy pewnych jego wartościach. Moim zdaniem 50 lub nawet 100% zapasu momentu na serwie to dobry pomysł.

Program ma wadę polegającą na złym ustawieniu bitów COM. Pracą wyjścia OC1A sterują COM1A1 i COM1A0 i to one powinny być ustawione jeśli chcesz dostać wypełnienie 10% przy tych wartościach ICR1 i OCR1A. Nie wiem dlaczego nie wpiszesz po prostu dwóch stałych (składających się z odpowiednich bitów wyznaczonych makrem _BV() ) do dwóch rejestrów TCNT1x zamiast takiego cackania się z bitami i operatorami |=. Kompilator nie może tego zoptymalizować do dwóch prostych zapisów, bo wszystkie rejestry peryferiów mają atrybut volatile a każdorazowe użycie |= wymusza operację odczyt-modyfikacja-zapis.

Jeżeli masz rozdzielone zasilania procesora i serwa oraz dobrze połączone masy, to ostatnią rzeczą jest sprawdzenie zasilania samego serwa. Czy możesz podłączyć swój oscyloskop pod zasilanie serwa i sprawdzić, czy nie ma zapadów podczas próby startu silnika? Nawet jeśli wejście pomiarowe jest przez kondensator (sprzężenie AC) to zaniki lub spadki zasilania do np. 3V powinno być wyraźnie widać. Acha, o ile pamiętam napisałeś wcześniej, że po zapodaniu sygnału PPM serwo podjeżdża do skrajnego położenia, czy tak? Nawet gdy ręcznie (bez zasilania) ustawisz je na środek? No to zasilanie raczej jest i o ile nie robisz czegoś naprawdę dziwnego, to.. nie mam więcej pomysłów 🙁 Zmierz jednak to zasilanie podczas pracy silnika.

Link do komentarza
Share on other sites

Serwo z nowym zasilaczem będę miał pod koniec tygodnia, wtedy zobaczę co słychać na nowym zasilaczu. Docelowo serwo będzie połączone kablem o długości ok 3m od AVR. Byłem dziś w sklepie i sprzedawca mi zalecił mniej więcej taki kabel, ekranowany http://allegro.pl/przewod-sterowniczy-w-ekranie-liycy-3x0-5-fv-pn-i4808806590.html. Pytanie, czy na taką odległość potrzebny jest ekran? czy ekran powinien być nie podłączony do niczego tak jak w skrętce? a może połączony z masą tak jak w antenie TV?

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!

Gość
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.