Skocz do zawartości

Serwa się zacinają.


piotrek038

Pomocna odpowiedź

Witem,

Mam pewien problem z serwami. Otóż zacinają się. Nie wiem czy to kwestia programu czy układu (chociaż ten jest mega prosty).


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

//------------ F_CPU 8MHz -----------//

#define LICZBA_SERW     8
#define SERWPORT        PORTB
#define SERWDIR         DDRB
#define SERW_PWMMIN     600
#define SERW_PWMMAX		2400
#define SERW_PWMSRODEK  ((SERW_PWMMAX + SERW_PWMMIN)/2)
#define LEDPORT			PORTD
#define LEDDIR			DDRD
#define BUTTPORT		PORTC
#define BUTTDIR			DDRC
#define BUTTPIN			PINC
#define BUTT_1			PC0
#define BUTT_2			PC1
#define BUTT_3			PC2
#define BUTT_4			PC3
#define BUTT_5			PC4
#define BUTT_6			PC5
#define BUTT_7			PC6
#define WOLNE			SERW_TablicaPwm[4]
#define WOLNE2			SERW_TablicaPwm[5]
#define UCHO_PG			SERW_TablicaPwm[0] //2200 MAX DÓŁ //1300 MAX GÓRA
#define UCHO_PD			SERW_TablicaPwm[1]
#define UCHO_LG			SERW_TablicaPwm[2] //800 MAX DÓŁ //1700 MAX GÓRA
#define UCHO_LD			SERW_TablicaPwm[3]

// 2500 LEWO //500 PRAWO


int SERW_TablicaPwm[LICZBA_SERW];
int SERW_Numer=0;
int SERW_NumerOdbior=0;

void SERW_TablicaPwmInit()                                        //Inicjalizacja tabeli przechowującej pozycje serw
{
   for(int i=0;i<LICZBA_SERW;i++)
       SERW_TablicaPwm[i]=SERW_PWMSRODEK;
}


void SERW_PortInit()                                            //Inicjalizacja portu do którego podłączono serwa
{
   SERWDIR = 0xFF;
   SERWPORT = 0x00;
}

void LED_PortInit()												//Inicjalizacja portu do którego podłączono diody
{
LEDDIR = 0xFF;
LEDPORT = 0x00;
}

void BUTT_PortInit()											//Inicjalizacja portu do którego podłączono przyciski
{
BUTTDIR = 0x00;
BUTTPORT = 0xFF;
}

void TIMER1_Init()
{
   TCCR1B |= _BV(WGM12);                                        //Tryb CTC
   OCR1A = SERW_PWMSRODEK;                                        //Ustawienie wstępne serw w pozycji środkowej
}

void TIMER2_Init()
{
   TCCR2 |= _BV(WGM21) | _BV(CS21) | _BV(CS22);                 //Tryb CTC, preskaler przez 256
   OCR2 = 78;                                                   //Odmierzanie 2,5 ms
   TIMSK |= _BV(OCIE2);                                         //Zezwolenie na przerwanie CTC
}

void Przyciski()												//Funkcja zmiany wartoci tablicy za pomocą przycisków
{
if(bit_is_clear(BUTTPIN,BUTT_1))							//LEWO
	{
		UCHO_PG=1800;
		UCHO_PD=1650;
		UCHO_LG=1700;
		UCHO_LD=2100;
		_delay_ms(20);

	}

if(bit_is_clear(BUTTPIN,BUTT_2))							//ŚRODEK
	{
		UCHO_PG=1700;
		UCHO_PD=1500;
		UCHO_LG=1300;
		UCHO_LD=1500;
		_delay_ms(20);

	}

if(bit_is_clear(BUTTPIN,BUTT_3))							//PRAWO
	{
		UCHO_PG=1250;
		UCHO_PD=800;
		UCHO_LG=1200;
		UCHO_LD=1350;
		_delay_ms(20);
	}

if(bit_is_clear(BUTTPIN,BUTT_4))
	{
		UCHO_PG=1400;
		UCHO_PD=1500;
		UCHO_LG=1600;
		UCHO_LD=1500;
		_delay_ms(20);
	}


if(bit_is_clear(BUTTPIN,BUTT_5))
	{
		UCHO_PG=2100;
		UCHO_PD=800;
		UCHO_LG=900;
		UCHO_LD=2300;
		_delay_ms(20);
	}

}

ISR(TIMER1_COMPA_vect)
{
   TCCR1B &= ~_BV(CS11);                                        //Włączenie TIMER1
   SERWPORT = 0x00;                                            //Wyzerowanie portu serw
   TIMSK &= ~_BV(OCIE1A);                                        //Wyłączenie zezwolenia na przerwanie COMP od TIMER1
   if(++SERW_Numer >= LICZBA_SERW)
       SERW_Numer=0;
}

ISR(TIMER2_COMP_vect)
{
   TCNT1=0;                                                    //Zerowanie TIMER1
   OCR1A = SERW_TablicaPwm[SERW_Numer];                        //Podanie wypełnienia dla danego serwa
   TCCR1B |= _BV(CS11);                                        //Uruchomienie TIMER1 z preskalerem 8
   SERWPORT |= _BV(SERW_Numer);                                //Ustawienie odpowiedniego pinu
   TIMSK |= _BV(OCIE1A);                                        //Zezwolenie na przerwanie COMP od TIMER1
}



int main()
{
   SERW_PortInit();
   LED_PortInit();
   BUTT_PortInit();
   SERW_TablicaPwmInit();
   TIMER1_Init();
   TIMER2_Init();
   sei();

   while(1)
   {
   	Przyciski();
   }
   return 0;
}

Serwa zacinają się losowo, ale zauważyłem że najczęściej w pozycji wywołanej przyciskiem 5:

if(bit_is_clear(BUTTPIN,BUTT_5))
	{
		UCHO_PG=2100;
		UCHO_PD=800;
		UCHO_LG=900;
		UCHO_LD=2300;
		_delay_ms(20);
	}

I teraz pojawia się moje pytanie, czy to wina kodu czy układu. Wszystko na AtMedze8. Zasilanie podłączone zgodnie ze wskazówkami ze strony.

Oczywiście wystarczy reset i wracają do normy.

Drugie co mi przyszło do głowy to może za niskie napięcie? Czy może to być spowodowane zbytni rozładowaniem się akumulatora? Tylko że serwa po resecie działają normalnie.

Czasem zdarza się że zacina się dosłownie co 30s a czasem przez godzinę można się bawić.

Może ma ktoś pomysł o co chodzi?

Pozdrawiam!

Link do komentarza
Share on other sites

Moim zdaniem przyczyną mogą być dwie rzeczy.

➡️ Zbyt słabe źródło zasilania kiedy serwo działa napięcie może przysiąść przez układ działa niestabilnie.

➡️ Nie dokładny zegar procesora...

Link do komentarza
Share on other sites

to znaczy serwa są w na 100% sprawne, wyciągnąłem je ze swojego akrobata wiec nie ma szans żeby coś im było 😉

Jeśli chodzi o zasilanie to właśnie jestem w trakcie manualnego sprawdzania 😉 faktycznie napięcie trochę przygasa ale zastanawia mnie dlaczego po tym jak już się zatrzymają trzeba je zrestartować a nie da się zmienić położenia przyciskiem, w końcu w jakieś tam określonej pozycji pobierany przez nie prąd jest minimalny (oczywiście nie są zblokowane) a one po prostu się zatrzymają i nic, nie reagują. Z dwa razy zdarzyło mi się że zaczęły drgać tak jakby serwo otrzymywało 2 sygnały, czyli niby wychodziło by na to że przycisk się zaciął ale to jest niemożliwe bo w takim przypadku reset by nie pomógł... czy się mylę?

Jeśli serwo podłączam do zasilania, bez sygnału to normalnie drgnie i tyle, tak jak to zwykle bywa.

( nie wiem czy o to chodziło ;/ )

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

Piotrek, zanim zaczniesz rozbierać serwa, spróbuj zweryfikować sygnał PPM jaki dla nich generujesz. Jeśli nie masz oscyloskopu, weź jakąś diodę LED szeregowo z opornikiem kilkaset omów i podłącz to do wyjścia sterującego serwem. Powinna dość słabo świecić a tak naprawdę mrugać 50Hz, sam wiesz. W zależności od wypełnienia sygnału PPM powinna być trochę jaśniejsza lub ciemniejsza ale nigdy nie może zgasnąć ani zapalić się na full. Sprawdź w ten sposób wszystkie wyjścia gdy jest dobrze a następnie poczekaj aż coś się zatnie i wtedy powtórz test z diodką. Może Twój program gdzieś zwisa albo któreś wyjście jest źle obsługiwane i "zostaje" w stanie 0 lub 1?

Czy mógłbyś w kilku słowach (ale jednak w miarę dokładnie) opisać swoją ideę generacji PPM?

Jeszcze przyszło mi do głowy to, że Twoja tablica przechowująca długości impulsów jest 16-bitowa. To oznacza, że do zmiany zawartości jednej pozycji procesor musi wykonać dwa zapisy do pamięci. Jeżeli przerwanie (które akurat będzie tej pozycji używać) przyjdzie w chwili gdy jeden bajt już został zapisany a drugi jeszcze nie, to cała liczba 16-bitowa w czasie obsługi przerwania będzie niespójna. Jeśli dodatkowo to co było tam wcześniej będzie jakieś pechowe, całość może np. przekroczyć zakres długości 2.5ms. Spróbuj ciągi instrukcji modyfikujące "USZY" zamknąć w blokach sekcji krytycznych cli() / sei().

Link do komentarza
Share on other sites

Podłącz dobre źródło zasilania bo często serwa potrafią pociągnąć sporo prądu.

Hmm kod wygląda ok. A jakie masz serwa?? W przycisku piątym wprowadzasz wartość 2300. Być może jest to już poza zakresem serwa??

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.