Frequenzimetro con pic18

  • Mauro Laurenti
  • Moderatore
  • Moderatore
Di più
10 Anni 10 Mesi fa - 10 Anni 10 Mesi fa #6 da Mauro Laurenti
Risposta da Mauro Laurenti al topic Frequenzimetro con pic18
Ciao,

se hai un periodo finestra di 1Hz, considera che un Hz di errore lo hai sempre.
Per cui abbassando la frequenza in ingresso l´errore percentuale sulla misura e´ piu´ grande.

1Hz su 10Hz e´ il 10% mentre su 100Hz e´ 1%.

Oltre che a dover calibrare il clock del PIC sarebbe interessante sapere qual´e´ la tua sorgente e come stabilisci la sua frequenza
...l´errore totale e´ data dalla somma del tuo sistema e quello della sorgente.

In questi casi e´ bene avere delle sorgenti "ottime", magari con poche frequenza di riferimento.

Come detto da Gabriele, controlla anche gli aspetti software affinché non siano creati ritardi e perdite di tempo durante la misura.

Saluti,

Mauro
Ultima Modifica 10 Anni 10 Mesi fa da Mauro Laurenti.

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • paoletto
  • Autore della discussione
  • Elit Utente
  • Elit Utente
Di più
10 Anni 10 Mesi fa #7 da paoletto
Risposta da paoletto al topic Frequenzimetro con pic18
Ciao Mauro, quindi mi stai dicendo che si può migliorare la misura non contando le occorrenze dei fronti di salita in un secondo ma bensì in mezzo secondo, un quarto, un ottavo di secondo e così via?

Se è così però non sono daccordo, semmai devo aumentare la finestra, non diminuirla, non so se mi spiego.
Cioè perdere 10 istruzioni macchina su un conteggio di 1 secondo è molto meno grave che perderne lo stesso su un conteggio di un ottavo di secondo, l'incertezza diminuisce o sbaglio?
Però forse ho capito cosa vuoi dire, cioè realizzare ritardi lunghi è molto meno preciso che realizzarne di piccoli?

Per quanto riguarda l'aspetto SW si potrebbe già migliorare la cosa se non dovessi far ripartire il timer0 ogni volta: non capisco perchè la scrittura della funzione WriteTimer0(int) non ha praticamente effetto se la scrivo dopo aver impostato i Timers nel main, ma funziona solo all'interno della ISR!
In effetti a me non serve farlo ripartire di volta in volta nuovamente, devo solo impostarlo ad un certo valore per ottenere il ritardo desiderato.

La strumentazione a mia disposizione non è un granchè, ho la MyDAQ ed un generatore di segnali un po vetusto ma funzionante con display a 7 segmenti al max 2 cifre dopo la virgola per visualizzare la frequenza e quindi ti lascio immaginare l'accuracy sulla lettura :blink: ma ora che ci penso dovrei avere un oscilloscopio analogico da qualche parte, un cascione enorme..
Vedo cosa posso fare..al max vado in labo e chiedo di mettermi a disposizione un po di strumenti.

Intanto cerco di usare il modulo capture che mi sembra la soluzione migliore in assoluto.

Saluti
Paoletto.

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • Mauro Laurenti
  • Moderatore
  • Moderatore
Di più
10 Anni 10 Mesi fa #8 da Mauro Laurenti
Risposta da Mauro Laurenti al topic Frequenzimetro con pic18
Da quello che dici sospetto che una parte dell´errore sia proprio dalla tua sorgente.

riguardo alla finestra temporale, per migliorare devi renderla piu´ grande e non piu´ piccola.
...sarebbe la legge dell´integrazione.
...maggiore e´ il tempo di misura e migliore e´ la risoluzione che riesci ad ottenere.

Un oscilloscopio ti aiuta a tarare il clock principale, ma se riesci a mettere mani su un frequency counter e´ meglio.

Saluti,

Mauro

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • paoletto
  • Autore della discussione
  • Elit Utente
  • Elit Utente
Di più
10 Anni 10 Mesi fa #9 da paoletto
Risposta da paoletto al topic Frequenzimetro con pic18
Ah ecco, volevo ben dire, quindi devo avere un ritardo maggiore :silly: , vedo cosa posso inventarmi. :cheer:

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • paoletto
  • Autore della discussione
  • Elit Utente
  • Elit Utente
Di più
10 Anni 10 Mesi fa - 10 Anni 10 Mesi fa #10 da paoletto
Risposta da paoletto al topic Frequenzimetro con pic18
Salve a tutti, vorrei capire perchè non funziona questo algoritmo.
Ho provato ad usare il modulo capture1.
Code:
// File template #include "p18f4550.h" #include "p18f4550.c" #include <capture.h> #include <timers.h> #include "delay.c" #include "display.c" // VARIABILI GLOBALI #pragma udata // PROTOTIPI FUNZIONE void main(void) { TRISD=0; Init_LCD(); PulisciLCD(); TRISCbits.TRISC2=1;//RC2 come ingresso per CCP1 RCONbits.IPEN=0; //modalità compatibile interruzioni INTCONbits.GIE=1; //abilita interrupt globale INTCONbits.PEIE=1; //abilita interrupt periferiche OpenCapture1( CAPTURE_INT_ON & C1_EVERY_RISE_EDGE ); OpenTimer1( TIMER_INT_OFF & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_1 & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF & T1_SOURCE_CCP ); while(1){ Scrivistringa("Frequenza"); Cursor2LINE(); Scrivinumero(Lettura_Timer1,3); //dovrei leggere il numero di conteggi di Timer1!! HomeLCD(); } #pragma config PLLDIV = 5 // (20 MHz input) #pragma config CPUDIV = OSC1_PLL2 #pragma config USBDIV = 2 // Clock source from 96MHz PLL/2 #pragma config FOSC = HSPLL_HS //#pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config PWRT = OFF #pragma config BOR = ON #pragma config BORV = 3 #pragma config VREGEN = ON #pragma config WDT = OFF #pragma config WDTPS = 32768 #pragma config MCLRE = ON #pragma config LPT1OSC = OFF #pragma config PBADEN = OFF #pragma config CCP2MX = ON #pragma config STVREN = ON #pragma config LVP = OFF //#pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming #pragma config XINST = OFF // Extended Instruction Set #pragma config CP0 = OFF #pragma config CP1 = OFF #pragma config CP2 = OFF //#pragma config CP3 = OFF #pragma config CPB = OFF #pragma config CPD = OFF #pragma config WRT0 = OFF #pragma config WRT1 = OFF #pragma config WRT2 = OFF //#pragma config WRT3 = OFF #pragma config WRTB = ON // Boot Block Write Protection #pragma config WRTC = OFF #pragma config WRTD = OFF #pragma config EBTR0 = OFF #pragma config EBTR1 = OFF #pragma config EBTR2 = OFF //#pragma config EBTR3 = OFF #pragma config EBTRB = OFF #include <capture.h> #include<timers.h> #pragma udata volatile unsigned int Lettura_Timer1=0; unsigned char stato=1; /** PRIVATE PROTOTYPES *********************************************/ void YourHighPriorityISRCode(void); void YourLowPriorityISRCode(void); /** VECTOR REMAPPING ***********************************************/ #define REMAPPED_RESET_VECTOR_ADDRESS 0x800 #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x808 #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x818 extern void _startup (void); // See c018i.c in your C18 compiler dir #pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS void _reset (void) { _asm goto _startup _endasm } #pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS void Remapped_High_ISR (void) { _asm goto YourHighPriorityISRCode _endasm } #pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS void Remapped_Low_ISR (void) { _asm goto YourLowPriorityISRCode _endasm } #pragma code HIGH_INTERRUPT_VECTOR = 0x08 void High_ISR (void) { _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm } #pragma code LOW_INTERRUPT_VECTOR = 0x18 void Low_ISR (void) { _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm } #pragma code //These are your actual interrupt handling routines. #pragma interrupt YourHighPriorityISRCode void YourHighPriorityISRCode() { if(PIR1bits.CCP1IF==1){//ho avuto un evento su ccp1? PIR1bits.CCP1IF==0;//resetta il flag per permettere nuove interruzioni if(stato==1){// se ho avuto il primo fronte di salita WriteTimer1(0); //scrivi zero nel Timer0 e comincia a contare stato=0;} //poichè si è già verificato il primo fronte di salita //pongo a zero lo stato in modo che possa intercettare //il secondo fronte di salita else{ //Intanto Timer1 conta e tiene memoria dei cicli macchina. Lettura_Timer1=ReadCapture1(); //stato è ancora pari a zero e quando si verifica un nuovo evento su ccp1 //viene eseguito il codice in else ovvero legge //il valore attuale di Timer1 stato=1; //ripone lo stato ad 1 in modo che possa ricatturare un nuovo primo fronte di salita } } //This return will be a "retfie fast", since this is in a #pragma interrupt section } #pragma interruptlow YourLowPriorityISRCode void YourLowPriorityISRCode() { } //This return will be a "retfie", since this is in a #pragma interruptlow section /** DECLARATIONS ***************************************************/ #pragma code

Dove sbaglio?

Saluti
Paoletto.
Ultima Modifica 10 Anni 10 Mesi fa da paoletto.

Si prega Accesso o Crea un account a partecipare alla conversazione.

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Forum - Ultimi messaggi