Not necessarily. You could use fixed point arithmetic instead. For example, multiply your integer value by 1000 to get three decimal places of precision.
When you're dealing with arithmetic you need to be aware of the range and resolution of your values all the way through your calculation, so that you can avoid overflow or rounding errors at any stage. The numbers shown in your example are small enough for overflow not to be an issue, but you need to consider the full range of real-world values to make sure that you types are capable of holding them.
[/quote]
Hmm - I've started doing this, I've renamed dpm to mdpm as dpm has been multiplied by 1,000,000 for accuracy. However, i've run into the same problem as before, and thus rpm returns 0 whilst dpm still functions. See code;
// program will run for 70 minutes until currentmicro overflows
// check what will happen at overflow time
// changed millis to micro, thought of floating point, but too slow
// attempt change back to milli
volatile int timer_pulsecount = 0;
volatile int angle_pulsecount = 0;
volatile unsigned long p_lastpulse = 0;
unsigned long c_lastpulse = 0;
float timer_c_pulsemillis = 0;
float timer_p_pulsemillis = 0;
float threepulsetime = 0;
float threepulsetimecopy = 0;
int rpm = 0;
int tooth_spacing = 10;
int lastCommand = 0;
unsigned long mdpm = 0;
unsigned long debug_p_millis = 0;
unsigned long debug_c_millis = 0;
void setup()
{
Serial.begin(9600);
attachInterrupt(0, crank, RISING); // din D2
}
void crank()
{
timer_pulsecount++; //
p_lastpulse = millis();
}
void loop()
{
////////////////// SPEED AND POSITION TRACKING ///////////////////
c_lastpulse = millis();
timer_c_pulsemillis = millis();
mdpm = ((3 * tooth_spacing) * 1000000) / threepulsetimecopy; // changed to multiply numerator by 1000, works fine still
rpm = ((mdpm / 1000000) * 60000) / 360; // converts degrees per micro to rpm
if (lastCommand != timer_pulsecount){
lastCommand = timer_pulsecount;
switch (lastCommand){
case 1:
timer_p_pulsemillis = timer_c_pulsemillis;
break;
case 3:
threepulsetime = timer_c_pulsemillis - timer_p_pulsemillis; // needs to be reset to 0
threepulsetimecopy = threepulsetime;
break;
}
}
if(timer_pulsecount > 3)
{
timer_pulsecount = 1;
threepulsetime = 0;
}
if((c_lastpulse - p_lastpulse) >= 2000) // used to reset dpm & rpm to 0 when no pulses come in
{
mdpm = 0;
rpm = 0;
}
////////////////// DEBUGGING SERIAL STREAM ///////////////////
debug_c_millis = millis(); // starts counting currentMillis
if(debug_c_millis - debug_p_millis >= 500) // if current - 0 is > 1000, run if script
{
debug_p_millis = debug_c_millis; // set previous to current
Serial.println(timer_pulsecount);
Serial.println(tooth_spacing);
Serial.println(threepulsetimecopy);
Serial.println(mdpm);
Serial.println(rpm);
Serial.println("");
}
}
// print the above data, timer_pulsecount increments correctly
// timer_p_pulsemicros is set to current when timer_pulsecount = 1
// previous and current pulsemicros latch as they should
// three pulse time saves on 3, resets when timer_pulsecount loops to 1
// current program WORKS!!!
So, do I actually HAVE to use floating point?