Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #30 on: November 16, 2012, 08:55:11 am » |
vorrei fare qualche cosa del genere partendo dalla formula base RT = R0(1 + AT + BT² + C(T-100)T³), vediamo cosa riesco a combinare 
|
|
|
|
|
Logged
|
Gianfranco
|
|
|
|
0
Online
Tesla Member
Karma: 81
Posts: 8184
:(){:|:&};:
|
 |
« Reply #31 on: November 16, 2012, 09:03:32 am » |
uhmm se vuoi una tale precisione io partirei da un termometro con già tale precisione, lo userei come riferimento per un range di misure molto più puntuali, e poi disegnerei il grafico della resistenza in funzione della temperatura. Poi dal grafico ricaverei (con non poca fatica) una funzione.
In generale, una volta che hai il grafico, testare formule come RT = R0(1 + AT + BT² + C(T-100)T³) è poco più difficile che inserire la formula in un foglio excel e vedere i valori ricavati al variare di R quanto sballano rispetto ai valori reali.
|
|
|
|
|
Logged
|
|
|
|
|
Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #32 on: November 16, 2012, 09:06:00 am » |
Avessi avuto lo strumento richiesto per fare il tuo esperimento lo avrei già usato, mi sarei segnato i valori grado per grado 
|
|
|
|
|
Logged
|
Gianfranco
|
|
|
|
Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #33 on: November 16, 2012, 04:22:51 pm » |
Ecco un pò di codice: #include <stdio.h> #include "pins_arduino.h" #include <LiquidCrystal.h>
#define UTI_PIN 5 #define UTI_RESISTANCE_REF 1000
float TempStorage[20] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; //Contiene le ultime 20 rilevazioni float Media = 0.0; //Contiene il valore della temperatura media int MediaCount = 0; //Contatore che permette il calcolo della media solo dopo aver riempito completamente l'array int ArrayMax = 19; // Dimensione massima array int CurPos = 0; //Contiene la posizione corrente nell'array
LiquidCrystal lcd(12, 11, 6, 4, 3, 2); unsigned long samplingMillis, printMillis; int samplingTime = 500; //In ms, frequenza di campionamento int printTime = 1000; //in ms, frequenza di stampa dei dati
void setup() { Serial.begin(9600); pinMode(UTI_PIN, INPUT); Serial.print("Avvio PT100"); Serial.print("\n"); lcd.begin(16, 2); lcd.print("PT100"); CurPos=-1; //Inizializzo la posizione nell'array delay(3000); }
int ReadUTI(uint8_t pin, float * temp,int refRes) //Ottimizzato per PT100 4 fili - Modalità 5 (4 fasi) { int state = HIGH; int i,startindex=-1; uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); uint8_t stateMask = (state ? bit : 0); unsigned long width[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; float nOff=0,nAB=0,nCD=0,nBC=0,nDF=0; while ( (*portInputRegister(port) & bit) != stateMask) ; for(i=0;i<10;i++) { while ( (*portInputRegister(port) & bit) == stateMask) width[i]++; while ( (*portInputRegister(port) & bit) != stateMask) width[i]++; } for(i=1;i<10;i++) { if(i<6) { if(width[i]<width[i+2]&&width[i]<width[i+3]&&width[i]<width[i+4]&&width[i+1]<width[i+2]&&width[i+1]<width[i+3]&&width[i+1]<width[i+4]) { startindex=i; i=10; } } } if(startindex!=-1) { nOff=width[startindex]+width[startindex+1]; nAB=width[startindex+2]; nCD=width[startindex+3]; nBC=width[startindex+4];
*temp=((nCD-nOff)/(nAB-nOff))*refRes; return 1; } else { return 0; } }
void readTemp() { float temp; if(ReadUTI(UTI_PIN,&temp,UTI_RESISTANCE_REF)) { float TempNorm = 2.596415876*temp-264.95648; //Formula ricavata dalla calibrazione a 0 e 100 °C if (CurPos<ArrayMax){CurPos++;} else { CurPos=0; } //Gestisce la posizione del cursore all'interno dell'array TempStorage[CurPos]=TempNorm; //Registra la temperatura all'interno dell'array if (MediaCount<23) {MediaCount++;} //Calcola la media solo se l'array è stato riempito completamente else { Media =0.0; for (int i=0;i<=ArrayMax;i++) { Media = Media + TempStorage[i];} Media = Media / (ArrayMax+1); } } else { printTempError(); //Se l'UTI non riceve alcuna temperatura, restituisce errore } }
void printTempError() { Serial.print("Not Found"); Serial.print("\n"); lcd.setCursor(0, 1); lcd.print("NotFound"); }
void printTempMedia() { if (MediaCount < 23) { //Stampa la media solo se l'array è completamente pieno Serial.print("Inizializzazione Sensore ("); Serial.print(CurPos); Serial.print(")"); Serial.print("\n"); lcd.setCursor(0, 1); lcd.print("Init"); } else { Serial.print(Media); Serial.print("\n"); lcd.setCursor(0, 1); lcd.print(Media); } }
void loop() { if ((millis()- samplingMillis) > samplingTime) { samplingMillis = millis(); readTemp(); } if ((millis()- printMillis) > printTime) { printMillis = millis(); printTempMedia(); } }
|
|
|
|
« Last Edit: November 16, 2012, 05:06:11 pm by GianfrancoPa »
|
Logged
|
Gianfranco
|
|
|
|
Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #34 on: November 17, 2012, 06:48:18 am » |
Al fine di poter trovare questa famosa formula magica, perfetta, di conversione, mi son messo un pochettino a giocare con Excel. Prego tutti voi di verificare che i miei ragionamenti sono esatti!!! La formula base, per una PT100, che restituisce il valore della resistenza è la seguente: 1) Rt = R0*(1 + A*t + B*t^2 + C*(t-100)*t^3)Supponendo di avere una PT100 ed un circuito che rispondano perfettamente a questa formula, andiamo avanti. Ho realizzato con excel una lista di valori derivati dalla suddetta formula, ed ho ricavato il seguente grafico:  Poi ho invertito x e y ed ho ottenuto il seguente grafico:  Al che ho fatto sviluppare a Excel la relativa formula: 2) t = 4E-13*Rt^6 - 2E-10*Rt^5 + 7E-08*Rt^4 - 2E-05*Rt^3 + 0,0038*Rt^2 + 2,1705*Rt - 241,09Ho ridato quindi in pasto ad excel i dati ottenuti dalla formula 1) ed ho ottenuto un valore simile a quello iniziale. Ho quindi creato una lista degli scarti di cui ho fatto il grafico:  Ancora una volta il buon Excel ha fatto il lavoraccio: 3) y = -8E-05x2 - 0,0086x - 0,6422Questa nuova formula corregge l'errore della 2) In pratica, dopo tutto questo trambusto ottengo che la somma delle formule 2) e 3) danno un risultato compatibile con la formula generale 1) che è si lineare, con le dovute approssimazioni! Come vi sembra? Ho sprecato tempo?? Tutto questo mi è utile perchè, dando per scontata la correttezza di quanto fatto, ho notato che la mia configurazione pt100 + circuito, risponde alla legge generale delle PT100 (formula 1)) con un offset di 2,047 Ohm. Sapendo ciò posso facilmente adattare le formule 2) e 3) al mio caso... che ne pensate?
|
|
|
|
|
Logged
|
Gianfranco
|
|
|
|
Lamezia Terme
Offline
Shannon Member
Karma: 386
Posts: 10227
Le domande di chi vuol imparare rappresentano la sua sete di sapere
|
 |
« Reply #35 on: November 17, 2012, 07:14:03 am » |
penso con terrore a cosa potrai essere capace di fare quando realizzerai il primo circuito con due sonde PT100 per rilevare il range di variazione 
|
|
|
|
|
Logged
|
|
|
|
|
Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #36 on: November 17, 2012, 07:27:44 am » |
Non sapevo di incutere tanto timore 
|
|
|
|
|
Logged
|
Gianfranco
|
|
|
|
0
Online
Tesla Member
Karma: 81
Posts: 8184
:(){:|:&};:
|
 |
« Reply #37 on: November 17, 2012, 11:07:36 am » |
ah, quindi hai preso la fomrula che usi - la formula vera = formula dell'errore, ma non vedo come ti possa aiutare la cosa, puoi usare direttamente la formula vera e bon. il problema quì è capire se la formula vera è abbastanza veritiera per la precisione che vuoi ottenere, no?
|
|
|
|
|
Logged
|
|
|
|
|
Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #38 on: November 17, 2012, 11:42:16 am » |
La formula vera (1) è quella che ho trovato in rete, tra le specifiche della resistenze al platino. Non posso usarla direttamente perchè restituisce la Resistenza in funzione della temperatura, mentre io ho bisogno di conoscere la temperatura in funzione della resistenza. Per tale ragione ho utilizzato Excel per trovarmi la formula inversa (2), soltanto che, vuoi per le approssimazioni, vuoi per la (forse) poca affidabilità di excel, produce un errore che in ogni caso ho calcolato e quindi eliminato aggiungendo un secondo passaggio (funzione 3). In ogni caso ancora non posso utilizzare questa funzione perchè è ideale, ovvero non tiene conto delle imprecisioni che produce il mio hardware, che, se non ho fatto troppi errori, aggiunge 2ohm rispetto ai valori "ideali", per cui non ho 100 ohm a 0°C bensì 102 ohm; non ho 138,5 ohm a 100°C bensì 140,5ohm. Perchè sto insistendo con la formula ideale? Mi è stato già consigliato di realizzare una semplice funzione partendo dai due punti di riferimento, cosa che ho fatto. Purtroppo questa funzione approssima il dato finale. Perchè? Leggendo in rete si trova che per ogni °C la resistenza subisce una variazione di 0,385 ohm. Purtroppo si tratta di un valore medio, perchè a 0°C la variazione è di 0,3909 ohm, mentre a 100°C è di 0,3793 ohm. Qui trovi una tabella dei valori ricavati partendo dalla formula base: http://www.sevimpianti.it/tabella_pt100.htmL'ideale sarebbe, come consigliato da tutti quanti, avere uno strumento già tarato su cui tarare il mio. Purtroppo non dispongo uno strumento simile, per cui devo accontentarmi dei punti di fusione ed ebollizione!
|
|
|
|
|
Logged
|
Gianfranco
|
|
|
|
Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #39 on: November 18, 2012, 07:49:58 am » |
In ogni caso, paranoie a parte, ecco lo schema:  Uploaded with ImageShack.usPS: ho apportato una correzione allo schemaRispetto allo schema presente nel topic http://arduino.cc/forum/index.php/topic,17349.0.html, ho modificato la RBias che ho portato a 2.2K e il pin 6 (SEL 3) che da GND ho portato a +5V in modo da poter usare la Modalità 5 dell'integrato, come specificato nel datasheet per l'utilizzo di una PT100 a 4 vie. Ovviamente il codice che ho riportato qualche post fa è stato modificato adeguatamente.
|
|
|
|
« Last Edit: November 27, 2012, 09:04:47 am by GianfrancoPa »
|
Logged
|
Gianfranco
|
|
|
|
Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #40 on: November 28, 2012, 04:49:54 am » |
Ecco il board:  Allego pure i file di Eagle Ricordo che questo è lo schema per utilizzare una PT100 a quattro fili, nella modalità 5 indicata nel datasheet.
|
|
|
|
« Last Edit: November 28, 2012, 04:57:49 am by GianfrancoPa »
|
Logged
|
Gianfranco
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 44
Arduino rocks
|
 |
« Reply #41 on: December 02, 2012, 04:51:59 am » |
In ogni caso, paranoie a parte, ecco lo schema:  Uploaded with ImageShack.usPS: ho apportato una correzione allo schemaRispetto allo schema presente nel topic http://arduino.cc/forum/index.php/topic,17349.0.html, ho modificato la RBias che ho portato a 2.2K e il pin 6 (SEL 3) che da GND ho portato a +5V in modo da poter usare la Modalità 5 dell'integrato, come specificato nel datasheet per l'utilizzo di una PT100 a 4 vie. Ovviamente il codice che ho riportato qualche post fa è stato modificato adeguatamente. rref non dovrebbe essere 100ohm per le pt100? edit: ah no, come non detto  . Comunque sto provando il tuo codice e il tuo schema (ho uno uti smartec anche io), ma mi stampa valori di resistenza intorno a 8500..C'è qualcosa che non mi torna  cosa potrebbe essere? ri-edit: come non detto. penso che sto usando il vecchio codice con il nuovo schema  potresti postare anche il nuovo codice?
|
|
|
|
« Last Edit: December 02, 2012, 06:04:58 am by sollazzo »
|
Logged
|
|
|
|
|
Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #42 on: December 02, 2012, 06:05:55 am » |
Ottimo!! Qualcuno con cui confrontarmi è splendido!! Allora, il tuo risultato è molto strano! La tua pt1000 è a 4 fili?? come li hai collegati i fili nel pinheader JP1? supponendo che i tuoi 4 fili siano in due coppie di colori, rosso e bianco come nel mio caso, devi mettere quelli bianchi nei pin 1-2, e quelli rossi nei pin 3-4. Ovviamente va bene anche il contrario 
|
|
|
|
|
Logged
|
Gianfranco
|
|
|
|
Palermo
Offline
God Member
Karma: 2
Posts: 700
Arduino rocks
|
 |
« Reply #43 on: December 02, 2012, 06:31:33 am » |
In ogni caso prova questo codice se puoi, ho portato il campionamento a 20 secondi ed immagazzino ogni volta il valore della resistenza e non della temperatura: #include <stdio.h> #include "pins_arduino.h" #include <LiquidCrystal.h>
#define UTI_PIN 5 #define UTI_RESISTANCE_REF 1000
double TempStorage[40]; //Contiene le rilevazioni int ArrayMax = 39; // Dimensione massima array: dimensione TempStorage - 1 double Media = 0.0; //Contiene il valore della temperatura media int MediaCount = 0; //Contatore che permette il calcolo della media solo dopo aver riempito completamente l'array int CurPos = 0; //Contiene la posizione corrente nell'array
LiquidCrystal lcd(12, 11, 6, 4, 3, 2); unsigned long samplingMillis, printMillis; int samplingTime = 500; //In ms, frequenza di campionamento int printTime = 1000; //in ms, frequenza di stampa dei dati
void setup() { Serial.begin(9600); pinMode(UTI_PIN, INPUT); Serial.print("Avvio PT100"); Serial.print("\n"); lcd.begin(16, 2); lcd.print("PT100"); CurPos=-1; //Inizializzo la posizione nell'array for (int i=0;i<= ArrayMax;i++) { //Inizializzo array a zero TempStorage[i] = 0.0; } delay(3000); }
int ReadUTI(uint8_t pin, double * temp,int refRes) //Ottimizzato per PT100 4 fili - Modalità 5 (4 fasi) { int state = HIGH; int i,startindex=-1; uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); uint8_t stateMask = (state ? bit : 0); unsigned long width[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; double nOff=0,nAB=0,nCD=0,nBC=0,nDF=0; while ( (*portInputRegister(port) & bit) != stateMask) ; for(i=0;i<10;i++) { while ( (*portInputRegister(port) & bit) == stateMask) width[i]++; while ( (*portInputRegister(port) & bit) != stateMask) width[i]++; } for(i=1;i<10;i++) { if(i<6) { if(width[i]<width[i+2]&&width[i]<width[i+3]&&width[i]<width[i+4]&&width[i+1]<width[i+2]&&width[i+1]<width[i+3]&&width[i+1]<width[i+4]) { startindex=i; i=10; } } } if(startindex!=-1) { nOff=width[startindex]+width[startindex+1]; nAB=width[startindex+2]; nCD=width[startindex+3]; nBC=width[startindex+4];
*temp=((nCD-nOff)/(nAB-nOff))*refRes; return 1; } else { return 0; } }
void readTemp() { double temp; if(ReadUTI(UTI_PIN,&temp,UTI_RESISTANCE_REF)) { if (CurPos<ArrayMax){CurPos++;} else { CurPos=0; } //Gestisce la posizione del cursore all'interno dell'array TempStorage[CurPos]=temp; //Registra la temperatura all'interno dell'array if (MediaCount<(ArrayMax+4)) {MediaCount++;} //Calcola la media solo se l'array è stato riempito completamente else { Media =0.0; for (int i=0;i<=ArrayMax;i++) { Media = Media + TempStorage[i];} Media = Media / (ArrayMax+1); } } else { printTempError(); //Se l'UTI non riceve alcuna temperatura, restituisce errore } }
void printTempError() { Serial.print("Not Found"); Serial.print("\n"); lcd.setCursor(0, 1); lcd.print("NotFound"); }
void printTempMedia() { if (MediaCount < (ArrayMax+4)) { //Stampa la media solo se l'array è completamente pieno Serial.print("Inizializzazione Sensore: "); Serial.print(CurPos); Serial.print("\n"); lcd.setCursor(0, 1); lcd.print("Init"); } else { //double TempNorm = 2.596415876*Media-264.95648; //Formula ricavata dalla calibrazione a 0 e 100 °C double TempNorm = 2.624704336*Media-266.3919005; //double TempNorm = (0.0000000000004 * pow(Media,6)) - (0.0000000002 * pow(Media,5)) + (0.00000007 * pow(Media,4)) - (0.00002 * pow(Media,3)) + (0.0038 * pow(Media,2)) + (2.1705 * Media) - 241.09; //TempNorm = TempNorm - ((-0.00008 * pow(TempNorm,2)) + (-0.0086 * TempNorm) - 0.6422); Serial.print(TempNorm); Serial.print(" - "); Serial.print(Media); Serial.print("\n"); lcd.begin(16, 2); lcd.print(Media); lcd.setCursor(0, 1); lcd.print(TempNorm); } }
void loop() { if ((millis()- samplingMillis) > samplingTime) { samplingMillis = millis(); readTemp(); } if ((millis()- printMillis) > printTime) { printMillis = millis(); printTempMedia(); } }
|
|
|
|
|
Logged
|
Gianfranco
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 44
Arduino rocks
|
 |
« Reply #44 on: December 02, 2012, 08:26:30 am » |
esatto ho pt100 a 4 fili(colori diversi, bianco-blu-maroone-nero). il bianco blu dovrebbe essere il rosso e marrone nero il bianco. ho collegato come hai detto te e ricaricato il codice. adesso come resistenza mi rileva sempre 0  Il circuito l'ho appena controllato e dovrebbe essere giusto edit: temo che ho sbagliato i colori: il bianco dovrebbe andare col nero e il marrone con il blu. ora riprovo a vedere se cambia
|
|
|
|
« Last Edit: December 02, 2012, 08:46:33 am by sollazzo »
|
Logged
|
|
|
|
|
|