help with float division?

I am trying to convert a usec timer value to RPM, and seeing a division problem of the nature…

RPM: ms, sec, rpm

61.12 0.061124 1202 should be: 981 (via calculator)

RPM: ms, sec, rpm

41.60 0.041596 2100 should be: 1442

RPM: ms, sec, rpm

45.93 0.045932 2002 should be: 1306

Here is the function code…

void get_rpm() {
float ms, sec;

ms = interval * 0.001; //convert usec to msec
sec = ms * 0.001; //convert msec to sec
rpm = int(60.0 / sec); //reciprocal

Serial.println(“RPM: ms, sec, rpm”); //show results
Serial.print(ms);
Serial.print("\t");
Serial.print(sec,6);
Serial.print("\t");
Serial.println(rpm,4);

}

If you examine the RPM data from the reciprocal, you can see it is wayyy off! “interval” is a global unsigned long and is the time between ignition events in usec. The calculations all work out until the division is performed. I may be overflowing an intermediate somewhere, but not sure where or how to determine. Thanks in advance for help or advise.

 rpm = int(60.0 / sec);   //reciprocal

This makes no sense. If rpm is a to be printed to 4 decimal places, why are you truncating the value to an int first?

but not sure where or how to determine.

Print all the intermediate values. Don't guess what is, or is not, working.

The print statements are merely used for debug purposes, but that's not my problem. The actual circuit is displaying on a hex LED display, which is showing the incorrect value for RPM. I placed the print statements in the code to try and isolate the problem. I'm specifically questioning the rpm = (60 / sec) statement - simple calculation! For instance, the 2nd data acquisition shows 60 / 0.041596 is 2100, but should be 1442. This is clearly the wrong value, as are all the other RPM values.

BTW, as you can see, the calculated RPM is indeed 4 places (or can be).

I'm using Windows XP with all current updates, and Arduino 1.6.0 IDE.

ps. I don't think this is a Project Guidance issue??? There is nothing wrong with the project per se, it is a simple math calculation giving the wrong answer!

I presume that rpm is declared to be an integer, in which case this:

Serial.println(rpm,4);

should be this:

Serial.println(rpm);

If that isn't the problem, post ALL your code in [code]...[/code] tags.

Pete

I basically copied your function into an empty sketch.
And added a bool to just have it print to serial once.

long interval = 61124;
bool shouldPrint = true;

void setup() {
  Serial.begin(9600);

}

void loop() {
  if (shouldPrint)
 get_rpm();

}
void get_rpm() {
  float ms, sec, rpm;
  
  ms =  interval * 0.001;  //convert usec to msec
  sec = ms * 0.001;        //convert msec to sec
  rpm = int(60.0 / sec);   //reciprocal
  
  Serial.println("RPM: ms, sec, rpm");  //show results
  Serial.print(ms);
  Serial.print("\t");
  Serial.print(sec,6);
  Serial.print("\t");
  Serial.println(rpm,4);
shouldPrint=false;
}

The values displayed on serial monitor using 61124 as the value for interval…

RPM: ms, sec, rpm
61.12 0.061124 981.0000

which is what you say is the correct answer.

Using Windows 10 and Arduino 1.6.4 in case that matters(but don’t know why it would).

You may need to post your whole code so one of the smarter than me folks(of which there are many) can reproduce your error. Because I have no idea where your RPM of 1202 comes from using 61124 for interval.

Whoops, I forgot to mention that rpm is a type int, but that still doesn't address the problem. I did write a short function where I typed in the value for sec; i.e., rpm = 60 / .041596 and it does provide the correct answer. However when the program produces the exact same .041596 value, I get an incorrect answer? Anyway, let me stare at it for a few more hours, and I'll see if the problem starts glowing in bright fluorescent green, or perhaps comes to me in my sleep. Thanx for your input.

gary30121: I am trying to convert a usec timer value to RPM, and seeing a division problem of the nature...

int get_rpm(long usec) {
  // input parameter: rotation period in microseconds
  // return value: rotations per minute
  return 60000000.0/usec;
}

void setup() {
  Serial.begin(9600);
  long time=61124; // microseconds
  int rpm=get_rpm(time); // calculate rpm in a function call
  Serial.println(rpm); // print result to Serial
}

void loop() {
}

The rpm limit when using "int" as the return value of the function is 32767 rpm. If you need to calculate higher rpm values, you need to use a different data type than "int".

Serial.println(rpm,4);

If rpm is of type int, then that line means “print rpm in base 4.”

  ms =  interval * 0.001;  //convert usec to msec
  sec = ms * 0.001;        //convert msec to sec
  rpm = int(60.0 / sec);   //reciprocal

That math is too complicated and uses way too many different units.

Why not just notice that one minute is 60 million microseconds, and so divide 60000000 by the number of microseconds for one revolution?

 1 min = 60 sec
       = 60[color=blue]000 milli[/color]seconds
       = 60[color=blue]000[/color][color=red]000 micro[/color]seconds