#include <LiquidCrystal_I2C.h>
const byte wings = 4; // no of wings of rotating object, for disc object use 1 with white tape on one side
volatile unsigned long prevPulseUs, pulseUs, prevPulseUsCopy, pulseUsCopy;
unsigned long pulsePeriod, rpm;
void isr() { //interrupt service routine
prevPulseUs = pulseUs;
pulseUs = micros();
}
bool timeOut(unsigned long ms) { //ms timer
volatile unsigned long prevMs, now;
now = millis();
if ((now - prevMs) >= ms) {
prevMs = now;
return true;
}
return false;
}
LiquidCrystal_I2C lcd (0x27, 16, 2);
void setup() {
pinMode(3, OUTPUT); // jumper to pin 2 for pwm test
analogWrite(3, 1); // test pwm @ 490 Hz = 29400 rpm / wings
lcd.init(); //initialize LCD
lcd.backlight(); //turn on the backlight on LCD
attachInterrupt(digitalPinToInterrupt(2), isr, RISING); //attaching the interrupt
}
void loop() {
if (timeOut(1000)) {
cli(); //stop interrupts
prevPulseUsCopy = prevPulseUs;
pulseUsCopy = pulseUs;
sei(); //allow interrupts
pulsePeriod = pulseUsCopy - prevPulseUsCopy;
if (pulsePeriod < 600) pulsePeriod = 600; // upper limit 120000 / wings
if (!pulseUsCopy || !prevPulseUsCopy) pulsePeriod = 10000000; // startup 0 rpm
rpm = 1000000 / pulsePeriod * 60 / wings; //calculates rpm
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("___TACHOMETER___");
lcd.setCursor(0, 1);
lcd.print(rpm);
lcd.print(" RPM");
lcd.print(" ");
}
}