Vai Indietro   PcTuner Forum > Sezione Hardware > Programmazione PIC
Arcade Registrazione Blogs Regolamento Feedback FAQ Lista Utenti Calendario Segna come Letti

Ultimi 5 blog pubblicati su PcTuner Blog
Data Titolo

Rispondi
 
Strumenti Discussione Modalità Visualizzazione
Vecchio 06-04-2011, 16.05.26   #1
Registered User
 

Iscritto da: 04-04-2006
Messaggi: 36
Feedback: (0)
Contagiri con PIC

Ciao a tutti, non sono un esperto programmatore, sto imparando e vorrei realizzare un contagiri con un PIC. Il modello del PIC utilizzatoè il 16F72.
L'idea è quella di prelevare un segnale impulsivo proveniente da un filo avvolto sul cavo della candela di un motore a scoppio. Ho preso spunto da un contagiri commerciale che ho visto applicato ad un rasaerba e che aveva questo principio di funzionamento. Suppongo che ad ogni giro del motore corrisponda un umpulso di candela che per mutua induzione viene a generale un fem indotta sul filo avvolto. Credo sia questo il principio. Ad ogni modo per provare a fare qualcosa mi sono procurato un frequenzimetro tarato su 50 hz (ho preso un valore a caso) con forma d'onda quadra e ho sfruttato il modulo CCP in modalità "capture" del pic. L'ingresso del pic a cui collegare la forma d'onda quadra è il pin RC2. Vi allego il programma che ho fatto per ora. Vi chiedo scusa per le porcate che posso avere scritto ma mi sto dilettando a tempo perso nella programmazione in mikroC dei PIC.

// Inizializzazione LCD su cui visualizzo il numero di giri/min
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

char txt1[]="RPM";

int ricevuto=0;
char pp[16];
char cont=0;
int flag_primoInterrupt=1;
unsigned int tempo;
unsigned int Periodo;
volatile unsigned int Giri_min;
unsigned char tmp;
static unsigned char contatore;

//Qui non sò se è giusto perchè ho ragionato di avere due interrupt legati a due fronti di salita per poterne
//misurare il periodo

void interrupt()
{
if(PIR1.CCP1IF)
{
PIR1.CCP1IF=0;

//Se è il primo interrupt

if(flag_primoInterrupt==1)
{
//AZZERO ILTIMER1

flag_primoInterrupt=0;
TMR1H = 0;
TMR1L = 0;
PIR1.TMR1IF=0;
}
else
{

Periodo = (CCPR1H<<8 + CCPR1L);
flag_primoInterrupt = 1;
ricevuto=1;

}
}


}


void main()

{

TRISB = 0x01;
PORTB = 0xFE;
TRISC2_bit=1;
RC2_bit = 0;

//Settaggio interrupt

INTCON=0xC0;
PIE1.CCP1IE = 1;
T1CON = 0x31;
CCP1CON = 0x05;
PIE1.TMR1IE = 1;


Lcd_Init(); // Initialize LCD

Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,txt1); // Write text in first row


while(1)
{

if(ricevuto==1)
{

Giri_min=(1/Periodo)*60;

ByteToStr(Giri_min,pp);
Lcd_Out(2,1,pp); // Write text in first row
ricevuto=0;

}

}


A questo punto collego l'uscita del frequenzimetro al pin RC2 del PIC e ciò che visualizzo sull'LCD è un numero fisso pari a 196. Anche se cambio frequenza leggo sempre quel valore appena collego il pin RC2 del PIC. Il microcontrollore ha un quarzo esterno a 4Mhz.
Vorrei sapere se possibile capire dove sto sbagliando.

Saluti
mfsaul Non in Linea   Rispondi Citando
Vecchio 06-04-2011, 18.34.18   #2
Credendo Vites
 
L'avatar di  SoldatoSemplice
 

Iscritto da: 17-11-2005
Locazione: Roma
Messaggi: 1,535
Feedback: (0)
Non posso correggerti il codice perchè usi un linguaggio che non conosco, comunque attento che non avrai un impulso ad ogni rotazione del motore, ma ci sono costanti moltiplicative di mezzo, ad esempio se il motore è quattro tempi avrai (mi pare) quattro impulsi ogni giro completo dell'albero, parimenti se è un due tempi avrai (sempre mi pare) due impulsi per giro.

Non solo, ma credo che il numero di scintille della candela è funzione anche del rapporto di riduzione del volano.

In pratica fai prima a mettere una coppia di trasmettitore luminoso, e relativo ricevitore sulla cinghia di trasmissione (con la macchina in folle, freno a mano tirato e numero di giri minimo, quindi non accelerata), poi conti il numero di impulsi che hai sul tuo accoppiamento induttivo e con una semplice divisione hai il rapporto di conversione.
__________________
Il tempo è il miglior maestro, purtroppo uccide tutti i suoi allievi.
SoldatoSemplice Non in Linea   Rispondi Citando
Vecchio 06-04-2011, 21.39.35   #3
Registered User
 

Iscritto da: 04-04-2006
Messaggi: 36
Feedback: (0)
Ah ok, è che più che un'auto mi serviva per un motore a scoppio di un rasaerba (è un due tempi). Comunque pensavo fosse un impulso candela ad ogni giro e ti ringrazio per la delucidazione.
A titolo informativo il codice è in C scritto con il pacchetto software mikroC.
Per ora ti ringrazio.

Saluti
mfsaul Non in Linea   Rispondi Citando
Vecchio 07-04-2011, 14.26.28   #4
Registered User
 

Iscritto da: 22-04-2010
Locazione: Reggio emilia
Messaggi: 600
Feedback: (0)
facciamo un po di teoria.......

se ho un motore a 4 tempi, avrò per ogni cilindro uno scoppio ogni due risalite del pistone, e quindi unio scoppio ogni 2 giri. occhio però che dipende da quante bobine ci sono sul motore, se ho una bobina per tutti i cilindri le cose stanno così, (beninteso leggendo il file della bobina dopo lo spinterogeno), se invecie ci sono due cilindri per ogni bobina ovviamente la scintilla sarà una per giro.


se leggo invecie un motore a 2 tempi, avrò uno scoppio ogni risalita del pistone, percui una scintilla al giro, solitamente sono ad 1 cilindro, se multicilindri valgono le considrazioni precedenti.
lelerelele Non in Linea   Rispondi Citando
Vecchio 07-04-2011, 21.02.33   #5
Tecnico ERMETICO!
 
L'avatar di  ciskopa
 

Iscritto da: 25-03-2007
Locazione: Monopoli
Messaggi: 2,885
Feedback: (0)
Anche in molti motori a 4 tempi si manda 1 scintilla per giro,per questione di semplicità,si chiama scintilla persa,che si usa anche oggi nelle autovetture moderne.
__________________
Mediamente io sono qui http://infoportal.it/
ciskopa Non in Linea   Rispondi Citando
Vecchio 12-04-2011, 00.54.45   #6
RockModerator
 
L'avatar di  RockRibelle
 

Iscritto da: 07-01-2009
Locazione: Lugano
Messaggi: 1,509
Feedback: (0)
Innanzitutto mi accerterei che i valori letti CCP1RH e CCP1RL variano con il variare della frequenza applicata su RC2, magari visualizzando separatamente il valore dei due registri. Solo dopo mi preoccuperei dei fattori correttivi, come ad esempio il numero di impulsi per giro ecc..
__________________
..Indomabile..
RockRibelle Non in Linea   Rispondi Citando
Vecchio 12-04-2011, 15.37.01   #7
Registered User
 

Iscritto da: 22-04-2010
Locazione: Reggio emilia
Messaggi: 600
Feedback: (0)
Quote:
Originariamente inviato da ciskopa Visualizza Messaggio
Anche in molti motori a 4 tempi si manda 1 scintilla per giro,per questione di semplicità,si chiama scintilla persa,che si usa anche oggi nelle autovetture moderne.
era quello a cui mi riferivo quando scrivevo....

se invecie ci sono due cilindri per ogni bobina ovviamente la scintilla sarà una per giro.


mi pare che sia così.
lelerelele Non in Linea   Rispondi Citando
Vecchio 12-04-2011, 23.32.38   #8
RockModerator
 
L'avatar di  RockRibelle
 

Iscritto da: 07-01-2009
Locazione: Lugano
Messaggi: 1,509
Feedback: (0)
Dal momento che moltiplicare per 2 o per 4 una costante dà sempre una costante, mi preoccuperei del problema evocato all'inizio del topic.
__________________
..Indomabile..
RockRibelle Non in Linea   Rispondi Citando
Vecchio 13-04-2011, 08.35.23   #9
Registered User
 

Iscritto da: 22-04-2010
Locazione: Reggio emilia
Messaggi: 600
Feedback: (0)
OK.

non conosco il tipo di compilatore da te usato, per cui la sintassi non mi sembra chiara, comunque non capisco questa riga:

Periodo = (CCPR1H<<8 + CCPR1L);

suppongo che CCPR1H e CCPR1L siano due varibili, e potrei pensare che siano di 8 bit, nel qualcaso pesarei anche che sia errato scorrere di 8bit un valore in una variabile di 8 bit, lo porterei a zero.
lelerelele Non in Linea   Rispondi Citando
Vecchio 14-04-2011, 09.10.50   #10
Registered User
 

Iscritto da: 04-04-2006
Messaggi: 36
Feedback: (0)
Eccomi. Scusate per l'assenza. Intanto vi ringrazione tutti per le risposte. Sono riuscito a far funzionare il circuito anche se non è una soluzione molto "tecnica". Diciamo che alla fine il risultato l'ho un pò forzato, nel senso che faccio molta fatica a filtrare il segnale e quindi i valori visualizzati sul display variano troppo rapidamente. Con una serie di "IF" ho stabilizzato meglio il segnale. Ad ogni modo su un piccolo rasaerba a due tempi questo programmino funziona. Non dico sia un bel programma perchè come programmatore sono molto scarso, però al momento mi funziona. Se capisco come ottimizzare il programma ve lo dico. Ad ogni modo ogni idea o suggerimento è ben accetta. Vi allego il programma che ho riscritto nel caso a qualcuno possa servire per prendere qualche spunto. Grazie a tutti. Alla prossima.


// Inizializzazione LCD su cui indicare i giri/min
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

char txt1[]="Tachometer";
char txt2[]="wait...";
char txt3[]="RPM";

int ricevuto=0;
char pp[16];
char cont=0;
int flag_primoInterrupt=1;
unsigned int tempo;
unsigned long Periodo;
unsigned long Giri_min;
unsigned char tmp;
static unsigned char contatore;
unsigned tOld, tNew;
char th,tl;
char edge = 0;
char capture = 0;
unsigned tword,tword2;
char txt[6];

void interrupt()
{

if(PIR1.CCP1IF){
if(!edge){
tOld = (256*CCPR1H)+CCPR1L;
edge = 1;
}else{
tNew = (256*CCPR1H)+CCPR1L;
capture = 1; // completa capture
edge = 0;
}
PIR1.CCP1IF = 0; //clear CCP flag
}
}



void main()

{
char i;
TRISB = 0x01;
PORTB = 0xFE;

//Settaggio interrupt

CCP1CON = 0x05; // Capture mode every rising edge
TRISC.F2 = 1; // RC2 come input
T1CON = 0x01; // timer1 ON, internal clock Fosc/4, prescaler 1:1
INTCON.GIE = 1;
INTCON.PEIE =1;
PIE1.CCP1IE = 1; // enable interrupt capture
PIR1.CCP1IF = 0; //clear CCP flag

//PIE1 = 0;

// PIE1.TMR1IE = 1;


//INTCON.GIE=1;
//INTCON.INTE=1;



Lcd_Init(); // Inizializza LCD

Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,txt3); // Scrive il testo nella prima riga



while(1){
if(capture){
PIE1.CCP1IE = 0; // Disabilita interrupt mentre processo
capture = 0; // clear flag
// Calcola periodo tra due impulsi successivi
tword = ~tOld + tNew+1;
tword2=(1/((tword/2)*0.000002))*60;
tword2=tword2/10;
if(tword2<=500) tword2=500;
if((tword2>500)&&(tword2<=1000)) tword2=1000;
if((tword2>1000)&&(tword2<=1500)) tword2=1500;
if((tword2>1500)&&(tword2<=2000)) tword2=2000;
if((tword2>2000)&&(tword2<=2500)) tword2=2500;
if((tword2>2500)&&(tword2<=3000)) tword2=3000;
if((tword2>3000)&&(tword2<=3500)) tword2=3500;
if((tword2>3500)&&(tword2<=4000)) tword2=4000;
if((tword2>4000)&&(tword2<=4500)) tword2=4500;
if((tword2>4500)&&(tword2<=5000)) tword2=5000;
if((tword2>5000)&&(tword2<=5500)) tword2=5500;
if((tword2>5500)&&(tword2<=6000)) tword2=6000;
if((tword2>6000)&&(tword2<=6500)) tword2=6500;
if((tword2>6500)&&(tword2<=7000)) tword2=7000;
if((tword2>7000)&&(tword2<=7500)) tword2=7500;
if((tword2>7500)&&(tword2<=8000)) tword2=8000;
if((tword2>8000)&&(tword2<=8500)) tword2=8500;
if((tword2>8500)&&(tword2<=9000)) tword2=9000;
if((tword2>9000)&&(tword2<=9500)) tword2=9500;
if((tword2>9500)&&(tword2<=10000)) tword2=10000;
if((tword2>10000)&&(tword2<=10500)) tword2=10500;
if((tword2>10500)&&(tword2<=11000)) tword2=11000;
if((tword2>11000)&&(tword2<=11500)) tword2=11500;
if((tword2>11500)&&(tword2<=12000)) tword2=12000;
if((tword2>12000)&&(tword2<=12500)) tword2=12500;
if(tword2>12500) tword2=13000;


WordToStr(tword2, txt); // converte in stringa
Lcd_Out(2,1,txt);
delay_ms(100);
PIR1.CCP1IF = 0; //clear CCP flag
delay_ms(300);
PIE1.CCP1IE = 1; // enable interrupt
}
}
}

Ultima Modifica di mfsaul : 14-04-2011 09.14.39.
mfsaul Non in Linea   Rispondi Citando
Vecchio 14-04-2011, 14.08.11   #11
Registered User
 

Iscritto da: 22-04-2010
Locazione: Reggio emilia
Messaggi: 600
Feedback: (0)
io userei una variabile, alla quale incrementeri 1 oppure decrementerei 1 a seconda che il numero dei giri letto sia superiore oppure inferiore al valore della variaile in quel momento, ottenendo di fatto una media dei valori letti, la cui velocità di variazione è funzione dalla velocità con cui la aggiorni.
lelerelele Non in Linea   Rispondi Citando
Vecchio 14-04-2011, 14.18.35   #12
Registered User
 
L'avatar di  Camillo
 

Iscritto da: 31-01-2006
Locazione: Genova
Messaggi: 1,471
Feedback: (0)
Quote:
Originariamente inviato da mfsaul Visualizza Messaggio
...Con una serie di "IF" ho stabilizzato meglio il segnale. Ad ogni modo su un piccolo rasaerba a due tempi questo programmino funziona. Non dico sia un bel programma perchè come programmatore sono molto scarso, però al momento mi funziona. Se capisco come ottimizzare il programma ve lo dico. Ad ogni modo ogni idea o suggerimento è ben accetta. Vi allego il programma che ho riscritto nel caso a qualcuno possa servire per prendere qualche spunto. Grazie a tutti. Alla prossima.

if(tword2<=500) tword2=500;
if((tword2>500)&&(tword2<=1000)) tword2=1000;
if((tword2>1000)&&(tword2<=1500)) tword2=1500;
if((tword2>1500)&&(tword2<=2000)) tword2=2000;
if((tword2>2000)&&(tword2<=2500)) tword2=2500;
if((tword2>2500)&&(tword2<=3000)) tword2=3000;
if((tword2>3000)&&(tword2<=3500)) tword2=3500;
if((tword2>3500)&&(tword2<=4000)) tword2=4000;
if((tword2>4000)&&(tword2<=4500)) tword2=4500;
if((tword2>4500)&&(tword2<=5000)) tword2=5000;
if((tword2>5000)&&(tword2<=5500)) tword2=5500;
if((tword2>5500)&&(tword2<=6000)) tword2=6000;
if((tword2>6000)&&(tword2<=6500)) tword2=6500;
if((tword2>6500)&&(tword2<=7000)) tword2=7000;
if((tword2>7000)&&(tword2<=7500)) tword2=7500;
if((tword2>7500)&&(tword2<=8000)) tword2=8000;
if((tword2>8000)&&(tword2<=8500)) tword2=8500;
if((tword2>8500)&&(tword2<=9000)) tword2=9000;
if((tword2>9000)&&(tword2<=9500)) tword2=9500;
if((tword2>9500)&&(tword2<=10000)) tword2=10000;
if((tword2>10000)&&(tword2<=10500)) tword2=10500;
if((tword2>10500)&&(tword2<=11000)) tword2=11000;
if((tword2>11000)&&(tword2<=11500)) tword2=11500;
if((tword2>11500)&&(tword2<=12000)) tword2=12000;
if((tword2>12000)&&(tword2<=12500)) tword2=12500;
if(tword2>12500) tword2=13000;
Non ho né tempo né voglia analizzare il programma però quella serie di if in fondo balza agli occhi e mi fa rizzare i capelli in testa.
Codice:
#define INCREM 500
  for(udummy=INCREM;udummy<=13000;udummy+=INCREM){
    if(tword2<=udummy){
      tword2=udummy;
      break;  // Esce dal ciclo for.
    }
  }
Dovresti usare i tag opportuni quando metti del codice.
__________________
Camillo

Internet ti fa vedere tutto ma non ti fa toccare niente. (Camillo Ferrari)
Camillo Non in Linea   Rispondi Citando
Vecchio 19-04-2011, 13.48.44   #13
Registered User
 

Iscritto da: 04-04-2006
Messaggi: 36
Feedback: (0)
Quote:
Non ho né tempo né voglia analizzare il programma però quella serie di if in fondo balza agli occhi e mi fa rizzare i capelli in testa.
Quote:
Dovresti usare i tag opportuni quando metti del codice.
Ho premesso che sto imparando a programmare e sono molto scarso. Tutto qui.
mfsaul Non in Linea   Rispondi Citando
Rispondi Per le vostre immagini su questo forum potete usare PcTunerUp!
Iscriviti gratuitamente alla nostra newsletter.


Utenti attualmente attivi che stanno leggendo questa discussione: 1 (0 utenti e 1 visitatori)
 
Strumenti Discussione
Modalità Visualizzazione

Regole di scrittura
non Puoi inserire messaggi
non Puoi rispondere ai messaggi
non Puoi inviare allegati
non Puoi modificare i tuoi messaggi

codice vB è Attivo
Smilies è Attivo
[IMG] il codice è Attivo
Il codice HTML è Disattivato
Trackbacks are Disattivato
Pingbacks are Disattivato
Refbacks are Disattivato
Vai al Forum


Tutti gli Orari sono GMT +2. Attualmente sono le 22.57.32.


Powered by vBulletin Versione 3.6.12
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright © 2010 - Master New Media S.r.l. a socio unico - P.I. 02947530784. Tutti i diritti di proprietà letteraria e artistica sono riservati- Privacy
www.pctuner.net è testata telematica registrata presso il Tribunale di Torino, n. 39 del 07.05.2008, Editore Master New Media S.r.l.