#include <Wire.h>
#define flowsensor 2 // Interrupt pin 2
#define statusLed LED_BUILTIN // Built in LED
#define prssensor A0 // Pressure Sensor Input Pin A0
#define outPulse 8 // L/min Pulse Output Pin D8
int number = 0;
// Setup Flowmeter
volatile unsigned long flowPulseCount = 0; // Counts flow sensor pulses unsigned
unsigned long flowPulseCount_prev = 0; // Previous Counts of flow sensor
float l_sec = 0; // Calculated litres/sec
float litres = 0; // Calculated litres
float rem_litres = 0; // Remaining Litres left over from output pulse
const float calFactor = 1.00; // flow calibration factor
// Setup Pressure
float prs_bar = 0.0; // Calculated pressure kPa
float low = 204; // Scaling values
float high = 1023;
unsigned long currentTime;
unsigned long cloopTime;
// Create Data length for I2C based on 2 Floats being sent
byte data[sizeof(float) * 2];
int dataLength = sizeof(data);
void setup() {
// Start Serial Monitor
Serial.begin(9600);
Serial.println("Starting Up....");
// Start i2C
Wire.begin(10); // join i2c bus with address #10
Wire.onRequest(requestEvent); // register event
//Set IO
//pinMode(flowsensor, INPUT);
pinMode(prssensor, INPUT);
pinMode(statusLed, OUTPUT);
pinMode(outPulse, OUTPUT);
attachInterrupt(digitalPinToInterrupt(flowsensor), flow, RISING); // Setup Interrupt
currentTime = millis();
cloopTime = currentTime;
}
void loop() {
currentTime = millis();
// Set Pulsed Output Low to start
digitalWrite(outPulse, LOW);
// Every second, calculate litres/second
if(currentTime >= (cloopTime + 1000))
{
cloopTime = currentTime; // Updates cloopTime
unsigned long flowPulseCount_now = flowPulseCount;
unsigned long flow_frequency = flowPulseCount_now - flowPulseCount_prev;
// Flash StatusLed to show loop running, can be removed
flashStatusLed(1);
// Get Flow Reading
// Pulse frequency (Hz) = 4.8Q, Q is flow rate in L/min.
l_sec = (flow_frequency / 4.8 / 60) * calFactor; // (Pulse frequency x 100) / 4.8Q x Cal factor = flowrate in L/sec 2dp
// Get Pressure Reading
prs_bar = map(analogRead(prssensor), low, high, 0, 1000); // Scale pressure raw to 0 - 10.00 bar
// Update Flow
float flow = l_sec;
Serial.print("Flow : ");
Serial.print(flow, 1);
Serial.print("L ");
// Update Pressure
float pressure = prs_bar;
Serial.print("Pres.: ");
Serial.print(pressure/100, 2);
Serial.print("bar ");
float freq = flow_frequency;
Serial.print(freq,0);
Serial.println("# ");
flowPulseCount_prev = flowPulseCount_now; // Update previous count for next calculation
// Calculate and accumulate volume to get
litres += l_sec;
// Generate a pulse if 1 liter or more has been accumulated
if (flowPulseCount > 4294967200) {
flowPulseCount = 0;
}
// Create Data Array with updated values for I2C
setupDataArray();
}
if (litres >= 1.00){
int numPulses = (int)(litres); // Calculate the number of pulses to send
for (int i = 0; i < numPulses; i++) {
digitalWrite(outPulse, HIGH);
delay(5);
digitalWrite(outPulse, LOW); // Output pulse every 1 l/min
delay(1000/numPulses -5);
}
litres -= numPulses; // Subtract the number of pulses sent from the accumulated liters
}
}
void setupDataArray() {
*((float*)data) = l_sec; // copy flow to first 4 bytes of data
*((float*)(data + sizeof(float))) = prs_bar; // copy pressure to second 4 bytes of data
Serial.print(data[0]);
Serial.print(" ");
Serial.print(data[1]);
Serial.print(" ");
Serial.print(data[2]);
Serial.print(" ");
Serial.print(data[3]);
Serial.print(" ");
Serial.print(data[4]);
Serial.print(" ");
Serial.print(data[5]);
Serial.print(" ");
Serial.print(data[6]);
Serial.print(" ");
Serial.println(data[7]);
}
void flow() // Interrupt function - count pulses from flowmeter
{
flowPulseCount++;
}
void flashStatusLed(int count) {
for (int i = 0; i < count; i++) {
digitalWrite(statusLed, HIGH);
delay(100);
digitalWrite(statusLed, LOW);
delay(10);
}
}
void requestEvent() {
Wire.write(data, dataLength); // respond
}