I've approached this with a multiplier rather than a bunch of math in the loop.
Heres my example code I refer to when I forget ![]()
#define TacometerPin 2 // Must be pin 2 or 3
// My Encoder has 400 Clock pulses per revolution
// note that 150000.0 = (60 seonds * 1000000 microseconds)microseconds in a minute / 400 pulses in 1 revolution)
#define Multiplier 150000.0 // don't forget a decimal place to make this number a floating point number
volatile uint32_t _deltaTime; // Delt in time
volatile uint32_t _lastTime; // Saved Last Time of Last Pulse
volatile uint32_t _Time;
void CaputreDeltaT() {
_deltaTime = (_Time = micros()) - _lastTime;
_lastTime = _Time;
}
void setup() {
Serial.begin(115200); //115200
pinMode(TacometerPin, INPUT);
attachInterrupt(digitalPinToInterrupt(TacometerPin), CaputreDeltaT, RISING);
}
void loop() {
float DeltaTime;
float SpeedInRPM = 0;
// Serial print is slow so only use it when you need to (10 times a second)
static unsigned long SpamTimer;
if ( (unsigned long)(millis() - SpamTimer) >= (100)) {
SpamTimer = millis();
noInterrupts ();
// Because when the interrupt occurs the EncoderCounter and SpeedInRPM could be interrupted while they
// are being used we need to command a "hold" for a split second while we copy these values down. This doesn't keep the
// interrupt from occurring it just slightly delays it while we copy values.
// if we don't do this we could be interrupted in the middle of copying a value and the result get a corrupted value.
DeltaTime = _deltaTime;
_deltaTime = 0; // if no pulses occure in the next 100 miliseconds then we must assume that the motor has stopped this allows a speed of zero to occure
interrupts ();
SpeedInRPM = Multiplier / DeltaTime; // Calculate the RPM
Serial.print(SpeedInRPM , 3);
Serial.print(" RPM");
Serial.println();
}
}
Z