Need some help with interger, float maths

Hello everyone

I have read this somewhere in the past before attempting to do this but now for the life of me I can't seem to find that previous post that I read. So here it is in a new post.

I'm trying to write a calibration procedure and want to calculate a decimal value to use as a float which I want to multiply with an integer value after that. The problem that I'm picking up is that the float is rounding off downwards, i.e. if I am expecting a result of 0.1 or 0.55 or 0.99 the result will always be 0.00

Likewise if I expect a result of 1.15, 1.67 or 1.97 the calculation only yields 1.

Is there a way of getting around this so that I can get the 1.67 value or something similar? I then want to use my float value as a multiplication factor that will act as a calibration factor. When the float is multiplied with an Integer I understand that the Integers in the formula are converted floats for the duration of the calculation and then the result is converted back to a Integer again?

The code is as follows:

        Calibration_Factor1 = Ref_Temp1 / Temp_Before;    

        // calculate the temperature value
        Temp_After = (Raw_Value2 / 3.755) * Calibration_Factor1;

Calibration_Factor1 is the factor needed to shift the current Temperature reading (Temp_Before) to the applied temperature reading (Ref_Temp1) Calibration_Factor1 is a Float.

Ref_Temp1 is the temperature value inserted by the user, temperature value applied to the sensor. [Integer]

Temp_Before is the analog value read / 3.755 to get the temperature value (The 3.755 since the thermocouple ic is giving 10mV per degree Celsius out - approximate value. [Integer]

Temp_After is the adjusted temperature so that the formula compensates for an inaccurate reading to represent the actual temperature applied to the sensor. [Integer]

Raw_Value2 is the analog value converted to a digital value i.e. the value read from the analog input. [Integer]

So in other terms:

        Float = Interger / Interger;    

        // calculate the temperature value
        Interger = (Interger / 3.755) * Float;

Thanks in advance for the help, it is much appreciated.

Calibration_Factor1 = Ref_Temp1 / Temp_Before;

if Ref_temp1 is less than Temp_before, the result of the division will be zero. You need to force the division to be done as floating point:

Calibration_Factor1 = (float)Ref_Temp1 / Temp_Before;

Pete

Are you able to work in smaller units (eg, millimetres rather than meters), so your 1.670 becomes 1670. You then only need to convert at the end of the calculation chain when you want to use the number. This technique allows you to retain significant digits and in many cases allows the use of integer arithmetic throughout, which is faster and has less approximations.

Hello el_supremo

Apologies for the late reply, I didn't get a chance to test out your words of wisdom. Supreme indeed, thanks for the advice on how to force the calculation to be done as a floating point, I've tested it now and eureka.

@marco_c

Unfortunately I have to work with fractions as it is operating as a multiplication factor to adjust the end value. So the temperature calibration factor won't be able to be converted to millimeters or meters but thanks for your input, much appreciated. Wish I could do it as it would save me valuable program space but that is a problem for another day.

can you post a minimal working sketch that shows the problem?

I think you missed the point in my example. If you are dealing in temperature then work in tenths or hundredths of a degree to eliminate the decimals to the level of significant digits you need.

Hello Marco_C

I understood the reference, I just don't see how I will be able to do it without a float, I'm sorry if my response came across as cheeky, that wasn't my intention .

@ Robtillaart

Here is the code that is currently working, still tweaking it as I'm going along. The problem was solved with the advice from el_supremo. The issue was at the line that read:

alibration_Factor1 = (float)Ref_Temp1 / Temp_Before;

but after inserting the (float) in brackets it solved the issue.

  //****************************************************************************************************************************************************************************
  //**************************************                            One Point Calibration                              *******************************************************
  //****************************************************************************************************************************************************************************
  
  
  void One_Point_Calibration ()
  { 
    
      //Prompt user to enter the reference temperature that is to be applied.
      GLCD.CursorToXY(13  , 5);  
      GLCD.print("Please insert the");
      GLCD.CursorToXY(10, 14);  
      GLCD.print("ref. temp that you ");
      GLCD.CursorToXY(7, 23);  
      GLCD.print("wish to apply:"); 

      if ( Loop_One_Time_Run_Through_Detector == 0 )  // Tests whether the Loop detector is 0, if it is, it sets the Ref Temp value to the value read from the sensor pin. The Loop detector is declared globally otherwise if it was declared locally, 
      {                                               // it would reset the value everytime the loop runs through and then the sensor value would constantly be set to the Ref Temp, effectively disabling the value to be changed.
        Raw_Value = analogRead(sensorPin);   
        Ref_Temp = Calibration_Factor1 * ( Raw_Value / 3.755 );
        Loop_One_Time_Run_Through_Detector++;
      }
      
      Ref_Temp1 = Ref_Temp;      // Sets Ref Temp1 to the Ref_Temp Value so that the Ref_Temp value can be edited to the value that the user desires. This statement keeps the Ref_Temp changes seperate from the stored Ref_Temp1 value

      Read_Buttons();
      Read_Buttons_Quickly();    // Function changes the Ref_Temp value depending on whether it is incremented or decremented.
      
      Temp = Ref_Temp1;          // Sets applicable Ref_Temp to Temp for printing purposes. (Ref_Temp1 is the applied temperature that the user is applying.

      GLCD.CursorToXY(91, 23);               
      Temp_Printing();    
      
      GLCD.DrawCircle(113,24, 1);  // X, Y, Radius; Draws a little circle to be the Degree symbol    
      
      GLCD.CursorToXY(117, 23); 
      GLCD.print("C");                

      //**************************************************************************************************************************
       
      GLCD.CursorToXY(25, 32);  
      GLCD.print("RAW Value:");
  
      Averaging_RAW_Value();                                // Read averaged RAW Value.
      
      GLCD.CursorToXY(85, 32);  
      GLCD.print(Raw_Value_Avg);                            // Print avareage RAW Value.
      
      //**************************************************************************************************************************
      
      Test_ENT_ESC_Counter_Value ();

      if ( ENT_ESC_Selector == 3)
      {             
        Temp_Before = Calibration_Factor1 * (Raw_Value_Avg / 3.755);                            // Temperature Before Calibration       
        
       Calibration_Factor1 = (float)Ref_Temp1 / Temp_Before;
        
        // calculate the temperature value
        Temp_After = Calibration_Factor1 * (Raw_Value_Avg / 3.755);       // Temperature After Calibration
       
        GLCD.ClearScreen();   
       
        while( ENT_ESC_Selector == 3)    
        {          
           GLCD.CursorToXY(10  , 5);  
           GLCD.print("Temp. before Cal:");                                // Print Temperature Before
           
           GLCD.CursorToXY(64  , 14);  
           GLCD.print(Temp_Before);
           
           GLCD.CursorToXY(10, 23);  
           GLCD.print("Temp. After Cal: ");                                 // Print Temperature After
           
           GLCD.CursorToXY(64  , 32);  
           GLCD.print(Temp_After);
           
           GLCD.CursorToXY(10  , 41);                        
           GLCD.print("Cal_Factor1:");                                       // Print Calibration factor - These values are displayed to be able to see the difference the calibration affected.
           
           GLCD.CursorToXY(64  , 50);  
           GLCD.print(Calibration_Factor1);
           
           delay(5000);
           GLCD.ClearScreen();    
           
           ENT_ESC_Selector = 0;

        }                  
      }
      
      
  }