Go Down

Topic: How to avoid floating point math (Read 2 times) previous topic - next topic

Nick Gammon

As long as you are trying, we'll be pleased to help.

I don't see interrupts being the issue here. You have two ISRs that you say are called every couple of seconds, so they are hardly the issue.

Then you have one which does a couple of adds. How many times a second do you expect it to be called? Let's put a metric on this.

And what data types are total_pulses, Count, tenth_gallon and running?

Nick Gammon


ahem...what's a code tag?


OK, here's some boilerplate. Read it, though:

Read this before posting a programming question

Please edit your post, select the code, and put it between [code] ... [/code] tags.

You can do that by hitting the # button above the posting area.

cornwallav8r


As long as you are trying, we'll be pleased to help.

I don't see interrupts being the issue here. You have two ISRs that you say are called every couple of seconds, so they are hardly the issue.

Then you have one which does a couple of adds. How many times a second do you expect it to be called? Let's put a metric on this.

And what data types are total_pulses, Count, tenth_gallon and running?


Very good questions those...

I expect no more than say, 100 pulses in a second. 
total_pulses-unsigned long, Count-unsigned int, tenth_gallon- unsigned int and running-boolean.

The calculating interrupt is done every 5 seconds, so I guess that can't be such an overhead issue, right?

Nick Gammon

Well out of interest, I set up a test. This code:

Code: [Select]

  total_pulses++ ; 
  Count++;
  tenth_gallon++;   
  running=1;


Takes about 2.8 uS to execute. So if you do 100 of them you have taken 280 microseconds. Add in the overhead of 100 interrupts, say 5 uS each, and that is another 500 uS. So in total 780 uS.

You have not even used up 1/1000 of the time you have in a second. Time to look elsewhere.

Besides, none of those are floating point variables. I thought you were worried about that?

cornwallav8r

No actually, it is this interrupt and its floating point math that I jumped to conclusions about...thoug I may simply have more dumb programming mistakes to fix instead.

Code: [Select]
void Repeats(){ //interrupt timer1 repeats every second-changed to 5 seconds...

  //here is the math...we sample every 5 seconds.  9200 counts per gallon. FIXED-use float cast to convert integers to float before calculating

  Calc = ((float)Count* ((float)720 / (float)k_factor)); //(Counts in 5 seconds/ number counts per gallon, converted from seconds to hours
  //using a large value we can select any k-factor - use counts per gallon - perfect
  // Calc is the gallons per hour.

  if (!flag){  //reset flag so running total flag is run only once
    flag=true;
  }      //this is used for averaging routine for average flow rate

  if (Count>0){
    stopped_flag++; //add 5 seconds to running time length

  }
  if (stopped_flag>5){  //this is to delay the time till we stop and wait....
    //30 seconds or so...it decrements with no flow
    stopped_flag=5; //add 5 seconds to length of time running, up to 30 seconds
    //-each unit of increase = 5 seconds of stoppage
  }

  if (Count==0){  //decrement once per 5 second with zero flow...
    stopped_flag--;

  }
  if (stopped_flag<=0){
    stopped_flag=0;  // no longer running
  }
  else {
    running=true;  //added this to ensure it stays running with flow
  }

  Count=0;  //reset for next interrupt

  //For some reason, when we start back up from stop, we re-enter the save routine.
  if ((stopped_flag<=0) && (running) ){  //we were running, then stopped

    state=10;  //keeps returning to state 10, stop and save, and looping again
    return;
  }

Go Up