Vai al contenuto
PLC Forum


Interfacciare Pic 16F877 A Pt100Ohm


slavin89

Messaggi consigliati

salve a tutti

mi presento per la prima volta all'interno di questo forum nel quale spero di trovarmi bene e soprattutto di trovare aiuto:)

vi faccio subito una domanda ; sto creando un termometro con un pic 16f877a un display lcd e una sonda pt100 ohm; per interfacciare la sonda al pic ho utilizzato il circuito proposto dalla microchip in particolare AN687 che probabilmente molti di voi già conoscono.

ho però purtroppo delle difficolta nello sviluppare il tutto e in particolare penso che il mio problema sia nella parte software..sfruttando il convertitore interno del pic al posto del 12 bit proposto non riesco a visualizzare la temperatura corretta sul disply e per corretta intendo approssimativamente..il ragionamento che ho fatto io è stato :

leggere il valore della conversione, moltiplicarlo per 244( ossia valore di tensione di ref 2,5 v diviso 1024 bit del convertitore)

successivamente ho preso il risultato e l'ho diviso per il risultato della divisione tra 2,5 volt e 800 gradi ovvero il range di funzionamento della sonda (-200÷600°c).

il risultato di tutto questo è un disastro:)

tengo a specificare che posso lavorare solo con numeri int.

se qualcuno potesse aiutarmi ve ne sarei grato

saluti

Link al commento
Condividi su altri siti


  • Risposte 132
  • Created
  • Ultima risposta

Top Posters In This Topic

  • slavin89

    62

  • Livio Orsini

    58

  • Nikiki

    6

  • GiRock

    4

Prima di tutto sei sicuro che i valori di temperatura da -200 a 600 °C corrispondano esattamente da 0 a 2,5 volt in ingresso al micro?... come hai collegato la sonda al micro?

Veniamo al calcolo, moltiplicando il valore campionato per 244 ottieni la tensione in ingresso al convertitore moltiplicata per 100.000 (se ho ben capito fai questo per evitare l'uso di un valore in virgola mobile. Nel secondo calcolo ovviamente non puoi dividere per il risultato di 2,5/800, ma anche in questo caso dovrai moltiplicare per 100.000 e usando solo la parte intera sarebbe 312... l'hai fatto?

Se si, facciamo una simulazione:

se la sonda misura +200 °C (metà range) si presume che il risultato della conversione sia 512 (la metà di 1024), moltiplicando 512 * 244 = 124.928, dopodichè 124.928 / 312 = 400... che ovviamente non è il valore in temperatura ma la differenza in gradi tra il valore minimo e il valore letto (-200 + 400 = 200... °C appunto)

Quindi il calcolo che fai va bene, devi fare attenzione a quel 100.000 e al risultato che non è una temperatura relativa agli 0°C ma un valore assoluto.

Una domanda:

Quando dici che puoi lavorare solo con numeri int, intendi interi in senso generico o int nel senso di tipo di dati del compilatore, come ad esempio il C?

Perchè se hai limitazioni a livello di dati, potresti avere problemi anche a manipolare numeri grandi come quelli che vai a calcolare, ti ricordo che i PIC16 sono micro a 8 bit, quindi in C un int è insufficiente a contenere i numeri per il tuo calcolo, avresti un overflow e di conseguenza un risultato che non ha niente a che vedere con quello che ti aspetti.

Link al commento
Condividi su altri siti

Tanto per cominciare sarebbe bene che sfruttassi il convertitore per 5V, al meno ilquanto di misura è meno sensibile ai distrubi.

Poi se operi su di un campo così ampio la misura è sicuramente non lineare. confronta una tabella di corrispondenza ohm/gradi e vedrai che si può considerare quasi lineare la misura se stai tra 0 e 100oC - 150oC

Link al commento
Condividi su altri siti

intanto ringrazio per le risposte..proseguo specificando che ho fatto fede a quanto scritto sul datasheet dell'an687 nella parte delle conclusioni dicono che il valore che avrò in tensione sarà compreso tra 0.138 e 2.343 volt..poi più in alto dicono che il campo scala della pt100 va da -200 a 600 °C quindi io ho associato probabilmente commettendo un errore , il valore min di tensione al valore minimo di temp e lo stesso per il valore max

In this circuit, the RTD element equals 100Ω at 0°C. If

the RTD is used to sense temperature over the range

of -200°C to 600°C, the resistance produced by the

RTD would be nominally between 18.5Ω and 313.7Ω,

giving a voltage across the RTD between 18.5 mV and

313.7 mV. Since the resistance range is relatively low,

wire resistance and wire resistance change over

temperature can skew the measurement of the RTD

element. Consequently, a 3-wire RTD device is used to

reduce these errors.

The errors contributed by the wire resistances, RW1

and RW3, are subtracted from the signal with op amp

A3. In this configuration, R1 and R2 are equal and are

relatively high. The value of R1 is selected to ensure

that the leakage currents through the resistor do not

introduce errors to the current in the RTD element. The

transfer function of this portion of the circuit is

The voltage signal at the output of A3 is filtered with a

2nd order, low pass filter created with A4, R8, C8A, C8B,

R9 and C9. It is designed to have a Bessel response

and a bandwidth of 10 Hz. R10 and R11 set a gain of

7.47 V/V. It reduces noise and prevents aliasing of

higher frequency signals.

This filter uses a Sallen-Key topology specially

designed for high gain; see [ 10]. The capacitor divider

formed by C8A and C8B improve this filter’s sensitivity

to component variations; the filter can be unproduceable

without this improvement. R12 isolates A4’s output

from the capacitive load formed by the series connection

of C8A and C8B; it also improves performance at

higher frequencies.

The voltage at A4’s output is nominally between 0.138V

and 2.343V, which is less than VREF (2.5V). The 12-bit

A/D converter (MCP3201) gives a nominal temperature

resolution of 0.22°C/LSb.

"estratto del datasheet"

io penso che il mio errore stia nel valutare i valori di tensione corretti rispetto alla temperatura ma dal datasheet non capisco come poterli trovare..

per quanto riguarda la moltiplicazione per 100000 serve appunto per non lavorare con numeri in virgola mobile e ho sempre tenuto conto di dover moltiplicare entrambi i fattori..

Link al commento
Condividi su altri siti

Questa discussione tratta un argomento molto simile al tuo, prova a dargli un'occhiata. Io ho realizzato quell'interfaccia proprio per misurare una temperatura con PT100 tramite un 16F876/7
Link al commento
Condividi su altri siti

scusami ma io ho dato un occhio alla discussione ma davvero non ho trovato nulla che potesse aiutarmi..tu hai usato l'an687?

puoi aiutarmi a risolvere il mio problema?

infine non voglio che qualcuno mi scriva il programma per carità vorrei solo capire cosa sbaglio ..non necessito di un range cosi elevato di temperatura se fosse quello il problema ma come faccio a definire i valori max e min di temperatura in relazione alle tensioni?..

Link al commento
Condividi su altri siti

Per prima cosa devi definire la gamma di temperatura necessaria per le tue esigenze.

La gamma di tensione è compresa sempre tra 0 e 5 V, che sono i limiti degli A/D dei PIC.

COnoscendo la gamma di temperatura conosci anche la gamma dei valori di resitenza che assumerà il tuo trasduttore. A questo punto è quasi banale associare al Trasduttore il vaslore di corrente necessaria per ottenere un valore di tensione che, amplificato, dia l'escursione richiesta.

Link al commento
Condividi su altri siti

Slavin89, se vuoi un aiuto più diretto devi fornire qualche informazione in più.

Quando scrivi "il risultato è un disastro" che cosa intendi esattamente?...

- la misura non è lineare?

- ciò che leggi sul display non ha niente a che vedere con la lettura?

- ... altro...

Inoltre...

- Per interfacciare la pt100 al pic hai riprodotto fedelmente lo schema elettrico suggerito sull' AN?

- Hai provato a misurare la tensione in uscita dal circuito e quindi in ingresso al pic con un normale tester? Se si, la misura è quella che ti aspetteresti?

- che linguaggio/compilatore usi per programmare il pic?

Link al commento
Condividi su altri siti

io penso che il mio errore stia nel valutare i valori di tensione corretti rispetto alla temperatura ma dal datasheet non capisco come poterli trovare..

l'intervallo di tensione che dovresti avere sull ingresso del pic con temperature da -200 a 600 gradi è scritto qui:

The voltage at A4’s output is nominally between 0.138V

and 2.343V, which is less than VREF (2.5V). The 12-bit

A/D converter (MCP3201) gives a nominal temperature

resolution of 0.22°C/LSb.

... sempre se interfacci la sonda con il circuito proposto sull' AN

Link al commento
Condividi su altri siti

il circuito che ho fatto per collegare la pt 100 è esattamente quello dell'an687.

all'uscita del circuito leggo un valore in mA che si aggira indicativamente intorno ai 340 mV e se scaldo la sonda vedo che questo valore aumenta quindi immagino il valore sia corretto..andando poi a vedere il display vedo che il valore non cambia come dovrebbe..partendo dal fatto che mi visualizza 180 gradi poi alle volte 40 ma le variazioni soprattutto non sono lineari con l'aumento dei mV; per capirci se a display vedo 89 gradi ( che già è sbagliato perchè siamo a temp ambiente) scaldo la sonda con una fiamma e lui continua a mostrarmi quel valore poi di colpo magari va a 280 e si blocca su quel valore..sembra come ci sia un filtro ma cosi non è..

sullo schema dell'an 687 c'è scritto di usare un valore di tensione di ref di 2,5 volt e dunque io ho impostato anche sul pic che la tensione V ref+ è 2,5 volt ..non riesco a capire dove sta lo sbaglio..

programmo in C e compilo con mp lab

Modificato: da slavin89
Link al commento
Condividi su altri siti

Cerchiamo di chiarire alcuni punti che non son chiari.

Da quello che scrivi sembra che tu usi l'A/D_C del PIC con Vref = 2.5 V. Da dove la ricavi questa tensione? A quale porta del PIC la connetti? COme hai settato il PIC?

Poi tu continui a scrivere "mA" ma dall'interfaccia devono uscire mV perchè l'A/D misura tensioni e non correnti.

Prova a connettere un tester all'uscita dell'interfaccia e fare misure di tensione al variare della temperatura della sonda.

Non c'è nemmeno bisogno di mettre una PT100 per verificare e tarare. Al posto della PT100 colleghi un resitore da 100 ohm 1% e leggi la tensione corrispondente a 0oC, colleghi in serie alla 100 ohm un altro resistore da 20 ohm ed avrai la tensione corrispondente a 51.50oC, sostistuisci il valore da 20 ohm con uno da 39 ohm ed avrai la tensione corrispondente a 102.50oC circa. Così avrai gia individuato 3 punti di una retta più che sufficienti per individuarla. l'unico problema che la PT100 non è prprio lineare, è quasi lineare nell'intervallo 0 - 150oC.

Una volta che hai stabilito se l'interfaccia lavora correttamente, potrai dedicarti alla conversione A/D

Link al commento
Condividi su altri siti

Per curiosità sono andato a vedere la AN687. Da un certo punto di vista è un classico: alimentazione della RTD con corrente costante, anche se 1 mA è al limite dell'autoriscaldamento, compensazione della linea con collegamento a 3 fili. Nel testo si legge chiaramente della non linearità tipica e ne da anche la curva (la linea rossa del diagramma, mentre quella blù è la funzione R = f(temp)).

Trovo un poco UCAS la realizzazione del filtro analogico, quando si dispone di un micro per leggere la temperatura, quindi molto più facile e pratico filtrare in digitale.

COme trovo anche poco pratico limitare l''escursione a 2.5 V, quando il micro di suo può convertire a 5 V.

COmunque è tutto "normale". Se hai realizzato l'interfaccia in modo corretto devi leggere i valori di tensione proprorzionali alla temperatura, anzi alla resistenza.

Verifica, come ho scritto prima, che questo avvenga. Poi se la parte analogica è corretta verifichiamo il software.

Link al commento
Condividi su altri siti

domani provo a fare le prove che ha detto Livio comunque la lettura del convertitore la salvo su un dato int mentre il risultato della lettura * risoluzione convertitore la salvo su un dato tipo long...

la tensione di 2,5 volt la ricavo da un circuito con lm e la uso sia come tensione di ref sull'an687 che come vRef + del convertitore dopo aver settato in modo appropriato il registro per settare le porte analogiche sul pic in particolare

ADCON1=0b10000000;

// bit 0 -> PCFG0 Configurazione delle porte analogiche , quali analogiche o digitali

// bit 1 -> PCFG1 Configurazione delle porte analogiche , quali analogiche o digitali

// bit 2 -> PCFG2 Configurazione delle porte analogiche , quali analogiche o digitali

// bit 3 -> PCFG3 Configurazione delle porte analogiche , quali analogiche o digitali

// bit 4 -> NON USATO

// bit 5 -> NON USATO

// bit 6 -> ADCS2 unito a ADCS1 e a ADCS0 su ADCON0 per impostare la frequenza di campionamento

// bit 7 -> ADFM 1: giustificazione a destra, 0: giustificazione a sinistra

la cosa strana è che per esempio ora facevo qualche prova ma il risultato è sempre che accendo lo strumento e mi visualizza un valore in questo caso 9.138 poi se scaldo con la mano mi va a 77.81 e rimane fisso li ma di colpo poi se tolgo la mano di colpo al valore precedente

Link al commento
Condividi su altri siti

Non so co,mme lavora il tuo compilatore, ma ADICON1, se sitratta del registro del PIC, andrebbe configurato come :


ADICON1 = 0b10000001; // Fosc/8 e A/D enabled (bit 0)

Mentre selezione deel canale, riferimento e giustificazione sono individuati da ADICON2

poi nei tuoi codici non vedo dove vai a testare l'EOC (fine della conversione).

Potrei postarti anche il codice che uso io però è per compilatore CCS.

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

// ADCON0

ADCON0=0b10000001;

// bit 0 -> ADON Abilitazione modulo ADC, 1=Acceso , 0=Spento

// bit 1 -> NON USATO

// bit 2 -> GO/DONE Stato di conversione 1=avvia conversione , 0=conversione finita

// bit 3 -> CHS0 Selezione della porta analogica da leggere

// bit 4 -> CHS1 Selezione della porta analogica da leggere

// bit 5 -> CHS2 Selezione della porta analogica da leggere

// CHS2|CHS1|CHS0

// 000=AN0

// 001=AN1

// 010=AN2

// 011=AN3

// 100=AN4

// 101=AN5

// 110=AN6

// 111=AN7

// abbiamo preselezionato la porta AN2 (010) in quanto è qui

// che abbiamo collegato la LM35

// bit 6 -> ADCS0 Frequenza di conversione A/D

// bit 7 -> ADCS1 Frequenza di conversione A/D

// |ADCON1| ADCON0 |

// |ADCS2 |ADCS1|ADCS0|Frequenza di conversione

// | 0 | 0 | 0 |Fosc/2

// | 0 | 0 | 1 |Fosc/8

// | 0 | 1 | 0 |Fosc/32

// | 0 | 1 | 1 |FRC(clock derivato da un circuito RC)

// | 1 | 0 | 0 |Fosc/4

// | 1 | 0 | 1 |Fosc/16

// | 1 | 1 | 0 |Fosc/64

// | 1 | 1 | 1 |FRC(clock derivato da un circuito RC)

// abbiamo scelto Fosc/32 in quanto, con il quarzo da 20MHz,

// ci garantisce un TAD di 1,6uS come spiegato nella parte introduttiva

// di questo capitolo del corso

// ADCON1

ADCON1=0b10000000;

// bit 0 -> PCFG0 Configurazione delle porte analogiche , quali analogiche o digitali

// bit 1 -> PCFG1 Configurazione delle porte analogiche , quali analogiche o digitali

// bit 2 -> PCFG2 Configurazione delle porte analogiche , quali analogiche o digitali

// bit 3 -> PCFG3 Configurazione delle porte analogiche , quali analogiche o digitali

// bit 4 -> NON USATO

// bit 5 -> NON USATO

// bit 6 -> ADCS2 unito a ADCS1 e a ADCS0 su ADCON0 per impostare la frequenza di campionamento

// bit 7 -> ADFM 1: giustificazione a destra, 0: giustificazione a sinistra

questi sono i registri che vanno settati sul mio pic

Link al commento
Condividi su altri siti

Io ho l'impressione che tu abbia copiato il codice da qualche parte cercando poi di adattarlo, difatti risulta LM35 e non PT100, ma perché non lo posti così magari possiamo controllarlo integralmente???

Per linearizzare una PT100 leggiti anche Callendar-Van Dusen Temperature/Resistance relation...

Link al commento
Condividi su altri siti

infatti è cosi se volete cito anche progetto e sito non ho certo nulla da nascondere..è solo che sul sito dove era postato non riesco a trovare aiuto..ho preso la base del programma e anzi del corso e ora sto creando un mio progetto da quello che ho imparato..

if(T0IF)

{

TMR0=102;

counter_LM35--;

if (counter_LM35==0)

{

ADGO=1;

counter_LM35=200;

}

T0IF=0;

}

if (ADIF)

{

calcola=1; // abilito, nel main, l'aggiornamento del valore di temperatura

ADIF=0; // resetto il flag di fine conversione A/D

}

if (calcola)

{

VALORE= ADRESL + (ADRESH<<8);

SOMMAval+=VALORE;

CONTAval++;

if (CONTAval==(DIVISORE-1))

{

result=SOMMAval/DIVISORE;

SOMMAval=0;

CONTAval=0;

tensione=((result*100)*215);

LCD_GOTO(1,7);

LCD_PUTUN(tensione/362);

LCD_PUTS(",");

LCD_PUTUN(tensione%362);

LCD_PUTCH(0b11011111); // simbolo del grado

LCD_PUTS("C");

if (result<20) // 20 bit equivale a 10°

{

LCD_GOTO(1,7);

LCD_PUTS(" ");

}

}

calcola=0;

} //fine calcolo

questo è la parte di calcolo poi il setting riporta solo i registri tris e i registri di config

Link al commento
Condividi su altri siti

Facciamo reset di tutto perchè c'è un po' troppa carne al fuoco.

Indipendentemente dall'articolo da cui hai preso spunto, vediamo di far funzionare il tuo lavoro. Non dico che è banale, ma quasi, almeno per chi ha un poco di esperienza.

Cominciamo con il dividere il porgettino in alcune funzioni base Hw e Sw e vediamo di affrontare il tutto con metodo. Ricorda che il metodo corretto di approccio è la base fondamentale per una buona riuscita. Si fa un passo alla volta, si consolida il terreno e, quando il terreno è sicuramente solido, ci si muove per ilf atto successivo.

Prima informazione necessaria per procedere ad aiutarti. Cosa usi per il debug? Hai un ICD e qualche altro strumento che ti permette di mettere break e di visualizzare le variabili?

Poi la parte Hw di interfaccia funziona correttamente? Hai effettuato le misure che ti avevo suggerito?

Se la parte Hw è funzionante si può passare alla fase successiva: l'acquisizione della temperatura.

Togli tutto il software che non serve a questa funzione.

Il software deve contenere solo la parametrizzazione delle porte del PIC un temporizzatore con il relativo interrupt per realizzare il clock necesario a schedulare le varie operazioni. Io solitamente uso TIMER1 ed il relativo interupt, però non è fondamentale.

Oltre a questo devi parametrizzare il convertitore A/D del pic ed effettuare l'acquisizione.

Per fare questo sono necessarie e sufficienti 20 istruzioni assembler, oppure 10 righe di "C" (forse anche meno).

Prova a seguire questa strategia. Se proprio non riesci a leggere l'A/D ti posto le istruzioni in asm per le verifiche del caso.

Link al commento
Condividi su altri siti

Allora, a mio parere l'errore è trattare un codice progettato per un sistema lineare come quello dello LM35 ed utilizzando la stessa procedura per adattarlo alla PT100 che di lineare a ben poco con tutta quell'escursione di temperatura...

Ho sottomano un codice in Basic che utilizza un MCP3421 per la trasmissione dei dati via I2C a 18bit compreso il valore della resistenza, la formula di linearizzazione è abbastanza complessa, si tratta di risolvere un equazione di II° grado con sistema ricorsivo fino ad ottenere un errore accettabile > 0.001, qui si tiene conto del GAIN, del coefficente maggiore e minore del valore di tensione rispetto alla temperatura, il valore della resistenza a 0°C, il tutto calcolato in base anche alla Vref e alla Iexc che sarebbe poi la corrente di eccitazione della sonda convertiti per il numero di bit dell'ADC, naturalmente vengono presi in considerazione anche il minimo ed il massimo valore di temperatura rilevabili, con questa formula si ottengono precisioni di lettura dell'ordine di 0.01°C...

Ad ogni modo ha ragione Livio, bisogna procedere per gradi, escludendo che nel percorso tra HW e SW non ci siano delle lacune che falsino le letture...

Link al commento
Condividi su altri siti

la formula di linearizzazione è abbastanza complessa

Questa è un po' una mania da teorici.

Quando si deve lavorare con un'escursione di temperatura ampia molto meglio lavorare su 2 fronti: quello Hw analogico e quello software.

Sul fronte Hw, basta ricordarsi un poco di come si agiva qualche anno fa quando la strumentazione era solo analogica: ponte di misura asimmetrico e scelta oculata del valore di corrente costante. Con poco si ottengono risultati strabilianti; questa tecnica l'ho imparata quasi 50 anni fa ma è ancora valida.

Sul fronte Sw è inutile effettuare calcoli complessi, molto pesanti che drenano infinite risorse di CPU. Molto meglio suddividere la gamma di misura in alcune sottogamme ed usare tabelle di compensazione-interpolazione. Anche qui con poco si ottiene molto.

con questa formula si ottengono precisioni di lettura dell'ordine di 0.01°C...

E' solo in teoria, nella pratica è ...praticamente impossibile visto che gli standard di strumentazione danno, al massimo, precisioni di +/-0.03oC a 0oC e +/- 0.08oC a 100oC. A meno di farsi selezionare una RTD appositamente il +/- 0.01oC te lo scordi.

Link al commento
Condividi su altri siti

Certo Livio,

si possono ottenere ottimi risultati anche per altre vie o escamotage, ma non di certo con quella che ha scritto il nostro Amico, adatta solamente per segnali linearizzati a monte...

Posso assicurarti che simulandolo, il circuito restituisce un errore di soli 0.01°C per temperature tra -50° +150°C, po si sale a 0.02°C verso i -100°C ed intorno ai 250°C, oltre siamo già a 0.03°C per poi arrivare ad un massimo di 0.06°C al si sopra dei 550°C, tutto sommato niente male...

Beh, il processore quì è fondamentale e lavora a pieno regime per compensare e ridurre l'errore senza l'uso di tabelle comparative, naturalmente il generatore di corrente deve essere impeccabile dal punto di vista progettuale così come i componenti utltilizzati...

Link al commento
Condividi su altri siti

Posso assicurarti che simulandolo, il circuito restituisce un errore di soli 0.01°C....

Questo è l'errore di tutto la parte di misura senza il sensore. Il sensore di suo ha un'errore maggiore, quindi a quell'errore devi aggiungere l'errore del sensore, secondo la classe di sensori impiegata. Nella classe standard l'errore del sensore è un ordine di grandezza maggiore, mentre nella classe migliore è 3 volte.

Poi alla fine tutto dipende dall'impiego che ne fai. Io, ad esempio, la prima applicazione che vidi serviva a calcolare il volume del carburante conoscendo il peso. In pratica le autocisterne in uscita dalla raffineria avevano il peso noto, però il volume era dipendente dalla temperatura del liquido stivato e visto che le tasse si calcolano sul volume era necessario conoscere la temperatura. E' superfluo sottolineare, in questa applicazione, l'importanza della precisione di misura.

Link al commento
Condividi su altri siti

sono un po in pausa con il progetto perchè provando a vedere le tensioni in uscita al circuito vedo che variano al variare della temperatura ma i valori sono sballati quindi ora mi faccio il circuito su stampato cosi sono sicuro che sia giusto e almeno elimino i possibili problemi hw..

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora

×
×
  • Crea nuovo/a...