and yet another version, this one keeping the rounds per second in a circular buffer and has a var RPM that reflects the rounds made in the last minute.
This one shows a memory effect.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); //set the LCD address to 0x27 for a 16 chars and 2 line display
//TESTPIN
const int testpin = 3;
//MAIN INPUTS
const int DispSampleTime = 1000; //[millisec] //= 0.1sec
// variables:
volatile unsigned long rounds;
unsigned long lastrounds;
unsigned long rps[60];
uint8_t idx = 0;
unsigned long RPM = 0;
unsigned long disp_timeold = 0UL;
unsigned long timeold = 0UL;
unsigned long timetemp = 0L;
//SETUP RUN ONLY ONCE @ start
void setup()
{
//DEBUG
TCCR2B = TCCR2B & 0b11111000 | 0x07 ; // sets PWM to 30.517578125 Hz on pin 3 and 11 //timer 2
//testpin TESTESTESTEST----------------------<<<<<<<<<<<<>>>>>>>>>>>>>
pinMode(testpin, OUTPUT);
analogWrite(testpin, 1); //sample 30.51757 hz pulse 1/255 uptime.
lcd.init(); // initialize the lcd
lcd.backlight();
//set interrupt on pin 2 and call function rpm_interrupt when pin is falling
attachInterrupt(0, rpm_interrupt, FALLING);
}
void loop()
{
// get rounds in last second
// place it in a circular buffer
// and keep the RPM up to date (after a minute it will stabilize)
timetemp = millis() - timeold;
if( timetemp >= 1000)
{
timeold += timetemp;
unsigned long t = rounds;
RPM -= rps[idx];
rps[idx] = t - lastrounds;
RPM += rps[idx];
idx++;
if (idx == 60) idx = 0;
lastrounds = t;
}
// DISPLAY RPM
timetemp = millis() - disp_timeold;
if( timetemp >= DispSampleTime)
{
disp_timeold += timetemp;
//disp stuff
lcd.clear();
lcd.print("Rpm: ");
lcd.print(RPM);
}
}
void rpm_interrupt()
{
rounds++;
}
So in the end there are several ways to calculate the RPM bute every method has its own side effects.
- if you count pulses in last second and multiply *60 (1st) , one pulse more or less give you a delta of 120
- if you count all pulses in a minute (above) you get a memory effect when accelerating. It takes a minute to become stable
- if you measure time of the last round (2nd) the accuracy depends on the duration (especially when using integer math)
IMHO The advantage of measuring time of the last round is that it is very reactive.