/* Alle Angaben ohne Gewaehr ! 2023-11-04 */ #define OFFSET 13 // 0-Offset des ADCs, Anpassung notwendig #define DEF_BAUDRATE 19200 #define ADC_MIN 0 #define ADC_MAX (4095 - OFFSET) // bei 12 Bit #define PT_IN_0 26 // analog Eingang A0 #define UNTERLAUF -99 // Fehler, auch bei Kurzschluss #define UEBERLAUF 999 // Fehler, auch bei offenem Eingang #define R_PT0 1000.0 // bei 0 Grad C #define R_REF 1200.0 // ext. Widerstand mit 0,1% #define R_ZULEITUNG 0 // bei laengeren Leitungen unbedingt anpassen #define PT_FAKTOR 3.85 // schon mit 1000.0 skaliert //#define IO_BANK0_BASE 0x40014000UL // ist auch schon in addressmap.h definiert #define GPIO0_CTRL (*(volatile unsigned int*)(IO_BANK0_BASE + 0x4u)) #define GPIO1_CTRL (*(volatile unsigned int*)(IO_BANK0_BASE + 0xcu)) #define IO_BANK0_GPIO0_CTRL_OUTOVER_Pos (8UL) /*!< OUTOVER (Bit 8) */ #define IO_BANK0_GPIO1_CTRL_INOVER_Pos (16UL) /*!< INOVER (Bit 16) */ #define NOS 100 // Anzahl fuer Mittelwert #define INL_INDEX 2 // nur dieses Segment verwenden const int INL_tab[][4] = {{ 0, 511,0,-3}, { 512,1535,7,-2}, {1536,2559,5,-6}, // INL_index = 2; hier genutztes Segment {2560,3583,3,-6}, {3584,4095,3,-1}}; int ADC_korrigiert(int eingang) { int temp_wert = 0, i, INL_spanne = 0; float index, korrektur = 0.0; for(i = 0; i < NOS; i++) temp_wert += analogRead(eingang); temp_wert /= NOS; // etwas filtern /* fuer automatische Suche / Segmentumschaltung while( temp_wert > INL_tab[i][1]) i++; // Segment in der Tabelle suchen */ i = INL_INDEX; // hier nur dieses Segment verwenden if(temp_wert <= INL_tab[i][0]) temp_wert = ADC_MIN; else if(temp_wert >= INL_tab[i][1]) temp_wert = ADC_MAX; else { index = temp_wert - INL_tab[i][0]; // Stratwert des Segmentes abziehen index /= (float)(INL_tab[i][1] - INL_tab[i][0]); // rel. Lage im Segment INL_spanne = INL_tab[i][2] - INL_tab[i][3]; // Korrekturbereich: Anfang - Ende korrektur = INL_tab[i][2] - INL_spanne * index; // ohne Rundung temp_wert -= korrektur; } Serial.print(temp_wert); Serial.print(" "); Serial.print(korrektur); Serial.print(" "); Serial.print(INL_spanne); Serial.print(" "); return(temp_wert); } int lese_PT1000(int ad_eingang) // liest den ADC-Eingang und rechnet auf Grad Celsius um { int ADC_wert, n; float temperatur, PT_x; pinMode(PT_IN_0, INPUT); // PT1000 freigeben analogRead(ad_eingang); // dummy ADC_wert = ADC_korrigiert(ad_eingang); // und Kanal messen pinMode(PT_IN_0, OUTPUT); // PT1000 wieder kurzschließen if(ADC_wert == ADC_MAX) temperatur = UEBERLAUF; else if(ADC_wert == ADC_MIN) temperatur = UNTERLAUF; else { ADC_wert -= OFFSET; if(ADC_wert < ADC_MAX) { // nur gueltige Werte auswerten PT_x = R_REF * ADC_wert / (ADC_MAX-ADC_wert); // Widerstand ausrechnen PT_x = PT_x - R_PT0 - R_ZULEITUNG; // Offset fuer 0 Grad abziehen temperatur = PT_x / PT_FAKTOR; // und auf Grad C skalieren } else temperatur = UEBERLAUF; // falls PT1000-Zuleitung offen } // lokalen, korrigierten Wert testweise ausgeben Serial.print("ADC: "); Serial.print(ADC_wert); Serial.print(" "); return temperatur; } void setup() { Serial.begin(19200); // per USB ausgeben analogReadResolution(12); } void loop(void) { Serial.print(lese_PT1000(PT_IN_0)); // per UART ausgeben Serial.println(" °C"); // Grad-Celsius delay(200); // 0,2 Sekunden warten }