Progetti

   

Tutorial

   

Servizi

   

Sponsor  

   
Benvenuto, Ospite
Nome utente: Password: Ricordami

ARGOMENTO: pilotare 2 servo con tre timer del pic18f4550

pilotare 2 servo con tre timer del pic18f4550 3 Anni 9 Mesi fa #11

  • mpeino
  • Avatar di mpeino
  • Offline
  • Gold Boarder
  • Messaggi: 174
  • Ringraziamenti ricevuti 2
  • Karma: 0

File allegato:

Nome del file: videoforme...ervo.rar
Dimensione del file:2,203 KB

Innanzitutto vorrei spiegarvi il mio progetto:
Sto cercando di costruirmi un radiocomando tipo quelli che si usano in aereomodellismo qualcuno potrebbe dirmi, con quello che costano conviene comprarselo, avete ragione ma questo per me è un hobby che altro non è che un buon esercizio per la mente. Il fatto è che se non ti poni un obbiettivo o progetto, leggendo un libro anche se è sempre a portata di mano non impari molto (mi riferisco al tuo libro Mauro)

Con questo progetto bisogna affrontare un problema RF che grazie ai NRF24L01 E A Marcello ho risolto bisogna lavorare con la periferica SPI e lavorare con i timer per pilotare i servo quindi ce ne sono di cose per esercitare la mente .

Mauro Laurenti ha scritto:
Salve Massimo,

l'utilizzo di un timer per servo non è errato ma usi più risorse del necessario.
Se dovessi avere solo due Servo potrebbe andare bene ed effettivamente il codice potrebbe essere più semplice da scrivere e leggere.

Se i servo aumentano però ti imbatti presto contro il limite dei timer che potrebbero non essere essere sufficienti (numericamente).

ho provato il programma scaricato da qui con un servo quest'ultimo si muove in maniera scorrevole con due gia la scorrevolezza si perde.

devo collegare 3 o 4 servi per me è piu importante l'affidabilità del servo che il dispendio risorse so gia dovro fare le prove co un pic con 4 timer a 16 bit per 3 servo (5 per 4 servo)

Per State machine (macchina a stati) intendo che le varie operazioni vengono a dipendere da una variabile di stato.

Per esempio per accendere una lampada lo potresti fare direttamente all'interno dell'ISR (Interrupt Service Routine) oppure cambi il valore ad una variabile e assegni il valore 1 (per acceso...o altro).
Nel main controlli in un loop la variabile di stato e quando la trovi ad 1 accendi la luce.
In questo modo le ISR sono molto corte visto che cambi solo il valore della variabile di stato.

Quando il timer continua a contare, nel main, hai tutto il tempo di gestire il nuovo stato.

In questo modo si riesce a snellire il software e in generale gestire più eventi.

Nel libro XC8 Step By Step che trovi nella sezione Libri, trovi diversi esempi che fanno uso di una variabile di stato.
Gli esempi sono negli ultimi capitoli visto che si richiede un poco di dimestichezza.

Saluti,

Mauro

questa e una strada che non avevo considerato devo rivedere un po tutto

ho allegato un piccolo video con le forma d'onda generate dal programma come potete vedere sono piu larghe di 2500us e sono molto instabili e come se il timer viene caricato da valore dell' adc ogni volta si gira un potenziometro ( bo forse ho detto una stupidagine)

Massimo
Ultima modifica: 3 Anni 9 Mesi fa da mpeino.
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

pilotare 2 servo con tre timer del pic18f4550 3 Anni 9 Mesi fa #12

  • mpeino
  • Avatar di mpeino
  • Offline
  • Gold Boarder
  • Messaggi: 174
  • Ringraziamenti ricevuti 2
  • Karma: 0
Pinna ha scritto:
questa è un'idea che mi è venuta in mente, invece di fare la scansione di ogni adc sequenzialmente usando lo shift, potresti avviare e chiudere la lettura per ogni canale, uno dietro l'altro..... mi spiego meglio: avvii la lettura sul canale 1, dopo che hai letto chiudi l'adc..... avvii la lettura sul canale 2, dopo che hai letto chiudi l'adc.... e così via.....
Marcello

Usando una variabile di stato questa è la soluzione che vado a sperimentare..

Grazie

Massimo
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

pilotare 2 servo con tre timer del pic18f4550 3 Anni 9 Mesi fa #13

  • Mauro Laurenti
  • Avatar di Mauro Laurenti
  • Offline
  • Moderatore
  • Messaggi: 4677
  • Ringraziamenti ricevuti 561
  • Karma: 52
Effettivamente dal video i segnali non sembrano stabili.
Credo che i tempi degli interrupt siano influenzati da altri processi o eventualmente da altre interruzioni.

Facendo uso di una macchina a stati generalmente riesci a districarti.

Tra i progetti di riferimento del testo, quelli di fine capitolo, ho fatto un esempio di gestione a macchina a stati in cui facevo uso del timer e dell'ADC. Ora non ricordo bene l'esempio ma dovrebbe essere chiaro il funzionamento della macchina a stati.

Saluti,

Mauro
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

pilotare 2 servo con tre timer del pic18f4550 3 Anni 9 Mesi fa #14

  • mpeino
  • Avatar di mpeino
  • Offline
  • Gold Boarder
  • Messaggi: 174
  • Ringraziamenti ricevuti 2
  • Karma: 0
probabilmente ho risolto il problema con questi metodi i servo si muovono in maniera lineare

1 metodo:
while(1) {
                 delay_ms (20);
                   servo_0();
                   servo_1();
                   servo_2();

in questo modo sfrutto tutti i timer a 16 bit .
Ecco la singola funzione:
void servo_0(void){
unsigned int timer0;
unsigned int timer0_high = 0;
unsigned int timer0_low = 0;
unsigned int sommatoria0 = 0;
unsigned int valore_ADC0 = 0;
unsigned int pulse0 = 0;
char i;
    ADCON0 = 0b00000000;
 
    ADCON0bits.ADON = 0x01;
                 sommatoria0 = 0;
                for (i = 0; i < 8; i++) {
 
                        ADCON0bits.GO = 1;
 
                       while(ADCON0bits.GO);
 
                       valore_ADC0 = (((int) ADRESH) << 8) | ADRESL;
 
                       sommatoria0 = sommatoria0 + valore_ADC0;
                }
        sommatoria0 = sommatoria0 >> 3;
        pulse0 = (sommatoria0 * 1.955) +500;
        timer0 = (unsigned int)(65536 - (pulse0 * FACTOR));
        timer0_high = timer0 >> 8;
        timer0_low = timer0 & 0xFF;
 
        TMR0H = timer0_high;
        TMR0L = timer0_low;
 
    T0CONbits.TMR0ON = 1;
    SERVO_0 =1;
  }

con il secondo metodo sfrutto il timer0 per i 20ms e credo una variabile per la macchina a stati presente nella funzione interrupt

allego i 2 file

Massimo
Allegati:
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

pilotare 2 servo con tre timer del pic18f4550 3 Anni 9 Mesi fa #15

  • Mauro Laurenti
  • Avatar di Mauro Laurenti
  • Offline
  • Moderatore
  • Messaggi: 4677
  • Ringraziamenti ricevuti 561
  • Karma: 52
Bene, vedo che stai usando MPLAB X...

In effetti hai usato la macchina a stati e reso l'ISR più snella.
Dal momento però che proponi la soluzione con incertezza credo che non ne stai ancora vedendo i vantaggi.

Hai dedicato un timer per servo, per cui potresti andare ancora al livello superiore di complessità e usare un timer per due servo.

Per l'ADC, creerei anche una routine e macchina a stati dedicata.
Per esempio ogni 10ms avvi una lettura ADC in maniera ciclica. Abilita gli interrupt anche per l'ADC.
Salvi il valore della lettura in una variabile per ogni servo. Poi dentro la funzione servo_x usi la variabile per controllare/impostare il timer.

Saluti,

Mauro
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.
Powered by Forum Kunena
   
© LaurTec 2006-2015