// https://wokwi.com/projects/410217439172554753
// https://forum.arduino.cc/t/looking-for-a-pump-project-rate-volume-displacement/1305478
/*
Tachometer using micros
Made by InterlinkKnight
Last update: 05/23/2019
*/
const byte PulsesPerRevolution = 1;
const unsigned long ZeroTimeout = 300000;
const byte numReadings = 5;
volatile unsigned long LastTimeWeMeasured;
volatile unsigned long PeriodBetweenPulses = ZeroTimeout+1000;
volatile unsigned long PeriodAverage = ZeroTimeout+1000;
unsigned long FrequencyRaw;
unsigned long FrequencyReal;
unsigned long RPM;
unsigned long PulseCounter = 1;
unsigned long PeriodSum;
unsigned long LastTimeCycleMeasure = LastTimeWeMeasured;
unsigned long CurrentMicros = micros();
unsigned int AmountOfReadings = 1;
unsigned int ZeroDebouncingExtra;
unsigned long readings[numReadings];
unsigned long readIndex;
unsigned long total;
unsigned long average;
unsigned long LPM;
unsigned long TOTAL;
void setup()
{
Serial.begin(115200);
attachInterrupt(digitalPinToInterrupt(2), Pulse_Event, RISING);
delay(1000);
}
void loop()
{
generateFakeSignal();
LastTimeCycleMeasure = LastTimeWeMeasured;
CurrentMicros = micros();
if(CurrentMicros < LastTimeCycleMeasure)
{
LastTimeCycleMeasure = CurrentMicros;
}
FrequencyRaw = 10000000000 / PeriodAverage;
if(PeriodBetweenPulses > ZeroTimeout - ZeroDebouncingExtra || CurrentMicros - LastTimeCycleMeasure > ZeroTimeout - ZeroDebouncingExtra)
{
FrequencyRaw = 0;
ZeroDebouncingExtra = 2000;
}
else
{
ZeroDebouncingExtra = 0;
}
FrequencyReal = FrequencyRaw / 10000;
RPM = FrequencyRaw / PulsesPerRevolution * 60;
RPM = RPM / 10000;
LPM = RPM * 2.4711 ;
// TOTAL = TOTAL++; //* 2.4711 ;
total = total - readings[readIndex];
readings[readIndex] = RPM;
total = total + readings[readIndex];
readIndex = readIndex + 1;
if (readIndex >= numReadings)
{
readIndex = 0;
}
average = total / numReadings;
// Serial.print("Period: ");
// Serial.print(PeriodBetweenPulses);
// Serial.print("\tReadings: ");
// Serial.print(AmountOfReadings);
// Serial.print("\tFrequency: ");
// Serial.print(FrequencyReal);
// Serial.print("\tRPM: ");
// Serial.print(RPM);
// Serial.print("\tTachometer: ");
// Serial.println(average);
// Serial.print("\t readings: ");
//Serial.print (readings[numReadings]);
Serial.print("\tTOTAL: ");
Serial.print(TOTAL++ * 2.4711);
Serial.print("\tLPM: ");
Serial.print(LPM);
// Serial.print("\tFrequency: ");
// Serial.print(FrequencyReal);
// Serial.print("\tRPM: ");
// Serial.print(RPM);
}
void Pulse_Event() // The interrupt runs this to calculate the period between pulses:
{
//TOTAL++;
PeriodBetweenPulses = micros() - LastTimeWeMeasured;
LastTimeWeMeasured = micros();
if(PulseCounter >= AmountOfReadings)
{
PeriodAverage = PeriodSum / AmountOfReadings;
PulseCounter = 1;
PeriodSum = PeriodBetweenPulses;
// TOTAL++;
int RemapedAmountOfReadings = map(PeriodBetweenPulses, 40000, 5000, 1, 10);
RemapedAmountOfReadings = constrain(RemapedAmountOfReadings, 1, 10);
AmountOfReadings = RemapedAmountOfReadings;
}
else
{
PulseCounter++;
PeriodSum = PeriodSum + PeriodBetweenPulses;
}
}
# define signal 8 // fake signal output pin
# define control A0 // frequency control pin
void generateFakeSignal()
{
static unsigned long lastEdge;
unsigned long now = micros();
long periodHalf = analogRead(control);
periodHalf = map(periodHalf, 0, 1023, 300000L, 300L);
// Serial.print(" "); Serial.println(periodHalf);
if (now - lastEdge > periodHalf) {
pinMode(signal, OUTPUT); // <-- should be in setuo, just didn't wanna
digitalWrite(signal, digitalRead(signal) == LOW ? HIGH : LOW);
lastEdge = now;
}
}