Torna indietro   BaroneRosso.it - Forum Modellismo > Elettronica > Circuiti Elettronici


Rispondi
 
Strumenti discussione Visualizzazione
Vecchio 01 dicembre 13, 13:19   #11 (permalink)  Top
Adv Moderator
 
L'avatar di romoloman
 
Data registr.: 15-08-2007
Residenza: sto a Massa ma sono molto Positivo
Messaggi: 12.071
Il tuo codice lo vedo molto critico dal punto di vista del segnale generato, cerco di spiegarti il perché:
Codice:
void setup(){
    pinMode(throttleInput,INPUT);
    auxServo.attach(auxOutput);
    auxServo.write(0);    //inizializzo il valore del canale aux su BASSO
}
a mio giudizio manca un

Codice:
    pinMode(auxOutput,OUTPUT);
quindi
Codice:
void setup(){
    pinMode(throttleInput,INPUT);
    pinMode(auxOutput,OUTPUT);
    auxServo.attach(auxOutput);
    auxServo.write(0);    //inizializzo il valore del canale aux su BASSO
}

continuando....
il seguente codice:
Codice:
//Acquisisco il valore del throttle
throttleVal = pulseIn(throttleInput,HIGH,25000);
Aspetta fino a 25000 microsecondi (25 ms) in attesa di trovare un segnale valido, se non lo trova ritorna 0. Il problema è che ciò rende instabile la generazione del segnale successivo, ma soprattutto rende la generazione del fronte di salita dell'uscita dipendente dal segnale in ingresso.
ovvero il segnale di uscita non verrà generato fino a che, o l'impulso viene rilevato, o avviene un timeout.
Andiamo avanti con l'analisi degli orrori :

Codice:
    //controllo il valore del throttle
    if(throttleVal <= 0){     //se il valore del throttle è andato a zero attivo il "failsafe"
minore o uguale di 0 ??? La condizione < 0 non sarà mai vera.... al massimo == 0
comunque questo non inficia il funzionamento ma è solo un questione di pulizia del codice.
Tuttavia non confronterei mai con 0, stai aspettando un segnale che deve avere un ampiezza compresa fra 1000 e 2000us.... perché rischiare di prendere delle spurie da pochi uSec come segnale valido ?

Codice:
        auxServo.write(179);  //"invio" un segnale ALTO
        delay(15);
    }
e invece nel caso il trhottle ci sia non viene generato segnale ??? (secondo me qui manca un else e c'è qualcosa di troppo, vedi in seguito)
Codice:
        auxServo.write(179);  //"invio" un segnale ALTO
    }  else {
        auxServo.write(0);  //"invio" un segnale BASSO
    }
comunque facciamo l'esempio che il segnale non ci sia e facciamo un analisi dei tempi...
pulseIn aspetta 25ms... ritorna 0..
auxServo.write() genera un impulso di 2ms
delay aspetta 15ms
in totale il tuo impulso viene generato ogni 42 ms...secondo me sono un po' troppi. forse allora togliendo il delay almeno lo avresti generato ogni 27ms e le cose andrebbero meglio.
Nel caso l'impulso sia presente con il tuo codice (tolto il delay e inserito l'else) invece avverrebbe la cosa seguente:
chiamiamo Ton il tempo in cui l'impulso di ingresso va alto:
Tduty la larghezza dell'impulso in ingresso
Ttot il periodo del ppm in ingresso (tipicamente 18ms)
servoin aspetta l'impulso T0=Ton
al tempo Ton+Tduty (variabile e dipendente dall'impulso in ingresso) auxServo.write() genera un impulso di larghezza 1000uSec e ritorna al ciclo successivo di pulseIn
A questo punto pulseIn aspetterà Ttot-1000usec-Tduty che si ripresenti l'impulso successivo.
essendo Tduty variabile è evidente che l'impulso generato da auxServo.write() avrà un jitter dipendente dalle variazioni dell'ingresso... E' vero che all'elettronica che legge l'impulso probabilmente non gliene frega nulla, ma è concettualmente sbagliato.
La generazione del PPM deve essere fatta in un interrupt che setta l'uscita, regola il timer per la chiamata successiva dopo i ms di ampiezza dell'impulso, la chiamata successiva resetta l'uscita e imposta il timeout dell'interrupt successivo a 22.5-(larghezza impulso) ms
(quello che correttamente viene fatto nella ISR(TIMER1_COMPA_vect) del codice da te postato.
nel tuo caso andrebbe fatto per un solo canale e non per tutti quelli dello stream PPM:

Spero di essere stato sufficientemente chiaro,
cordiali saluti
__________________
Vivere in qeusto mondo e molto belo belo e vale la pena starci ma a volte in questa UNICA vita che ci apartiene posono succedere cose brute brute alora mi chiedo perche siete incazziati domani pole esere anche lultimo
Grazie "TRANQUILLO"
FAI 15766

Ultima modifica di romoloman : 01 dicembre 13 alle ore 16:35
romoloman non è collegato   Rispondi citando
Vecchio 03 dicembre 13, 19:56   #12 (permalink)  Top
User
 
L'avatar di faustog_2
 
Data registr.: 19-07-2008
Residenza: catania
Messaggi: 978
???

sarà l'età.. o forse mi sono un pò arruginito ! o force troppi Acronimi FC, RX, AUX1 ecc vorrei capire meglio..

..dunque la scheda MultiWii dotata d acellerometri e giroscopi.. dunque è in grado di rilevare ogni movimento possibile.. con una sensibilità dignitosa.. per quello che ho capito ..tu vorresti in un canale della tua ricevente.. attivare o meno il controllo della MultiWii.. ..dunque essa provvederà a stabilizzare il modello attraverso arduino, che leggendo i valori digitali dell'orizzonte e delle sbandate... riesce a correggere attraverso un opportuno movimento dei servi...

ovviamente i servo si muoveranno sempre attraverso i tuoi comandi.. ma nel caso non muovessi gli stick.. , quindi se non rileva variazioni dalla RX montata sul velivolo e inoltre il ch 6 è in modalità fail save... allora solo in questo caso intraprende le azioni che impartisce arduino..

..dimmi se ho capito bene intanto oppure non ho capito una mazza!


Citazione:
Originalmente inviato da baccothe Visualizza messaggio
Dunque, ho un arduino nano e stavo pensando di utilizzarlo per implementare una procedura di failsafe.

L'idea è questa:

1)collego un canale aux della rx(Turnigy 8ch) ad un pin di arduino, supponiamo il pin 6.

2)collego un pin di arduino,supponiamo il pin 7 al canale (per esempio)AUX1 della FC, in questo caso una MultiWii.

3)Sulla MultiWii abbino l' RTH al canale AUX1, supponiamo RTH ON su un valore ALTO, RTH OFF su un valore BASSO.

4)vado a leggere tramite la funzione pulseIn() il valore della rx sul pin 6, ed eseguo un controllo:

4.1)se il valore è > 0, invio sul pin 7 un valore BASSO

4.2)altrimenti attivo il FailSafe, e invio un valore ALTO sul pin 7, attivando l' RTH.

Il problema è che non riesco ad inviare i valori ALTO/BASSO sul pin 7, ho provato importando la libreria servo.h e utilizzare la funzione servo.write(val) ma nisba...

Un piccolo pezzo del codice che ho utilizzato e che non funziona, ovvero quello per inviare un segnale da arduino alla MultiWii:

Codice:
#include <Servo.h> 

Servo myservo;

int auxPinOut = 7;

void setup() 
{ 
 
    myservo.attach(auxPinOut);
  
} 

void loop() {

    myservo.write(1900);

}
Qualche idea? Che ne dite? è un'idea folle? stupida? impraticabile?
faustog_2 non è collegato   Rispondi citando
Vecchio 04 dicembre 13, 20:32   #13 (permalink)  Top
User
 
L'avatar di baccothe
 
Data registr.: 10-12-2012
Residenza: roma
Messaggi: 430
Innanzi tutto grazie romoloman per essere stato così meticoloso

Alcuni punti mi sono chiari, altri un pò meno:

Citazione:
Codice:
Codice:
//Acquisisco il valore del throttle
throttleVal = pulseIn(throttleInput,HIGH,25000);
Aspetta fino a 25000 microsecondi (25 ms) in attesa di trovare un segnale valido, se non lo trova ritorna 0. Il problema è che ciò rende instabile la generazione del segnale successivo, ma soprattutto rende la generazione del fronte di salita dell'uscita dipendente dal segnale in ingresso.
ovvero il segnale di uscita non verrà generato fino a che, o l'impulso viene rilevato, o avviene un timeout.
Andiamo avanti con l'analisi degli orrori :
Aspettare un segnale valido in input e, nel caso questo non arrivi(perdita di segnale??)dopo tot tempo ritornare 0, non è proprio quello che dobbiamo fare? Mi stai consigliando di diminuire il tempo di timeout ? o di utilizzare un'altro sistema per leggere il segnale del throttle ?

Citazione:
Codice:
Codice:
    //controllo il valore del throttle
    if(throttleVal <= 0){     //se il valore del throttle è andato a zero attivo il "failsafe"
minore o uguale di 0 ??? La condizione < 0 non sarà mai vera.... al massimo == 0
comunque questo non inficia il funzionamento ma è solo un questione di pulizia del codice.
Tuttavia non confronterei mai con 0, stai aspettando un segnale che deve avere un ampiezza compresa fra 1000 e 2000us.... perché rischiare di prendere delle spurie da pochi uSec come segnale valido ?
Non ha alcun senso fare un confronto del tipo <= 0, d' accordissimo, poco elegante e inutile.

Quello che però non capisco è perché tu non confronteresti con 0, mi spiego, banalmente quello che ho fatto è stato leggere il valore dalla ricevente e con la trasmittente accesa leggo un valore compreso tra 1000 e 2000, che ovviamente si muove a seconda del movimento dello stick.

Nel momento in cui ho spento la trasmittente,simulando una perdita di segnale, questo valore è andato a 0.

In che altro modo posso intercettare un'assenza di segnale? se non confrontando questo valore con 0 ?

Per tutti gli altri punti che mi hai segnalato credo d'aver capito, grazie per la spiegazione.

Per quanto riguarda il fatto di usare le interrupt e il Timer credo di aver più o meno capito concettualmente quello che si va a fare, con le mie competenze attuali non sono in grado di implementare qualcosa,devo vedermi meglio come funzionano i Timer e i vari registri.

Se però il codice che ho postato è fatto bene perché non mi funziona?

Ho modificato così le define:

Codice:
//this programm will put out a PPM signal

//////////////////////CONFIGURATION///////////////////////////////
#define chanel_number 1  //set the number of chanels ->ho bisogno di controllare 1 solo canale

#define default_servo_value 1500  //set the default servo value
#define PPM_FrLen 1500  //set the PPM frame length in microseconds (1ms = 1000µs)
#define PPM_PulseLen 300  //set the pulse length
#define onState 1  //set polarity of the pulses: 1 is positive, 0 is negative
#define sigPin 6  //set PPM signal output pin on the arduino ->vorrei l'uscita ppm sul pin 6
//////////////////////////////////////////////////////////////////
Ma comunque continua a non funzionare, il valore che leggo sulla GUI di multiwii resta fisso, come se non ci fosse attaccato nulla.

L'unica cosa che ho notato, smanettando un po "a buffo", è che modificando il parametro #define onState e portandolo da 1 a 0, quello che succede è che il valore del canale su multiwii inizia a oscillare, arriva "lentamente" al massimo, e poi torna indietro,al minimo e così via.

Cosa mi manca ?

Citazione:
sarà l'età.. o forse mi sono un pò arruginito ! o force troppi Acronimi FC, RX, AUX1 ecc vorrei capire meglio..

..dunque la scheda MultiWii dotata d acellerometri e giroscopi.. dunque è in grado di rilevare ogni movimento possibile.. con una sensibilità dignitosa.. per quello che ho capito ..tu vorresti in un canale della tua ricevente.. attivare o meno il controllo della MultiWii.. ..dunque essa provvederà a stabilizzare il modello attraverso arduino, che leggendo i valori digitali dell'orizzonte e delle sbandate... riesce a correggere attraverso un opportuno movimento dei servi...

ovviamente i servo si muoveranno sempre attraverso i tuoi comandi.. ma nel caso non muovessi gli stick.. , quindi se non rileva variazioni dalla RX montata sul velivolo e inoltre il ch 6 è in modalità fail save... allora solo in questo caso intraprende le azioni che impartisce arduino..

..dimmi se ho capito bene intanto oppure non ho capito una mazza!
Quello che vorrei fare è molto più "semplice", non voglio controllare la stabilita del mozzo, voglio soltanto intercettare un'eventuale perdita di segnale della radio, e in questo caso inviare un segnale alla scheda di controllo che mi attivi una modalità di volo, per esempio un ritorno a casa.

Ho trovato in rete un software Multiwii modificato, che implementa questo genere di failsafe, ma andiamo OT, se riesco volevo proseguire con la mia idea.
baccothe non è collegato   Rispondi citando
Vecchio 04 dicembre 13, 20:48   #14 (permalink)  Top
User
 
L'avatar di baccothe
 
Data registr.: 10-12-2012
Residenza: roma
Messaggi: 430
Nel codice il parametro da modificare è #define PPM_PulseLen, ci sono arrivato per tentativi
baccothe non è collegato   Rispondi citando
Vecchio 04 dicembre 13, 22:27   #15 (permalink)  Top
Adv Moderator
 
L'avatar di romoloman
 
Data registr.: 15-08-2007
Residenza: sto a Massa ma sono molto Positivo
Messaggi: 12.071
Citazione:
Originalmente inviato da baccothe Visualizza messaggio
Nel codice il parametro da modificare è #define PPM_PulseLen, ci sono arrivato per tentativi
Il PPM_PulseLen defnisce il valore minimo dell'interframe, ovvero la distanza da un impulso all'altro.
300 è un valore abbastanza standard, ma magari l'interfaccia multiwii lo vuole più lungo (400+uSec)
tuttavia non ho capito ma ora ti funziona oppure no ?
__________________
Vivere in qeusto mondo e molto belo belo e vale la pena starci ma a volte in questa UNICA vita che ci apartiene posono succedere cose brute brute alora mi chiedo perche siete incazziati domani pole esere anche lultimo
Grazie "TRANQUILLO"
FAI 15766

Ultima modifica di romoloman : 04 dicembre 13 alle ore 22:52
romoloman non è collegato   Rispondi citando
Vecchio 04 dicembre 13, 22:57   #16 (permalink)  Top
User
 
L'avatar di baccothe
 
Data registr.: 10-12-2012
Residenza: roma
Messaggi: 430
Citazione:
Originalmente inviato da romoloman Visualizza messaggio
Il PPM_PulseLen defnisce il valore minimo dell'interframe, offero la distanza da un impulso all'altro.
300 è un valore abbastanza standard, ma magari l'interfaccia multiwii lo vuole più lungo (400+uSec)
tuttavia non ho capito ma ora ti funziona oppure no ?
Quel valore è esattamente il valore che esce in output, e che legge multiwii...

Impostando quel valore tra 1000 e 2000 multiwii lo legge tranquillamente...non so il perché ma è così

A quanto pare funziona, ora non sono al pc,domani posto il codice
baccothe non è collegato   Rispondi citando
Vecchio 06 dicembre 13, 18:25   #17 (permalink)  Top
User
 
L'avatar di tevere
 
Data registr.: 23-03-2013
Residenza: Roma
Messaggi: 456
ciao a tutti
baccothe scusa l'intromissione, scrivo qui perchè sempre di ppm si parla.

ho provato a cercare sul forum e anche su internet, ma non sono riuscito a trovare una funzione, sotto forma di libreria o anche codice scritto, che mi permetta di leggere un segnale ppm prelevato da una rx (FrSky Delta 8) e che mi restituisca i valori divisi canale per canale. esiste?

tevere

p.s. ho provato anche a guardare i software per multirotori, ma, a causa delle mie poche conoscenze in quest'ambito, non sono riuscito ad estrapolare nulla
__________________
vola...vola...volaaaaaaaaaaaaaaaaaaaaaaaaaa
tevere non è collegato   Rispondi citando
Vecchio 11 febbraio 14, 20:10   #18 (permalink)  Top
User
 
L'avatar di faustog_2
 
Data registr.: 19-07-2008
Residenza: catania
Messaggi: 978
Non è una cosa complicata!

tutto sommato non è complicato....

abbiamo il Timer1 che cresce a ritmo di mezzo microsecondo.. (prescaler 8) ovvero 500 nS (nano secondi) quando raggiunge il valore del periodo, si verifica un interrupt.... che viene catturato dalla funzione ISR( ecc...) ..dentro questa funzione viene azzerato il timer... viene eseguito il fronte di salita sul pin in causa... Adesso il compare dovrà osservare non più il periodo ma un altro registro l'OCR1A appena il Timer1 raggiunge questo valore avviene dinuovo un interrupt ma stavolta esegue il fronte di discesa STOP! fine della storia.. ovviamente i registri



Citazione:
Originalmente inviato da baccothe Visualizza messaggio
Sempre in rete ho trovato questo, ma...non riesco a capirlo

Codice:
//this programm will put out a PPM signal

//////////////////////CONFIGURATION///////////////////////////////
#define chanel_number 1  //set the number of chanels
#define default_servo_value 1500  //set the default servo value
#define PPM_FrLen 22500  //set the PPM frame length in microseconds (1ms = 1000µs)
#define PPM_PulseLen 300  //set the pulse length
#define onState 1  //set polarity of the pulses: 1 is positive, 0 is negative
#define sigPin 10  //set PPM signal output pin on the arduino
//////////////////////////////////////////////////////////////////


/*this array holds the servo values for the ppm signal
 change theese values in your code (usually servo values move between 1000 and 2000)*/
int ppm[chanel_number];

void setup(){  
  //initiallize default ppm values
  for(int i=0; i<chanel_number; i++){
    ppm[i]= default_servo_value;
  }

  pinMode(sigPin, OUTPUT);
  digitalWrite(sigPin, !onState);  //set the PPM signal pin to the default state (off)
  
  cli();
  TCCR1A = 0; // set entire TCCR1 register to 0
  TCCR1B = 0;
  
  OCR1A = 100;  // compare match register, change this
  TCCR1B |= (1 << WGM12);  // turn on CTC mode
  TCCR1B |= (1 << CS11);  // 8 prescaler: 0,5 microseconds at 16mhz
  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
  sei();
}

void loop(){
  //put main code here
  static int val = 1;
  
  ppm[0] = ppm[0] + val;
  if(ppm[0] >= 2000){ val = -1; }
  if(ppm[0] <= 1000){ val = 1; }
  delay(10);
}

ISR(TIMER1_COMPA_vect){  //leave this alone
  static boolean state = true;
  
  TCNT1 = 0;
  
  if(state) {  //start pulse
    digitalWrite(sigPin, onState);
    OCR1A = PPM_PulseLen * 2;
    state = false;
  }
  else{  //end pulse and calculate when to start the next pulse
    static byte cur_chan_numb;
    static unsigned int calc_rest;
  
    digitalWrite(sigPin, !onState);
    state = true;

    if(cur_chan_numb >= chanel_number){
      cur_chan_numb = 0;
      calc_rest = calc_rest + PPM_PulseLen;// 
      OCR1A = (PPM_FrLen - calc_rest) * 2;
      calc_rest = 0;
    }
    else{
      OCR1A = (ppm[cur_chan_numb] - PPM_PulseLen) * 2;
      calc_rest = calc_rest + ppm[cur_chan_numb];
      cur_chan_numb++;
    }     
  }
}
faustog_2 non è collegato   Rispondi citando
Rispondi

Bookmarks




Regole di scrittura
Non puoi creare nuove discussioni
Non puoi rispondere alle discussioni
Non puoi inserire allegati
Non puoi modificare i tuoi messaggi

BB code è Attivato
Le faccine sono Attivato
Il codice [IMG] è Attivato
Il codice HTML è Disattivato
Trackbacks è Disattivato
Pingbacks è Disattivato
Refbacks è Disattivato


Discussioni simili
Discussione Autore discussione Forum Commenti Ultimo Commento
aiuto con arduino e ppm alex-military Circuiti Elettronici 0 22 febbraio 13 14:52
Ricevitore di segnale PPM CarloRoma63 Radiocomandi 2 06 marzo 12 18:24
Installazione Frsky V8HT interno - Trovare il segnale ppm +e - sulla radio searchworlds Radiocomandi 4 22 maggio 11 23:18
GRAUPNER MX-16S 35 Mhz. PROBLEMI DI SEGNALE IN PPM rentwc Radiocomandi 2 30 marzo 10 00:41
trovare segnale ppm silviocross Radiocomandi 8 11 marzo 10 22:21



Tutti gli orari sono GMT +2. Adesso sono le 09:29.


Basato su: vBulletin versione 3.8.11
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
E' vietata la riproduzione, anche solo in parte, di contenuti e grafica. Copyright 1998/2019 - K-Bits P.I. 09395831002