Progetti

   

Sponsor

   

Servizi

   

Sponsor OurPCB  

   
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 11 Mesi fa #1

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

File allegato:

Nome del file: pilotare2s...imer.rar
Dimensione del file:61 KB

buongiorno a tutti

Questo nuovo quesito nasce perche ho utilizzato un valido programma scritto da Marcello Pinna che si trova a questo link che si chiama Pinna: 2 servo, 2 potenziometri devo dire a tale proposito che oltre a essere geniale funziona benissimo.

Il problema è che la base dei tempi per un servo è di 20ms mentre per il secondo servo è di 40ms.
Finche si utilizzano 2 servo non ci sono problemi ma quando i servo aumentano 3 o 4 non sempre rispondono in maniera pronta e reattiva il che per il mio progetto è un problema.

Oh pensato perciò di utizzare il TIMER0 per i 20ms e i TIMER1 E TIMER3 per l'onda quadra di 2500 micrS. Un timer per ogni servo.

Per chiarezza divido il codice in tre settori
#define BITMASK 0b11000011    //maschera per il bitshift dei canali
 
#define SERVO_0 PORTD.B0      //il servo0 lo collego alla porta RD0
 
#define SERVO_1 PORTD.B1      //il servo0 lo collego alla porta RD1
 
 
 
 
[code]
[/code]

void interrupt  (void)
 {
if (INTCON.TMR0IF)          //intercetto l'iterrupt del TIMER0
{ 
 SERVO_0 =1;               // metto a 1 l'uscita dei servo
 SERVO_1 =1;
 
 TMR0H= 0B00111100;       //ricarico il TIMER0 per la temporizzazione
 TMR0L= 0B10110000;       //dei 20ms
 
  T1CON.TMR1ON = 1;      //abilito il TIMER1
  timer1 = (unsigned int)(65536 - (pulse[0] * 5));  //Serie di passaggi per creare
  timer1_high = timer1 >> 8;                        //Serie di passaggi per creare//l'onda quadra 500ms - 2500ms
  timer1_low = timer1 & 0xFF;
  TMR1H = timer1_high;
  TMR1L = timer1_low;
 
  T3CON.TMR3ON = 1;        //abilito il TIMER3
  timer3 = (unsigned int)(65536 - (pulse[1]  * 5));   //Serie di passaggi per creare
  timer3_high = timer3 >> 8;                          //Serie di passaggi per creare
  timer3_low = timer3 & 0xFF;
  TMR3H = timer3_high;
  TMR3L = timer3_low;
 
INTCON.TMR0IF=0;          //azzero il flag di interruzzione del TIMER0
}
 
if(PIR1.TMR1IF  ){        //intercetto l'iterrupt del TIMER1
 
SERVO_0 = 0;              //mando a 0 uscita SERVO_O
T1CON.TMR1ON = 0;         //disabilito il TIMER1
PIR1.TMR1IF = 0;          //azzero il flag di interruzzione del TIMER1
}
 
if (PIR2.TMR3IF){          //azzero il flag di interruzzione del TIMER3
 
SERVO_1 = 0;               //mando a 0 uscita SERVO_1
T3CON.TMR3ON = 0;          //disabilito il TIMER3
PIR2.TMR3IF = 0;           //azzero il flag di interruzzione del TIMER3
}
}
while(1)
 
{
  sommatoria[channel] = 0;
 
 
          for (i=0; i<8; i++){
              ADCON0.GO = 1;
 
              while (ADCON0.GO);
              valore_ADC[channel]= (((int)ADRESH)<<8) | ADRESL;
 
              sommatoria[channel] = sommatoria[channel]+ valore_ADC[channel];
              }
 
              sommatoria[channel] = sommatoria[channel]>>3;
 
              pulse[channel] =(sommatoria[channel] * 1955 ) + 500 ;
 
              channel++;
 
              if (channel == 2){
              channel = 0;
              }
              ADCON0 &= BITMASK;
              ADCON0 |= ((channel)<<2);
 
}
}


il codice prende spunto da quello di PINNA solo che non funziona tanto bene l'onde quadre sono molto instabili e non vengono rispettati per niente i 2500micrS

allego il file completo che è scritto MikroC

ringrazio anticipatamente ogni forma di aiuto.

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

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

  • Pinna
  • Avatar di Pinna
  • Offline
  • Moderatore
  • Messaggi: 1008
  • Ringraziamenti ricevuti 107
  • Karma: 8
Caio Massimo, solo ora ho potuto dare un'occhiata al tuo programma (sto correggendo qualche cosa non corretta sull'articolo
riguardante il modulo nrf24l01)..... senti, la prima cosa che ho visto, non conosco mikroC, è che nei define hai scritto PORTD.B0 e PORTD.B1.. mi chiedo, è giusto ciò che hai scritto oppure si tratta di un errore di battitura dove invece va scritto PORTD.D0 e PORTD.D1? se vuoi chiamami e ne parliamo tra noi al telefono :)

Marcello
Chi vola vale, chi vale vola, chi non vola è un vile
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

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

  • mpeino
  • Avatar di mpeino
  • Offline
  • Gold Boarder
  • Messaggi: 174
  • Ringraziamenti ricevuti 2
  • Karma: 0
PORTD.B0 e PORTD.B1 significa pin0 e pin1 della PORTD per il resto non cambia molto con il compilatore della microchip.

ciao e grazie Marcello
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

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

  • Mauro Laurenti
  • Avatar di Mauro Laurenti
  • Offline
  • Moderatore
  • Messaggi: 4682
  • Ringraziamenti ricevuti 561
  • Karma: 52
Salve Massimo,

potresti specificare il quarzo di cui fai uso?
Dal momento che parli di tempi degli impulsi presumo che tu abbia fatto delle misure con un oscilloscopio.
Hai modo di postare degli screen shot?

Da uno sguardo veloce, per ora ti posso dire che in generale il timer lo devi attivare dopo che viene impostato altrimenti perdi dei "colpi".

Formalmente se imposti tutti i timer ogni 20ms vuol dire che il tuo periodo totale è 20ms + il tempo che impieghi per le impostazioni.

Dovendo gestire più servi e tempi ridotti organizzerei il programma in maniera diversa, in particolare facendo uso delle state machine, ovvero eseguo il codice nel main e negli interrupt (ISR) cambio solo il valore di stato.
A seconda dello stato della state machine nel main eseguo un codice diverso.

Personalmente userei un timer per una base dei tempi che mi permetta di ottenere 20ms.
Magari con tempi da 10ms, e un secondo timer per orchestrare i servo.

Potrebbe tornare utile un tempo di 10ms * 2 in maniera da fare le impostazioni durante i tempi morti e non dopo i 20ms.

Quali sono le specifiche del tuo sistema?
Quanti servi?
Quanti potenziometri? (mi aspetto 1:1 con servi.)


Saluti,

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

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

  • Pinna
  • Avatar di Pinna
  • Offline
  • Moderatore
  • Messaggi: 1008
  • Ringraziamenti ricevuti 107
  • Karma: 8
Massimo, io non so più come dirtelo...... quello che leggi nell'oscilloscopio è una somma dei tempi totali di tutti i servi, non il tempo per ogni singolo servo.... se nel programma imposti un timer qualunque per darti 20 ms, sempre 20 ms ti darà, perchè il calcolo del tempo, dopo l''azzeramento dello stesso, prevede quello; il timer è impostato così e non fa ciò che vuole lui..... scusa, ma se tu dovessi usare 16 servi useresti un pic che ha 17 timers? a parte che non esistono, ma ti pare logico? io, come tutti, uso due timer, uno per i 20 ms e l'altro per regolare l'ampiezza del segnale pwm tramite adc... ogni canale adc lo scansiono uno per volta effettuando uno shift.... insomma, te lo ha detto Gianni, te lo detto io, forse in modo velato te lo ha detto anche Mauro e tu ancora ti ostini? vuoi per caso riscoprire l'aqcua calda????? Detto questo, ti abbraccio perchè sei veramente una bellissima persona, a cui mi sono affezionato, nonostante ti abbia conosciuto in una sola occasione, quella del MF2014.... ma dai, prenditi un giorno, vieni a roma a trovarmi e ti dimostreò che ti sbagli..... e dopo andiamo a mangiare un'ottima pinsa (non pizza) a 100 metri da casa mia, chiaramente ospite mio :) :) :)

dimenticavo..... tua famiglia compresa :) :) :)
Chi vola vale, chi vale vola, chi non vola è un vile
Ultima modifica: 3 Anni 11 Mesi fa da Pinna.
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.
Powered by Forum Kunena
   
© LaurTec 2006-2021