// 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 = 1;
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;
unsigned long Totalpumped =1;
unsigned long loopcount = 1;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
void setup()
{
// Library for I2C / TWI device communication
// Library to control the LCD screen
lcd.init(); // initialise the LCD
lcd.backlight(); // turn backlight on
lcd.clear(); // clear the screen
//LiquidCrystal_I2C lcd(0x3F, 16, 2);
Serial.begin(115200);
attachInterrupt(digitalPinToInterrupt(2), Pulse_Event, RISING);
delay(1000);
}
void loop()
{
generateFakeSignal();
// lcd.setCursor(0, 0); // set the cursor to position 1, line 1
// lcd.print("Hello YouTube!"); // write on the screen
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 - readings[readIndex];
readings[readIndex] = RPM;
total = total + readings[readIndex];
readIndex = readIndex + 1;
Totalpumped == readIndex + Totalpumped;
if (readIndex >= numReadings)
{
readIndex = 0;
}
average = total / numReadings;
Serial.print("\tMilliseconds: ");
Serial.print(millis ());
lcd.setCursor(0, 0); // set the cursor to position 1, line 1
//lcd.print("T:"); // write on the screen
// lcd.print(millis ()/1000); // write on the screen
//lcd.print(" ");
// Serial.println("");
Serial.print("\tTotal Liters: ");
Serial.print(loopcount* 2.4711);
lcd.print("Liters:"); // write on the screen
lcd.print(loopcount* 2.4711); // write on the screen
lcd.setCursor(0, 1); // set the cursor to position 1, line 2
Serial.print("\tLPM: ");
Serial.print(LPM);
lcd.print("LPM:"); // write on the screen
lcd.print(LPM); // write on the screen
Serial.print("\tRPM: ");
Serial.print(RPM);
lcd.print(" ");
lcd.print("RPM:"); // write on the screen
lcd.print(RPM); // write on the screen
Serial.println("");
}
void Pulse_Event() // The interrupt runs this to calculate the period between pulses:
{
loopcount ++;
PeriodBetweenPulses = micros() - LastTimeWeMeasured;
LastTimeWeMeasured = micros();
if(PulseCounter >= AmountOfReadings)
{
PeriodAverage = PeriodSum / AmountOfReadings;
PulseCounter = 1;
PeriodSum = PeriodBetweenPulses;
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, 1000, 200000, 0);
// 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;
}
}
/*
* SDA is the serial data
* SCL is the serial clock
*
* GND --> GND white
* VCC --> 5V grey
* SDA --> A4 red
* SCL --> A5 blue
*
*
* I2C connections for each Arduino:
* Uno, Ethernet A4 (SDA), A5 (SCL)
* Mega2560 20 (SDA), 21 (SCL)
* Leonardo 2 (SDA), 3 (SCL)
* Due 20 (SDA), 21 (SCL) or SDA1, SCL1
*
*/
/*
* Set the correct chip for your LCD
* Use 0x27 when you have the PCF8574 chip made by NXP
* Use 0x3F when you have the PCF8574A chip made by Ti (Texas Instruments)
* The last two digits represent the LCD size
* e.g. 20x4 or 16x2
*
*/