having problems with my floats [ solved ]

I am using a pulse output water flow sensor.

This sketch shows totalMiliLitre as an integer

I divide that by 1000 to get totalLitre, which is a float but I only get an integer with decimal places of 00

here is my output, sketch at the end.

Rate: 0.00L/min Total 1098 mL 1.00 L Rate: 0.00L/min Total 1098 mL 1.00 L Rate: 13.10L/min Total 1316 mL 1.00 L Rate: 12.88L/min Total 1530 mL 1.00 L Rate: 10.43L/min Total 1703 mL 1.00 L Rate: 9.99L/min Total 1869 mL 1.00 L Rate: 9.77L/min Total 2031 mL 2.00 L Rate: 9.99L/min Total 2197 mL 2.00 L Rate: 10.21L/min Total 2367 mL 2.00 L Rate: 9.77L/min Total 2529 mL 2.00 L Rate: 9.99L/min Total 2695 mL 2.00 L Rate: 7.77L/min Total 2824 mL 2.00 L

byte statusLed    = 13;
byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin       = 2;
float calibrationFactor = 4.5;
volatile byte pulseCount;  
float flowRate;
// unsigned int flowMilliLitres;
float flowMilliLitres;
unsigned long totalMilliLitres;
//float totalLitres;
unsigned long oldTime;

void setup()
{
  

  Serial.begin(57600);
  pinMode(statusLed, OUTPUT);
  digitalWrite(statusLed, HIGH);  // We have an active-low LED attached
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);

  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres  = 0;
  oldTime           = 0;

  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}

void loop()  // ++++++++++++++++++++++++++++++++++++++++++++++++++ VOID LOOP
{
   
   if((millis() - oldTime) > 1000)    // Only process counters once per second
  { 

    detachInterrupt(sensorInterrupt);
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    oldTime = millis();
     flowMilliLitres = (flowRate / 60) * 1000 ; // to get mLph
     totalMilliLitres += flowMilliLitres;
     float totalLitres = totalMilliLitres / 1000 ;
      
    unsigned int frac;
    
    Serial.print("Rate: ");
    Serial.print(flowRate);      Serial.print("L/min");
    Serial.print("  Total ");             // Output separator
    Serial.print(totalMilliLitres);     Serial.print(" mL "); 
    Serial.print(totalLitres);     Serial.println(" L"); 

    pulseCount = 0;
    
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  }
}

void pulseCounter()
{
  pulseCount++;
}

I divide that by 1000

Divide it by 1000.00 instead.

Try changing

float totalLitres = totalMilliLitres / 1000 ;

to

float totalLitres = totalMilliLitres / 1000.0;

Thanks !

worked great.

Rate: 0.00L/min Total 1143 mL 1.14 L Rate: 1.78L/min Total 1172 mL 1.17 L Rate: 13.54L/min Total 1397 mL 1.40 L Rate: 12.88L/min Total 1611 mL 1.61 L Rate: 10.65L/min Total 1788 mL 1.79 L Rate: 9.99L/min Total 1954 mL 1.95 L Rate: 9.99L/min Total 2120 mL 2.12 L Rate: 10.21L/min Total 2290 mL 2.29 L

dave-in-nj: worked great.

Do you understand why ?

totalMilliLitres is being treated as an int, the conversion to a float takes place after the division by 1000. so it rounds down!

Mark

PS you could also use (float)totalMilliLitres / 1000

M

UKHeliBob: Do you understand why ?

one of the values was an int, so all the results are also int. just because one of the numbers was a float and had room for the answer as a float, the int took preference.

changing

unsigned long totalMilliLitres; to float totalMilliLitres;

would result in the same way, a decimal.

unsigned long and float are both 32 bits. so, it appears that there is no benefit in my sketch to use unsigned long over float.

dave-in-nj: one of the values was an int, so all the results are also int. just because one of the numbers was a float and had room for the answer as a float, the int took preference.

changing

unsigned long totalMilliLitres; to float totalMilliLitres;

would result in the same way, a decimal.

unsigned long and float are both 32 bits. so, it appears that there is no benefit in my sketch to use unsigned long over float.

Shouldn't integer math execute faster?

dave-in-nj: one of the values was an int, so all the results are also int. just because one of the numbers was a float and had room for the answer as a float, the int took preference. ...

But, but, but ... When I do this:

float dividend = 123456.789;
int divisor = 1000;

void setup()
{
  Serial.begin(9600);
  Serial.println(dividend / divisor);
}

void loop() {
}

I get 123.46

Even if I use an explicit 1000 instead of the variable divisor, I get the float answer.

Why?

ChrisTenone: But, but, but ... When I do this:

float dividend = 123456.789;
int divisor = 1000;

void setup() {   Serial.begin(9600);   Serial.println(dividend / divisor); }

void loop() { }




I get 123.46

Even if I use an explicit 1000 instead of the variable divisor, I get the float answer.

Why?

This is beyond my knowledge. the language has it's needs and wants and much is well above my pay grade.

I am trying to read a water flow sensor. interrupt, watch the time it takes, based on time of flight, determine frequency, then show current flow rate. with flow rate, and volume per pulse, one can determine quantity.

then there is the LCD to update.

and once I get those things settled, a simple 3 window proportional control, a poor mans fuzzy control. that is simple ; 1) outside of the big window, move fast. 2) within the middle window, move slow 3) within the tiny window, move very slow. and possibly a tic or two from an integral correction.

I assume the slowest part is the LCD, the flow sensor uses an interrupt routine and probably the easiest part is the pwm setpoint for the control.

I do not see any loss of speed with doing floating point math, but then again, I was stuck on the division......

I will say that setting up buckets, running the pumps, siphoning water back and playing with all the electronical bits has been a lot of fun.

all that said, and in discussing speed of math,

is it faster for a program to do floating point math, specifically division by 1000 and Serial.print (answer)

or to serial write the first two digits to the LCD then a decimal point then the two digits on the right of the decimal point ?

and I guess the real question is that with this program, is there really and benefit to doing integer math ?