Memo pentru decodarea semnalelor PWM și ppm, note ale programatorului

Aparatul radio tipic funcționează astfel. Există un transmițător (de fapt, APA în sine) și un receptor. Receptorul cu transmițătorul comunică printr-un fel de protocol, adesea închis. Receptorul decodează acest protocol și transferă mai departe poziția pixurilor pe echipament, de exemplu, la controlerul de zbor (PC) al quadrocopterului. PC-ul și receptorul comunică în conformitate cu protocolul lor, pe care ambii trebuie să o înțeleagă. În acest loc, PWM și PPM sunt foarte populare. Există și alte opțiuni, în special SBUS, DSM2 și DSX, dar în acest articol vom lua în considerare doar PWM și PPM.







PPM (modul de poziționare a impulsurilor) - aceasta este o astfel de încercare de a împinge o mulțime de semnale PWM într-un singur fir, sau, cel puțin, personal mă gândesc la asta. PPM transmite întotdeauna impulsuri scurte. Pauzele între fronturile impulsurilor corespund cu durata unui semnal PWM. Semnalele sunt transmise secvențial, mai întâi valoarea pe primul canal, apoi pe al doilea canal și așa mai departe. Corespondența dintre semnalele PPM și PWM este bine reflectată de următoarea oscilogramă înregistrată pe Rigol DS1054Z:

Memo pentru decodarea semnalelor PWM și ppm, note ale programatorului

Oscilogram scos din receptor RadioLink R8EF, având un mod în care doi pini servește semnale PPM și SBUS, iar pinii rămase - semnal PWM pentru canalele de 3 până la 8. Prin urmare, semnalele PWM pentru canalele 1 și 2 nu sunt afișate. Aici puteți vedea câteva caracteristici interesante. În primul rând, acest receptor special utilizează unitatea logică 3.3, deși alimentat de la 5 V. În al doilea rând, acesta semnalul PPM este inversat în raport cu modul în care este desenat, de obicei, în imagini (de exemplu, în acest thread). Ciudat cum pare, tot ceea ce este scris mai sus despre fronturile impulsurilor rămâne adevărat. În particular, în imagine fronturile corespunzătoare semnalului PWM de pe canalul 3 sunt evidențiate cu cursoare. În acest caz, semnalul PPM este mutat în raport cu semnalele PWM, dar, în general, receptorul nu a trebuit să le sincronizeze într-un fel.

PPM funcționează bine până când încercați să împingeți mai mult de 8 canale în ea. Dacă există mai multe canale, atunci fie semnalele încep să se actualizeze cu o întârziere mai mare de 20 ms (ca în cazul PWM), fie este necesar să se "comprime" semnalele, să se piardă precizia lor sau să se utilizeze fire suplimentare. Personal, nu am văzut că mai mult de 8 canale au fost transmise prin PPM.

Bine, acum să spunem că vreau să-mi controlez robotul cu echipament radio. Aici este codul corespunzător pentru PWM:

#include
#include

# definește NCHANNELS 8
#define CH1_PIN 5 // CH2_PIN = CH1_PIN + 1, etc







volatile int pwm_value # 91; NCHANNELS # 93; = # 123; 0 # 125; ;
volatile int prev_time # 91; NCHANNELS # 93; = # 123; 0 # 125; ;

void în creștere # 40; # 41; ;

căderea neplăcută # 40; # 41; # 123;
uint8_t pin = PCintPort. arduinoPin;
PCintPort. attachInterrupt # 40; PIN-ul, în creștere, RISING # 41; ;
pwm_value # 91; pin - CH1_PIN # 93; = micros # 40; # 41; - prev_time # 91; pin - CH1_PIN # 93; ;
# 125;

void în creștere # 40; # 41;
# 123;
uint8_t pin = PCintPort. arduinoPin;
PCintPort. attachInterrupt # 40; PIN-ul, cădere, cădere # 41; ;
prev_time # 91; pin - CH1_PIN # 93; = micros # 40; # 41; ;
# 125;

void setup # 40; # 41; # 123;
pentru # 40; uint8_t i = 0; eu pinMode # 40; CH1_PIN + i, INPUT_PULLUP # 41; ;
PCintPort. attachInterrupt # 40; CH1_PIN + i, în creștere, RISING # 41; ;
# 125;

Serial. începe # 40; 9600 # 41; ;
# 125;

buclă voidă # 40; # 41; # 123;
pentru # 40; uint8_t i = 0; eu Serial. println # 40; "ch" + șir # 40; i + 1 # 41; + "=" + String # 40; pwm_value # 91; eu # 93; # 41; # 41; ;
Serial. println # 40; "----------------" # 41; ;
întârziere # 40; 1000 # 41; ;
# 125;

Și acesta este codul pentru PPM:

#include
#include

#define PPM_PIN 6
#define MAX_CHANNELS 12

volatile int pwm_value # 91; MAX_CHANNELS # 93; = # 123; 0 # 125; ;
volatile int prev_time = 0;
volatile int curr_channel = 0;

volatilă boolă volatilă = falsă;

void în creștere # 40; # 41;
# 123;
int tstamp = micros # 40; # 41; ;

/ * nu ar trebui să se întâmple niciodată în mod automat, dar cine știe. * /
dacă # 40; curr_channel pwm_value # 91; curr_channel # 93; = tstamp - prev_time;
dacă # 40; pwm_value # 91; curr_channel # 93;> 2100 # 41; # 123; / * este de fapt o sincronizare * /
pwm_value # 91; curr_channel # 93; = 0;
curr_channel = 0;
# 125; altfel
curr_channel ++;
# 125; altfel
overflow = true;

prev_time = tstamp;
# 125;

void setup # 40; # 41; # 123;
pinMode # 40; PPM_PIN, INPUT_PULLUP # 41; ;
PCintPort. attachInterrupt # 40; PPM_PIN, în creștere, RISING # 41; ;

Serial. începe # 40; 9600 # 41; ;
# 125;

buclă voidă # 40; # 41; # 123;
pentru # 40; uint8_t i = 0; eu Serial. println # 40; "ch" + șir # 40; i + 1 # 41; + "=" + String # 40; pwm_value # 91; eu # 93; # 41; # 41; ;
dacă # 40; revărsare # 41;
Serial. println # 40; "Overflow!" # 41; ;
Serial. println # 40; "----------------" # 41; ;
întârziere # 40; 1000 # 41; ;
# 125;

Codul a fost testat pe aparatul radio RadioLink T8FB și receptorul la acesta R8EF. În fotografia următoare, receptorul, care a fost comutat în modul PPM, este conectat la Arduino Nano cu firmware-ul pentru PPM încorporat în acesta:

Memo pentru decodarea semnalelor PWM și ppm, note ale programatorului

Exemplu de ieșire de depanare pe UART:

Scopul bibliotecii PinChangeInt folosit mai sus ar trebui să fie clar de cod. Vă permite să închideți întreruperile pe marginea de conducere și de tracțiune (creștere și cădere) a semnalului la pinii specificați. Detalii despre această bibliotecă pot fi găsite aici și aici. Versiunea completă a firmware-ului pentru decodarea semnalelor PWM și PPM este disponibilă pe GitHub.

Înarmat cu cunoștințele acumulate aici, nu putem controla numai Arduino folosind radio, dar, de asemenea, de exemplu, decodoare de lipire PWM / de la PPM (dacă nu doriți să plătească pentru gata AliExpress), sau chiar pentru a produce propriul echipament radio, pe baza unui NRF24L01 sau un alt modul radio. Acesta este doar primul lucru care mi-a venit personal.

Și ce idei nebunești de creativitate aveți?

Îți place postul? Trimiteți-le altora:

(JS trebuie să fie activată)







Articole similare

Trimiteți-le prietenilor: