Skocz do zawartości

Generator PPM


Pomocna odpowiedź

Napisano

Witam.

Jako, że nie chciałbym wyważać już otwartych drzwi 🙂. Czy ktoś z was wykonywał kiedyś generator PPM ? Jeśli tak to proszę o jakieś podpowiedzi, jak rozwiązaliście to sprzętowo oraz programowo.

Z góry wielkie dzięki za odpowiedź.

Kiedyś walczyłem z tym, ale na innym forum. Znaczy sie nie jest to chyba typowe PPM, ale pozwala sterować 4 czy 5 serwami naraz, napisane jest to w BASCOM AVR.

Tutaj masz opis naszych wzmagań i listingi programów.

Mateusz, dużo zależy od tego jaką dokładność chcesz uzyskać. Jeżeli nie dużą to wystarczy po prostu zliczać takty mikrokontrolerem. Lepszą dokładność uzyskasz stosując układ z serii PCF... A jeszcze lepszą dokładność uzyskasz zaprzęgając do tego odbiornik GPS. Od strony programowej będzie to tylko zliczanie impulsów - nic trudnego.

Hehe, widzę, że nie zrozumiałem twojego pierwszego postu (skrót PPM ma też inne rozwinięcie 🙂 ).

Wracając do sterowania serwami, to ja poszedłbym po najmniejszej linii oporu i zastosował jeden z układów z serii Xmega które mają do 24 wyjść PWM i kalibrowany wewnętrzny oscylator. Wykorzystanie sprzętowego generatora PWM właściwie zwalnia cię z pisania programu, jedyne co musisz robić w programie to zmiana szerokości impulsu (jedna linijka kodu na jedno serwo).

Niestety muszę wykorzystać tylko jedno wyjście bo chce wysyłać dane przez radio do modelu. A komunikacja odbywa się przez jedną linię.

Chodzi mi o taki sygnał jak na obrazku poniżej:

No na pewno się da 🙂 bo to nie jest skomplikowane. Tylko myślałem, że może ma ktoś już jakieś rozwiązanie które wypracował po wielu próbach i jest optymalne i proste w implementacji 🙂 A może nawet jakieś sprzętowe rozwiązanie na mux na przykład 🙂

Znaczy się ty potrzebujesz układ kodujący do pilota, czy dekodujący do modelu ?

Kiedyś w EDW był opisany sterownik 16 serwomechanizmów, który można by upchnąć w CPLD, ale nie wykorzystywał om metody PPM.

Ja nie mam zbudować sterownika iluś tam serw tylko muszę wysłać sygnał do nadajnika (Futaba 10C). I ma być to sygnał PPM. Czyli co 20ms wysyłam po kolei długość wypełnienia sygnału PWM pierwszego serwa, potem drugiego itd. i tak co 20ms.

Na razi mam coś takiego ale to chyba nie działa ;/. Na razie nie mogę tego sprawdzić bo nie mam oscyloskopu.

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

#define SetBit(x,y)	x |= (1<<y)
#define ClrBit(x,y) x &= ~(1<<y)
#define NegBit(x,y) x ^= (1<<y)

volatile int S1,S2,S3,S4,S5,S6,S7,S8,S9,S10, t=0;   // Zmienna w mikro sekundach, Serwa 1,2,3,...        

void ppm()
{

//Serwo 1 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S1-300);

//Serwo 2 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S2-300);

//Serwo 3 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S3-300);

//Serwo 4 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S4-300);

//Serwo 5 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S5-300);

//Serwo 6 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S6-300);

//Serwo 7 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S7-300);

//Serwo 8 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S8-300);

//Serwo 9 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S9-300);

//Serwo 10 **********************
SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);
_delay_us(S10-300);

SetBit(PORTC,1);
_delay_us(300);
ClrBit(PORTC,1);


NegBit(PORTC,2);
}

ISR(TIMER1_COMPA_vect)
{
ppm();	
}


int main(void)
{ 
DDRC	=	0b11111111;		// PORTC jako wyjście
PORTC	=	0b11111111;

TCCR1A= (1<<FOC1A);
TCCR1B= (1<<CS11) | (1<<WGM21);

OCR1A=4000;
TIMSK = (1<<OCIE1A);

sei();

S1=1000;
S2=400;
S3=400;
S4=2000;
S5=400;
S6=2000;
S7=400;
S8=400;
S9=2000;
S10=400;

 while(1)
 {   

 }
}

Podstawowa sprawa - nie powinno stosować się zmiennych jako argumentu funkcji _delay_us() ani _delay_ms()!

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