Delta meter with a circular buffer.
#define IRQ_A 0
#define IRQ_B 1
#define FlowA 2
#define FlowB 3
volatile unsigned int countIN = 0;
volatile unsigned int countOUT = 0;
unsigned long oldTime = 0;
unsigned long totalPulses = 0;
unsigned int circBuf[60];
uint8_t idx = 0;
void setup()
{
Serial.begin(57600);
pinMode(FlowA, INPUT);
pinMode(FlowB, INPUT);
digitalWrite(FlowA, HIGH);
digitalWrite(FlowB, HIGH);
attachInterrupt(IRQ_A, CounterIN, FALLING);
attachInterrupt(IRQ_B, CounterOUT, FALLING);
}
void loop()
{
unsigned long now = millis();
if(now - oldTime >= 1000)
{
unsigned long duration = now - oldTime;
oldTime = now;
// store usage of last second in circular buffer
idx++;
if (idx == 60) idx = 0;
// disable interrupts while reading & reset counters.
cli();
circBuf[idx] = countIN - countOUT;
countIN = 0;
countOUT = 0;
sei();
totalPulses += circBuf[idx];
long pulsesLastMinute = 0;
for (uint8_t i=0; i<60; i++)
{
pulsesLastMinute += circBuf[i];
}
// LPH based upon last minute
float LPH_M = pulsesLastMinute/10000.0 * 60;
// LPH based upon last second
float LPH_S = circBuf[idx]/10000.0 * 3600;
// Total Liters since start
float liters = totalPulses/10000.0;
// DISPLAY USAGE
Serial.print(now);
Serial.print("\tLPH_M:\t");
Serial.print(LPH_M, 3);
Serial.print("\tLPH_S:\t");
Serial.print(LPH_S, 3);
Serial.print("\tLiters:\t");
Serial.println(liters, 3);
}
}
void CounterIN()
{
countIN++;
}
void CounterOUT()
{
countOUT++;
}