Skip to content

Instantly share code, notes, and snippets.

@cellularmitosis
Last active June 6, 2021 21:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cellularmitosis/a27b8365a5b6f48fda74bb7966f419a9 to your computer and use it in GitHub Desktop.
Save cellularmitosis/a27b8365a5b6f48fda74bb7966f419a9 to your computer and use it in GitHub Desktop.
Are 32-bit floats sufficient for micros to RPM conversion?

Blog 2021/2/20

<- previous | index | next ->

Are 32-bit floats sufficient for microseconds-to-RPM conversion?

Answer: yes.

Engine ECU's calculate engine RPM by measuring the delay (in microseconds) between pulses from a crank position sensor.

Converting from micros to RPM can be performed as a single division (60 million / delay), but do 32-bit floats have sufficient resolution to produce usable results? We can write a simple C program to answer this.

Our expected range of values spans from cranking speed (about 240 RPM, or 250,000 micros) to engine redline (about 10,000 RPM, or 6,000 micros).

Output:

250000 micros -> 240.0000000000000000 rpm, (as bytes: 0x43700000)
250001 micros -> 239.9990386962890625 rpm, (as bytes: 0x436fffc1)
6000 micros -> 10000.0000000000000000 rpm, (as bytes: 0x461c4000)
6001 micros -> 9998.3339843750000000 rpm, (as bytes: 0x461c3956)
// Test of whether 32-bit floats are suitable for conversion from microseconds
// to revolutions per minute.
#include <stdint.h>
#include <stdio.h>
// gcc -std=c99 -O0 -Wall -Werror -o rpm rpm.c && ./rpm
int main() {
// 250,000 micros represents cranking speed (240 RPM).
// 6,000 micros represents redline (10,000 RPM).
uint32_t nums[99] = {250000, 250001, 6000, 6001};
for (int i=0; i < 4; i++) {
uint32_t n = nums[i];
float f = 60000000.0;
float g = f / n;
printf("%u micros -> %.16f rpm, (as bytes: 0x%x)\n", n, g, *(unsigned int*)&g);
}
return 0;
}
/* output:
250000 micros -> 240.0000000000000000 rpm, (as bytes: 0x43700000)
250001 micros -> 239.9990386962890625 rpm, (as bytes: 0x436fffc1)
6000 micros -> 10000.0000000000000000 rpm, (as bytes: 0x461c4000)
6001 micros -> 9998.3339843750000000 rpm, (as bytes: 0x461c3956)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment