// There is a structural/logic bug in this sketch.
// If the input stops, then the last pulses need to shift back
// in time before the sketch understands that they are too old.
// During that time, the previous pulses are stil used to calculate
// the frequency a few times.
// The variable 'newData' is added for that, but not yet implemented.
#include <LiquidCrystal_I2C.h>
// The lastMicros is the time of the last trigger (rising pulse)
// The lasterMicros is the time before that.
volatile unsigned long lastMicros; // 'volatile', it is read in the loop()
volatile unsigned long lasterMicros;
volatile bool newData; // if the last(er)Micros were used
unsigned long previousMillis;
LiquidCrystal_I2C lcd (0x27, 16, 2);
void IRAM_ATTR isr()
{
lasterMicros = lastMicros;
lastMicros = micros();
newData = true;
}
void setup()
{
Serial.begin(115200);
pinMode(5, OUTPUT);
attachInterrupt(digitalPinToInterrupt(19), isr, RISING);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("___TACHOMETER___");
lcd.setCursor(0, 1);
lcd.print("Hz : ");
}
void loop()
{
unsigned long currentMillis = millis();
if( currentMillis - previousMillis >= 250)
{
previousMillis = currentMillis;
noInterrupts();
unsigned long lastMicrosCopy = lastMicros;
unsigned long lasterMicrosCopy = lasterMicros;
newData = false;
interrupts();
unsigned long howLongAgoLastPulse = micros() - lastMicrosCopy;
// Suppose that 1Hz is the minimum frequency, then the signal
// is not valid if the last pulse was more than 1 second ago.
// Let's say it is not valid if it longer than 1.1 seconds.
// The micros() can count up to 70 minutes.
if( howLongAgoLastPulse > 1100000UL) // 1.1 seconds
{
// no valid pulse received in this time.
lcd.setCursor( 5, 1);
lcd.print( "----- ");
Serial.println("-----");
}
else
{
// Only the last timing in microseconds is known.
// The 'elapsedMicros' could be a average filter in the future.
unsigned long elapsedMicros = lastMicrosCopy - lasterMicrosCopy;
Serial.println(elapsedMicros);
// the time is in microseconds, divide by 1000000 for timing in seconds
float frequency = 1.0 / (float(elapsedMicros) / 1000000.0);
lcd.setCursor( 5, 1);
lcd.print( frequency);
lcd.print( " ");
}
}
//delay(5); // slows down the PWM frequency of the custom chip
}