/* PT100.cpp - Library for measuring temperature with a PT100. Created by João Lino, June 24, 2015. Released into the public domain. */ #include "Arduino.h" #include "PT100.h" PT100::PT100(char *name, int OutputPin_SensorPower, int InputPin_TemperatureReading, int TimeBetweenReadings, float ADCVmax, float Vs, float R1) { _name = name; _OutputPin_SensorPower = OutputPin_SensorPower; _InputPin_TemperatureReading = InputPin_TemperatureReading; _TimeBetweenReadings = TimeBetweenReadings; _ADCVmax = ADCVmax; _Vs = Vs; _R1 = R1; _temperatureAverage = 24.0; _measuredTemperature = 24.0; _lastTemperatureRead = 0; _VoutAnalogSample = -1; _VoutPreviousAnalogSample = -1.0; _temperatureMeasurementsMarker = 0; _rPT100MeasurementsMarker = 0; _measuredTemperatureDeviation = 0.0; _sampleDeviation = 0.0; analogReference(INTERNAL1V1); // EXTERNAL && INTERNAL2V56 && INTERNAL1V1 pinMode(_OutputPin_SensorPower, OUTPUT); // setup temperature sensor input pin digitalWrite(_OutputPin_SensorPower, LOW); // initialize sensor on } void PT100::setPower(float ADCVmax, float Vs) { _ADCVmax = ADCVmax; _Vs = Vs; } void PT100::safeHardwarePowerOff() { digitalWrite(_OutputPin_SensorPower, LOW); // Turn temperature sensor OFF for safety } void PT100::measure(boolean ln) { if(millis() - _lastTemperatureRead >= _TimeBetweenReadings) { //time to measure temperature /** measure Vout analog sample */ digitalWrite(_OutputPin_SensorPower, HIGH); // initialize sensor on delay(10); _VoutAnalogSample = analogRead(_InputPin_TemperatureReading) + _sampleDeviation; // Get a reading digitalWrite(_OutputPin_SensorPower, LOW); // initialize sensor on _lastTemperatureRead = millis(); // Mark time of temperature reading _rPT100MeasurementsMarker++; // Position reading buffer marker at the last updated position if(_rPT100MeasurementsMarker >= TEMPERATURE_AVERAGE_VALUE_I) _rPT100MeasurementsMarker = 0; // Check that it has not gone out of the buffer range _rPT100Measurements[_rPT100MeasurementsMarker] = _VoutAnalogSample; float Vout = GetMedian(_rPT100Measurements) * _ADCVmax / CONSTANT_ADC_STEP_COUNT; float Rx = _R1 / ( _Vs / Vout - 1.0); /** Calculate temperature value */ _measuredTemperature = 1.08271 * pow(10.0, -13.0) * (3.12508 * pow(10.0, 16.0) - 5.65566 * pow(10.0, 6.0) * sqrt(3.51501 * pow(10.0, 19.0) - 4.61805 * pow(10.0, 16.0) * Rx)); #ifdef DEBUG Serial.print(_name); Serial.print(","); //Serial.print(_VoutAnalogSample); Serial.print(GetMedian(_rPT100Measurements)); Serial.print(","); if(ln) Serial.println(""); #endif } } float PT100::GetMedian(int array[]){ int sorted[TEMPERATURE_AVERAGE_VALUE_I]; float value = 0.0; for(int x = 0; x < TEMPERATURE_AVERAGE_VALUE_I; x++) { sorted[x] = array[x]; } //ARRANGE VALUES for(int x = 0; x < TEMPERATURE_AVERAGE_VALUE_I; x++){ for(int y = 0; y < TEMPERATURE_AVERAGE_VALUE_I - 1; y++){ if(sorted[y]>sorted[y+1]){ int temp = sorted[y+1]; sorted[y+1] = sorted[y]; sorted[y] = temp; } } } //CALCULATE THE MEDIAN (middle number) if(TEMPERATURE_AVERAGE_VALUE_I % 2 != 0){// is the # of elements odd? int temp = ((TEMPERATURE_AVERAGE_VALUE_I+1)/2)-1; value = (float) sorted[temp]; } else{// then it's even! :) value = ((float) ( sorted[(TEMPERATURE_AVERAGE_VALUE_I/2)-1] + sorted[TEMPERATURE_AVERAGE_VALUE_I/2] )) / 2.0; } return value; } float PT100::GetMode(float new_array[]) { int ipRepetition[TEMPERATURE_AVERAGE_VALUE_I]; for (int i = 0; i < TEMPERATURE_AVERAGE_VALUE_I; i++) { ipRepetition[i] = 0;//initialize each element to 0 int j = 0;// while ((j < i) && (new_array[i] != new_array[j])) { if (new_array[i] != new_array[j]) { j++; } } (ipRepetition[j])++; } int iMaxRepeat = 0; for (int i = 1; i < TEMPERATURE_AVERAGE_VALUE_I; i++) { if (ipRepetition[i] > ipRepetition[iMaxRepeat]) { iMaxRepeat = i; } } return new_array[iMaxRepeat]; } float PT100::getCurrentTemperature() { return _measuredTemperature + _measuredTemperatureDeviation; // - 4.41; } float PT100::getMeasuredTemperatureDeviation() { return _measuredTemperatureDeviation; // - 4.41; } float PT100::setMeasuredTemperatureDeviation( float measuredTemperatureDeviation) { if( _measuredTemperatureDeviation != measuredTemperatureDeviation ) { _measuredTemperatureDeviation = measuredTemperatureDeviation; for( int i = 0; i < TEMPERATURE_AVERAGE_VALUE_I; i++ ) { _temperatureMeasurements[i] = _temperatureMeasurements[i] + ( _measuredTemperatureDeviation * -1 ); } } return _measuredTemperatureDeviation; // - 4.41; } float PT100::setSampleDeviation( float sampleDeviation) { _sampleDeviation = sampleDeviation; return _sampleDeviation; }