Output in PPMsum, è possibile?

Ciao a tutti,

per il mio progetto avrei bisogno di un output in PPMsum a 4 canali: con arduino leggo i 4 canali di una ricevente RC e li dovrei replicare (con o senza modifiche al valore dei singoli canali a seconda della situazione) in un unico output in PPMsum. Come si può realizzare l'output in PPMsum?
grazie a tutti per l'aiuto.

edmond_dantes:
Ciao a tutti,

per il mio progetto avrei bisogno di un output in PPMsum a 4 canali: con arduino leggo i 4 canali di una ricevente RC e li dovrei replicare (con o senza modifiche al valore dei singoli canali a seconda della situazione) in un unico output in PPMsum. Come si può realizzare l'output in PPMsum?
grazie a tutti per l'aiuto.

Questa è una cosa che interessa anche a me e mi sono sempre ripromesso di approfondire ma non ho mai trovato il tempo.
Non so se ti può aiutare ma una cosa che pensavo di fare è studiarmi la parte del codice MultiWii dove decodifica i segnali PPMSUM e vedere se da li si riesce a capire
come fare l'inverso.

Ciao.

edmond_dantes:
Come si può realizzare l'output in PPMsum?

E' una cosa semplicissima da fare, prima misuri la durata dei quattro segnali PPM in ingresso, poi durante la pausa tra due due frame consecutivi, i famosi 20 ms per ogni ripetizione, metti un pin a 1 logico per tanti microsecondi quanto durano i quattro segnali in ingresso, rispettando l'ordine, separandoli tra loro con uno 0 logico di almeno 100 us.
In pratica avrai una cosa simile dove canale1, canale2, canale3, canale4 sono il periodo in microsecondi dei vari impulsi PPM in ingresso, il tutto va ripetuto ogni 20 ms utilizzando di volta in volta le letture in ingresso dei canali.

digitalWrite(OutPin, HIGH);
delayMicroseconds(canale1);
DigitalWrite(OutPin, LOW);
delayMicroseconds(100);

digitalWrite(OutPin, HIGH);
delayMicroseconds(canale2);
DigitalWrite(OutPin, LOW);
delayMicroseconds(100);

digitalWrite(OutPin, HIGH);
delayMicroseconds(canale3);
DigitalWrite(OutPin, LOW);
delayMicroseconds(100);

digitalWrite(OutPin, HIGH);
delayMicroseconds(canale4);
DigitalWrite(OutPin, LOW);

Tutto chiaro! Grazie Astrobeed!

Rianimo un po' questa discussione perchè ora ho iniziato a ragionarci (sono molto veloce a fare le cose che mi passano per la testa XD).
Ho letto la spiegazione di astro che è stata molto chiara, però mettendola in pratica funziona in parte, quindi ho fatto delle ricerche, a dire il vero non ho trovato molto, infatti
ho trovato solo questo: R/C PPM encoding - MFTech che però mi sembra anche ben spiegato.
Da quello che dice qui, il pacchetto ppmsum ha una lunghezza fissa di 22.5ms, l'impulso di ogni canale è separato da una pausa di 0.3ms e l'impulso di ogni singolo canale può durare da
1 a 2ms inclusa la pausa di separazione (0.3ms).
Poi qui parla di un pacchetto di start che mi viene da pensare sia la differenza tra la somma degli 8 canali e 22.5ms.
Il problema è che se implemento il codice con il pacchetto di start non mi funziona più niente, mentre se non lo implemento mi trovo con il canale 1 che in realtà fa muovere il servo
sul canale 2 e andando avanti mi trovo invece che per far muovere il 6 e 7 devo fare riferimento al 5 e 6 però non si muovono del tutto, quindi mi viene da pensare che è una questione
di timing, probabilmente la pausa non deve essere di 100ms ma nemmeno di 300ms.
Chiedo solo se qualcuno mi può linkare qualche documento un po' più esauriente per capire quali sono i tempi esatti da rispettare.
Grazie :slight_smile:
Ciao.

che lo consideri sengnale inizale o finale poco cambia. sta di fatto che è un segnalòe LOW e non HIGH come sembra da quel grafico:

Perfetto, però c'è ancora qualcosa che non mi torna.
Nel link postato da me, parlano di 22.5ms di lunghezza del pacchetto, nelle due immagini postate da te parlano di 20ms e visto che poi
mi è venuto in mente che anch'io ho una ricevente frsky con relativo foglietto (avevo la soluzione sotto il naso e l'ho cercata in mezzo mondo :blush:)
ho consultato il foglietto della mia ricevente e li parlano di 18ms.
A questo punto ho un po' di confusione sulla durata del paccheto.
Nel frattempo farò un po' di prove con una durata di 20ms e vedo cosa succede.
Grazie della risposta, mi sei stato veramente molto utile :slight_smile:
Ciao.

notare il sibolo tilde davanti ai numeri: si tratta di un simbolo che vuol dire "circa". Infatti, fintanto che è presente e riconoscibile un segnale di star o di stop, si può avere delle variani anche significative.
da 18 a 22ms sono 4ms di differenza, che sulla media di 20ms sono il 5% di errore!
la statistica dice che l'errore si indica come la viariazione dal valore medio, nel nostro caso quindi 20ms+-2.5%, ma non mi stupirei se (con qualche problema con molti canali) si raggiunga un errore del 5%. anzi, direi che l'errore massimo è proporzionale al numero di canali usati!

lesto:
notare il sibolo tilde davanti ai numeri: si tratta di un simbolo che vuol dire "circa". Infatti, fintanto che è presente e riconoscibile un segnale di star o di stop, si può avere delle variani anche significative.
da 18 a 22ms sono 4ms di differenza, che sulla media di 20ms sono il 5% di errore!
la statistica dice che l'errore si indica come la viariazione dal valore medio, nel nostro caso quindi 20ms+-2.5%, ma non mi stupirei se (con qualche problema con molti canali) si raggiunga un errore del 5%. anzi, direi che l'errore massimo è proporzionale al numero di canali usati!

Perfetto, ho creato uno schetch che muove 7 servi contemporaneamente rispettando 20ms di lunghezza pacchetto e 0.3 di separazione canale e funziona :slight_smile:
Grazie.

E rieccomi qui con il mio PPM :frowning:
Ho un problemino!
Allora, il primo sketch di prova che faceva muovere i servi andava bene, ma il problema nasce ora che devo tenerli fermi.
Non riesco a tenerli perfettamente fermi, hanno sempre un continuo tremolio.
Vi spiego un po' meglio.........
Ho preso un modulo di trasmissione FRSKY e l'ho collegato ad arduino che genera il segnale PPM e dall'altra parte ho messo una
ricevente (ovviamente FRSKY) con dei servi attaccati (per il momento 4).
Ho fatto la prova di dargli un segnale fisso, ma continuano a tremare in continuazione, mentre se collego il modulo alla mia radio
quando non muovo nulla rimangono perfettamente fermi.
Eppure il segnale che esce sia da arduino che dalla ricevente, misurandolo con l'oscilloscopio è identico, sia per quanto riguarda la
lunghezza totale del segnale, che la pausa tra un canale e l'altro che il quello che va a comandare i servi.
Mi viene il dubbio e chiedo una conferma a voi che il radiocomando invii il segnale solo quando ci sono delle variazioni sui valori
(movimento stick) mentre quando non ci sono variazioni, non invia nulla o invia solo un segnale di conferma che secondo me
potrebbe essere un segnale alto che dura 22.1ms + una pausa di 0.4ms.
Questo purtroppo non saprei come misurarlo perchè dovrei avere la possibilità di vedere effettivamente cosa esce in antenna ma
non ho strumenti per poterlo fare.
Qualcuno di voi conosce meglio di me il sistema di trasmissione dei radiocomandi?
Grazie.
Ciao.

no, il segnale arriva uguale e viene sempre ripetuto. Se sei sicuro che tenendo gli stick fermi i segnali sono IDENTICI allora il problema potrebbe essere l'amperaggio insufficiente.

lesto:
no, il segnale arriva uguale e viene sempre ripetuto. Se sei sicuro che tenendo gli stick fermi i segnali sono IDENTICI allora il problema potrebbe essere l'amperaggio insufficiente.

Ma tu parli di amperaggio sulla ricevente o sulla trasmittente?
Sulla ricevente non può essere, perchè è la stessa fonte di alimentazione che ho usato anche per fare il test direttamente con la radio (batteria lipo 3s+bec).
Nella trasmittente nemmeno perchè uso una batteria al piombo a 12V (ovviamente carica).
Un dubbio che mi è venuto questa sera è che magari il segnale che butta fuori arduino è troppo attenuato rispetto alle esigenze del modulo FRSKY.
Per caso sai di quanto necessita nell'ingresso segnale il modulo FRSKY.
Nei foglietti che ho in dotazioni non ho trovato dati di questo tipo, però domani provo a vedere se nel loro sito c'è scritto qualcosa.
Grazie.
Ciao.

Lesto che LITRAGGIO ha il tuo serbatoio? XD XD XD

Stefanoxjx:
Mi viene il dubbio e chiedo una conferma a voi che il radiocomando invii il segnale solo quando ci sono delle variazioni sui valori
(movimento stick) mentre quando non ci sono variazioni, non invia nulla o invia solo un segnale di conferma che secondo me
potrebbe essere un segnale alto che dura 22.1ms + una pausa di 0.4ms.

Il segnale viene trasmesso di continuo, il tremolio dei servi vuol dire che il tuo segnale non è stabile nel tempo, ovvero non vengono generate sequenze di impulsi perfettamente identiche a parità di condizioni.
Come generi il ppm e in base a cosa vari le durate dei singoli impulsi ?

Sorry for the english, but if you guys are still looking to output PPM signals, I have a low level library which does this.

Its a variation of the code here - RCArduino: Arduino Serial Servos, much faster than using digitalwrite and delay.

The clock signal is basically PPM, the variation allows you to set the number of channels and removes the reset pulse.

Duane B

rcarduino.blogspot.com

astrobeed:

Stefanoxjx:
Mi viene il dubbio e chiedo una conferma a voi che il radiocomando invii il segnale solo quando ci sono delle variazioni sui valori
(movimento stick) mentre quando non ci sono variazioni, non invia nulla o invia solo un segnale di conferma che secondo me
potrebbe essere un segnale alto che dura 22.1ms + una pausa di 0.4ms.

Il segnale viene trasmesso di continuo, il tremolio dei servi vuol dire che il tuo segnale non è stabile nel tempo, ovvero non vengono generate sequenze di impulsi perfettamente identiche a parità di condizioni.
Come generi il ppm e in base a cosa vari le durate dei singoli impulsi ?

Eccomi, scusate il ritardo nella risposta ma nel frattempo ho provato a vedere se ne capivo qualcosa di più e riuscivo a cavarmela da solo............. ovviamente non ci sono riuscito :frowning:
Questo è lo sketch che genera il segnale PPM:

#define  Durata	        22000
#define  Pausa          400
#define  PPMPin         8  


void setup()
{                
  Serial.begin(9600);
  pinMode(PPMPin, OUTPUT);     
}


void loop()
{
  int  ch[8] = {720, 1120, 1120, 1120, 1120, 1120, 1120, 1120};
  long timeframe;
  timeframe=0;

  //1
  digitalWrite(PPMPin, HIGH);
  delayMicroseconds(ch[0]);
  digitalWrite(PPMPin, LOW);
  delayMicroseconds(Pausa);
  timeframe=timeframe+ch[0]+Pausa;
  
  //2
  digitalWrite(PPMPin, HIGH);
  delayMicroseconds(ch[1]);
  digitalWrite(PPMPin, LOW);
  delayMicroseconds(Pausa);
  timeframe=timeframe+ch[1]+Pausa;
  
  //3
  digitalWrite(PPMPin, HIGH);
  delayMicroseconds(ch[2]);
  digitalWrite(PPMPin, LOW);
  delayMicroseconds(Pausa);
  timeframe=timeframe+ch[2]+Pausa;

  //4
  digitalWrite(PPMPin, HIGH);
  delayMicroseconds(ch[3]);
  digitalWrite(PPMPin, LOW);
  delayMicroseconds(Pausa);
  timeframe=timeframe+ch[3]+Pausa;

  //5
  digitalWrite(PPMPin, HIGH);
  delayMicroseconds(ch[4]);
  digitalWrite(PPMPin, LOW);
  delayMicroseconds(Pausa);
  timeframe=timeframe+ch[4]+Pausa;
  
  //6
  digitalWrite(PPMPin, HIGH);
  delayMicroseconds(ch[5]);
  digitalWrite(PPMPin, LOW);
  delayMicroseconds(Pausa);
  timeframe=timeframe+ch[5]+Pausa;

  //7
  digitalWrite(PPMPin, HIGH);
  delayMicroseconds(ch[6]);
  digitalWrite(PPMPin, LOW);
  delayMicroseconds(Pausa);
  timeframe=timeframe+ch[6]+Pausa;

  //8
  digitalWrite(PPMPin, HIGH);
  delayMicroseconds(ch[7]);
  digitalWrite(PPMPin, LOW);
  delayMicroseconds(Pausa);
  timeframe=timeframe+ch[7]+Pausa;


  //Completa il frame 20ms
  digitalWrite(PPMPin, HIGH);
  delayMicroseconds(Durata -timeframe);
  digitalWrite(PPMPin, LOW);
  delayMicroseconds(Pausa);
}

Questo sketch genera un segnale PPM che dovrebbe lasciare tutti i servocomandi fermi nella posizione impostata.
Provando a commentare le righe inerenti a tutti i canali e lasciando solo quella del primo canale, con l'oscilloscopio ho effettivamente notato una cosa che
non riuscivo a vedere analizzando l'onda di tutti gli 8 canali.
Il segnale non è precisissimo, ha delle piccole oscillazioni che sono effettivamente quelle che generano il tremolio dei servocomandi.
Nel frattempo ho fatto qualche ricerca per capire se magari dipendesse dal fatto che la serie di istruzioni faceva perdere del tempo prezioso di elaborazione
ma non credo sia quello il problema.
Infatti ho provato a scrivere un piccolo sketch che genera un'onda quadra direttamente tramite il timer ma anche con questo vedo che la lettura non è sempre
uguale, ci sono delle piccole variazioni:

void  setup()
{
  pinMode(3, OUTPUT);
  pinMode(11, OUTPUT);
  TCCR2A = _BV (COM2A1) | _BV (COM2B1) |_BV (WGM21) | _BV (WGM20);
  TCCR2B = _BV (CS22);
  OCR2A = 200;
  OCR2B = 100;
}
 
void  loop()
{}

Quindi a questo punto la domanda è: qual'è il trucco per avere un segnale pulito e stabile?
Grazie dell'aiuto.
Ciao.

DuaneB:
Sorry for the english, but if you guys are still looking to output PPM signals, I have a low level library which does this.

Its a variation of the code here - RCArduino: Arduino Serial Servos, much faster than using digitalwrite and delay.

The clock signal is basically PPM, the variation allows you to set the number of channels and removes the reset pulse.

Duane B

rcarduino.blogspot.com

Thanks for your help.
I will study it as soon as possible :slight_smile:
Bye.

Stefanoxjx:
Eccomi, scusate il ritardo nella risposta ma nel frattempo ho provato a vedere se ne capivo qualcosa di più e riuscivo a cavarmela da solo............. ovviamente non ci sono riuscito :frowning:

Se non mi ricordo male la delayMicroseconds() non è molto precisa come ripetibilità dei tempi, ovvero soffre di jitter, dopo pranzo provo il tuo sketch e ti dico di quanto oscillano esattamente i vari impulsi (misura con DSO) e vediamo come fare per risolvere il problema.

astrobeed:

Stefanoxjx:
Eccomi, scusate il ritardo nella risposta ma nel frattempo ho provato a vedere se ne capivo qualcosa di più e riuscivo a cavarmela da solo............. ovviamente non ci sono riuscito :frowning:

Se non mi ricordo male la delayMicroseconds() non è molto precisa come ripetibilità dei tempi, ovvero soffre di jitter, dopo pranzo provo il tuo sketch e ti dico di quanto oscillano esattamente i vari impulsi (misura con DSO) e vediamo come fare per risolvere il problema.

Grazie :slight_smile:

Ho fatto un primo test col tuo sketch e ti confermo quanto avevo sospettato, e tu che tu avevi già visto con l'oscilloscopio, i segnali dei servo soffrono tutti di un jitter compreso tra 5 e 20 us e questo causa il tremolio dei servo che lavorano in continuazione per aggiornare la posizione.
Per me la soluzione può essere solo una, prima di tutto eliminare la digitalwrite che è lentissima di suo e poi usare direttamente un timer per le temporizzazioni invece della delaymicroseconds che per questo genere di applicazioni non è abbastanza precisa/stabile.
Adesso faccio una modifica al volo allo sketch per renderlo preciso e tra non molto te lo posto.