unknow bug; float change value

Hi.

I wrote a library to an RTD sensor. I wanted to add a function to calibrate the internal reference resistor.
I store value of the calibration in a float array but. when a run the reading input loop, the value of the float change to the ouput temp. there is now place that I can found for the valu to change.

there the part of the c++ where the bug came from.

void RTD10k::read(int selecInput) {//do reading loop

  //average calculation

  int averageIn = average(selecInput);

  if (_reso = 10) {
    map(averageIn, 0, 1023, 0, 4095); //mapping for 10bits resolution
  }

  //electric value calculation
  Vin = (averageIn) * _Vref / 4095;
  
  Serial.println(_RrefOffset[selecInput]);  <===== _RrefOffset is the bugging float
  float Rref = 10000;
//  Rref = 10000 + _RrefOffset[selecInput];
  Serial.println(Rref);
  resistance = (Vin / (_Vref - Vin) * Rref);


_temp = (1/( (1/3950.00) * log(resistance/10000.00) +  (1/298.00) )  -273);  // resistance to temp formula
if (_temp < -50){
  _temp = -50;  
}
temp = _temp;   /// <=====temp float seem to push the _RrefOffset[] value

}



void RTD10k::calibrateRref(int input, float offset){ // this runnig at setup loop

 _RrefOffset[input] = offset;
 Serial.println(_RrefOffset[input]);
}

troubleshoot have demonstrate by now that the value follow the value, I mute any other function in the sketch an the problem persist so I conclude the bug is inside here somewhere but cant find it.

posting complete sketch here:

//main .ino

/* RTD10kB3950 is a simple, low cost, maximum precision formula for an RTD NTC (negative tempeture coeficient) 
  of 10Kohm at 25 degres C with a Beta of 3950.
  A Excel file will be join with the calculation table I used if you would like to use another Beta.
  Notice that if the resistance at 25C is different than 10K, the formula would be more difficult to addapt.

Formula is:

B = Beta,
T = current temperature
R25C = resistance of RTD at 25 Celsius
R = RTD resistance at current temp

    -------------------
    
    T = ( 1/ ( (1/B) * ln( R/R25C ) +  ( 1/298.00 ) )  -273 );
    
    -------------------

    ln in natural logarythme, will be log() fonction in arduino math.h library 

    File created 20/05/2015

    By Nitrof
*/


#include <RTD10k.h>

int Ainput0 = 0; //set input pin for RTD
float output = 0; //ouput variable
String strRoomTemp = "Room Tempeture"; //set the name of the input for serial print 

RTD10k Ain;//start an instance of library

void setup() {
  Serial.begin(9600);//start serial port
  analogReadResolution(12);//arduino DUE only
  Ain.initialize(3.3,12); //set the reference input voltage 3.3V or 5V, and input resolution 10 or 12 (arduino DUE only)
//  Ain.calibrateRref(0,-14.66); //calibrate shield Reference resistor, (analog in, calibration value find with calibration sketch)
}

void loop() {
  Ain.read(Ainput0); //do the readinf temps loop
  output = Ain.temp; //read the result of reading
  Ain.serialInputMon(strRoomTemp); //pring all value to the serial port
  delay (1000);
}


//header file;

/* RTD10kB3950 is a simple, low cost, maximum precision formula for an RTD NTC (negative tempeture coeficient) 
  of 10Kohm at 25 degres C with a Beta of 3950.
  


    File created 20/05/2015

    By Nitrof
*/

#ifndef RTD10k_h
#define RTD10k_h
#include "Arduino.h"
#include <math.h>
    
class RTD10k
{
  public:
    float temp;   //give tempeture
    float Vin;  //voltage to the analoge pin input
    float resistance;   //resistance in ohm of the RTD
    int average(int inputAv); //average calculation function

    void initialize(float Vref = 5,int reso = 10);  //referance voltage 3.3 or 5 V and input resolution
    void read(int selecInput);
    void serialInputMon(String StrInput);
    void runCalibration(int input);
    void calibrateRref(int input, float offset);

  private:
  
    int _selecInput;
    float _temp;
    int _reso;
    float _Vref;
    float _RrefOffset[];
   
};

#endif


//cpp file

/* RTD10kB3950 is a simple, low cost, maximum precision formula for an RTD NTC (negative tempeture coeficient) 
  of 10Kohm at 25 degres C with a Beta of 3950.


Formula is:

B = Beta,
T = current temperature
R25C = resistance of RTD at 25 Celsius
R = RTD resistance at current temp

    -------------------
    
    T = ( 1/ ( (1/B) * ln( R/R25C ) +  ( 1/298.00 ) )  -273 );
    
    -------------------

    ln in natural logarythme, will be log() fonction in arduino math.h library 

    File created 20/05/2015

    By Nitrof
*/

#include "Arduino.h"
#include "RTD10k.h"

const int numReadings = 20; //set average to count

//////////---------------------------------------////////////////////////////////////////////

void RTD10k::initialize(float Vref,int reso) {
  _Vref = Vref;
  _reso = reso;
  for (int i = 0; i < numReadings; i++){
    _RrefOffset[i] = 0;
  }
}

//////////---------------------------------------////////////////////////////////////////////

void RTD10k::read(int selecInput) {//do reading loop

  //average calculation

  int averageIn = average(selecInput);

  if (_reso = 10) {
    map(averageIn, 0, 1023, 0, 4095); //mapping for 10bits resolution
  }

  //electric value calculation
  Vin = (averageIn) * _Vref / 4095;
  
  Serial.println(_RrefOffset[selecInput]);
  float Rref = 10000;
//  Rref = 10000 + _RrefOffset[selecInput];
  Serial.println(Rref);
  resistance = (Vin / (_Vref - Vin) * Rref);


_temp = (1/( (1/3950.00) * log(resistance/10000.00) +  (1/298.00) )  -273);  // resistance to temp formula
if (_temp < -50){
  _temp = -50;  
}
temp = _temp;

}

//////////---------------------------------------////////////////////////////////////////////

void RTD10k::serialInputMon(String(ipName)) {    ///print all value for an input on demande
  //print on serial port input reading  
  if (Serial.available() > 0) ; {
    Serial.println( "input; " + ipName + "; " + Vin + "Volt; R= " + resistance + " ohm Tempeture= " + temp + "C");
  }
}

//////////---------------------------------------////////////////////////////////////////////

///////////////****** calibration functions !!!
void RTD10k::runCalibration(int selectInput){

 int averageIn = 0;
 averageIn = average(selectInput);

 if (_reso = 10) {
    map(averageIn, 0, 1023, 0, 4095); //mapping for 10bits resolution
  }
  
  //electric value calculation
  Vin = averageIn * _Vref / 4095;

  float realRref = (_Vref-Vin)*10000/Vin;
  float Offset = 0;
  Offset = 10000-realRref;

  String prntStatus = "input " ;
  prntStatus += String(selectInput) += ":";
  prntStatus +=  String(realRref) += "ohm , correction = ";
  prntStatus += String(Offset);

  if (Serial.available() > 0) ;{
    Serial.println(prntStatus);
  }
}

//////////---------------------------------------////////////////////////////////////////////



void RTD10k::calibrateRref(int input, float offset){

 _RrefOffset[input] = offset;
 Serial.println(_RrefOffset[input]);
}

//////////---------------------------------------////////////////////////////////////////////

int RTD10k::average(int inputAv){

  int output = 0;
  int count = 0;
  for (int i = 0; i < numReadings; i++){
    int reading = analogRead(inputAv);
    count += reading;
  }
  output = count/numReadings;
  return output;
}

//////////---------------------------------------////////////////////////////////////////////
  if (_reso = 10) {

Assigning the value of 10 to reso in an if statement is almost certainly wrong. = != ==.

    map(averageIn, 0, 1023, 0, 4095); //mapping for 10bits resolution

map() returns a value. If the returned value is not important, it is pointless to call the function.

Beyond this, I can't understand what your problem is.

Hi Paul.

the if statement was effectively wrong. I fix it. but that didnt fix my problem. i’ll try to explain it better.

in my setup I set in a matrix a float value for an ajustement of my reference resistor input on my shield(simple voltage divider whit an RTD).

so the resistor value of 10k in addition the the offset.

float Rref = 10000;
Rref = 10000 + _RrefOffset[selecInput];

but no where a change the value of <_RrefOffset> execept in the setup function;

void RTD10k::calibrateRref(int input, float offset){

 _RrefOffset[input] = offset;
 Serial.println(_RrefOffset[input]);
}

the value is good on the serial print until the reading loop running in void loop run for the second time. then the value of <_RrefOffset[selecInput]> becam the one of and I dont understand how…

this is the function

void RTD10k::read(int selecInput) {//do reading loop

  //average calculation

  int averageIn = average(selecInput);

  if (_reso = 10) {
    map(averageIn, 0, 1023, 0, 4095); //mapping for 10bits resolution
  }

  //electric value calculation
  
  Vin = (averageIn) * _Vref / 4095;
  
  Serial.println(_RrefOffset[selecInput]);
  float Rref = 10000;
//  Rref = 10000 + _RrefOffset[selecInput];
  Serial.println(Rref);
  resistance = (Vin / (_Vref - Vin) * Rref);


_temp = (1/( (1/3950.00) * log(resistance/10000.00) +  (1/298.00) )  -273);  // resistance to temp formula
if (_temp < -50){
  _temp = -50;  
}
temp = _temp;

}

I wish I’m enough clear…

thank

  if (_reso = 10) {
    map(averageIn, 0, 1023, 0, 4095); //mapping for 10bits resolution
  }

This does NOT address either of the issues that I pointed out. Why should I continue reading?

it use someehwre else cause i use arduino due and set it at 12 bit analogRead. the function is there for the library to be compatible with uno or other 10 bit board. it is maybe not a good way... but i'm not a real programmer....

it use someehwre else cause i use arduino due and set it at 12 bit analogRead. the function is there for the library to be compatible with uno or other 10 bit board. it is maybe not a good way... but i'm not a real programmer....

I don't understand a bit of this, except that last part. The correct code would be

  if (_reso == 10) {
    averageIn = map(averageIn, 0, 1023, 0, 4095); //mapping for 10bits resolution
  }

We can't see what selectInput is in that function. We can't see that it is valid, and within the range of the array.

for map(), humm thnk feel dumm…

for selectInput;
it is an analog input, so in my exemple , value of 0.

for the array , I not sure to understand, so thats what I got;
in the header file

float _RrefOffset[];

and initiate it on a setup function:

 for (int i = 0; i < 12; i++){
    _RrefOffset[i] = 0;

and the configuration runnig at setup to:

void RTD10k::calibrateRref(int input, float offset){ /// (analogInput associated, offset)

 _RrefOffset[input] = offset;
 Serial.println(_RrefOffset[input]);
}

here my offset was -14.66

ok, I better commented each line of code inside the function. maybe it will help to better understand.

and here a shema of the input:

3.3V — (reference resistor) — | — (RTD resistor) — GND
|
analogPin

this is what is runnig the loop in void loop. other valu are set un setup loop.
so the RrefOffset is initiate from 0 to 10 = 0
after, position 0 in the array is set to -14.66

void RTD10k::read(int selecInput) {//do reading loop


  int averageIn = average(selecInput); //analoRead(selecInpput)

  if (_reso == 10) {
    averageIn = map(averageIn, 0, 1023, 0, 4095); //mapping for 10bits resolution, else consider 12bit
  }

  //electric value calculation
  
  Vin = (averageIn) * _Vref / 4095;  //calculate voltage to analog pin
  
  Serial.println(_RrefOffset[selecInput]); //print the offset of reference resistor store in matrix
  float Rref = 10000; //set default resistor value to 10k ohm
//  Rref = 10000 + _RrefOffset[selecInput]; //add the offset to default reference resistor value
  Serial.println(Rref); //print the reference resistor value
  
  resistance = (Vin / (_Vref - Vin) * Rref); //calculate the resistance plug into the input


_temp = (1/( (1/3950.00) * log(resistance/10000.00) +  (1/298.00) )  -273);  // resistance to temp formula
if (_temp < -50){ //limite the lower range to -50C
  _temp = -50;  
}
temp = _temp; //reurn tempeture in C degre

}

in the first past of the loop, the value same to be ok…

that’s the print statement return:

-14.66 // _RrefOffset[selecInput]
10000.00 // Rref value
input; Room Tempeture; 1.65Volt; R= 9995.12 ohm Tempeture= 25.01C //all the value print by the serialInputMon function previosly posted.

the second past that’s the print statement:

25.01 //_RrefOffset[selecInput]
10000.00 //// Rref value
input; Room Tempeture; 1.65Volt; R= 9985.36 ohm Tempeture= 25.03C

it appear the the _RrefOffset[selecInput] following the temperature value ( that is the float int the Function.

juste to be sure… reposting the serialInputMon function to…:

void RTD10k::serialInputMon(String(ipName)) {    ///print all value for an input on demande
  //print on serial port input reading  
  if (Serial.available() > 0) ; {
    Serial.println( "input; " + ipName + "; " + Vin + "Volt; R= " + resistance + " ohm Tempeture= " + temp + "C");
  }
}

for the array , I not sure to understand, so thats what I got; in the header file

Not bloody likely. You can NOT define an array with no size.

Hooo ! ...

that's it... it works...

Thanks a lot Paul for your help and patiance.

have a nice day !