Hello everyone,
I am working on an in-line flow meter project and am having difficulty with the data readings since I am measuring the flow rate based on pulses. Is there a way to read pulses as decimals instead of integers? The flow rate data from my testing was 1.6 L/hr and 3.21 L/hr. The 1.6 L/hr corresponds to 1 pulse, and the 3.21 L/hr corresponds to 2 pulses when checked using the pulse counter. The flow rate obtained from another flow meter is within this range, so it is correct. However, I need an approximate and consistent value for the flow rate to create a calibration curve when doing manual testing. Does anyone have an idea of how I can achieve this? I used an Arduino UNO. Here is my code.
#include <max6675.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
#include <RTClib.h>
byte sensorInterrupt = 0; // 0 = digital pin 2
byte sensorPin = 2;
// initialize the library with the numbers of the interface pins
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_PCF8523 rtc;
// for the data logging shield,I use digital pin 10 for the SD cs line
const int chipSelect = 10;
// The hall-effect flow sensor outputs
// litre/minute of flow.
volatile float pulseCount;
float flowRate;
float totalLiters;
float density;
unsigned long oldTime;
int thermoDO = 4;
int thermoCS = 5;
int thermoCLK = 6;
MAX6675 thermocouple (thermoCLK, thermoCS, thermoDO);
// File object for data logging
File dataFile;
void setup()
{
// Initialize a serial connection for reporting values to the host
Serial.begin(9600);
// Set up the LCD's number of columns and rows:
lcd.init(); //initialize the lcd
lcd.backlight(); //open the backlight
//Initialize SD card
if (!SD.begin(chipSelect)) {
Serial.println("SD initialization failed!");
return;
}
Serial.println("SD initialization done.");
dataFile = SD.open("MANUAL", FILE_WRITE);
if (!dataFile) {
Serial.println("Error opening data file.");
return;
}
// Write header to file
dataFile.println("Time, Flowrate (L/min), Volume (L), Temperature (°C), Density (kg/m3");
dataFile.flush();
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH);
pulseCount = 0;
flowRate = 0.0;
totalLiters = 0;
oldTime = 0;
// The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
// Configured to trigger on a HIGH state change (transition from LOW
// state to HIGH state)
attachInterrupt(sensorInterrupt, pulseCounter, HIGH);
}
/**
* Main program loop
*/
void loop()
{
if((millis() - oldTime) > 1000) // Only process counters once per second
{
// Disable the interrupt while calculating flow rate and sending the value to
// the host
detachInterrupt(sensorInterrupt);
// Because this loop may not complete in exactly 1 second intervals we calculate
// the number of milliseconds that have passed since the last execution and use
// that to scale the output. We also apply the calibrationFactor to scale the output
// based on the number of pulses per second per units of measure (litres/minute in
// this case) coming from the sensor.
flowRate = (1000.0 / (millis() - oldTime)) * pulseCount / 37.40;
// flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount / 2244.19)*3600;
// Note the time this processing pass was executed. Note that because we've
// disabled interrupts the millis() function won't actually be incrementing right
// at this point, but it will still return the value it was set to just before
// interrupts went away.
oldTime = millis();
// Divide the flow rate in litres/minute by 60 to determine how many litres have
// passed through the sensor in this 1 second interval, then multiply by 1000 to
// convert to millilitres.
totalLiters += flowRate / 60 * 1000;
// Add the millilitres passed in this second to the cumulative total
//totalLiters += flowRate;
thermocouple.readCelsius(); //Data for temperature sensor.
if(28 > thermocouple.readCelsius() >= 27);
density = 840*(.9898 - (((27-thermocouple.readCelsius())*(0.9898-0.9890))/(27-28)));
if(thermocouple.readCelsius() >= 30);
if(29 > thermocouple.readCelsius() >= 28);
density = 840*(.9890 - (((28-thermocouple.readCelsius())*(0.9890-0.9881))/(28-29)));
if(thermocouple.readCelsius() >= 30);
density = 840*(.9873 - (((30-thermocouple.readCelsius())*(0.9873-0.9847))/(30-33)));
if(thermocouple.readCelsius() > 33);
density = 840*(.9847 - (((33-thermocouple.readCelsius())*(0.9847-0.9839))/(33-34)));
if(thermocouple.readCelsius() > 34);
density = 840*(.9839 -(((34-thermocouple.readCelsius())*(0.9839-0.9830))/(34-35)));
if(thermocouple.readCelsius() > 35);
density = 840*(.9830 -(((34-thermocouple.readCelsius())*(0.9830-0.9822))/(35-36)));
if(thermocouple.readCelsius() > 36);
density = 840*(.9822 -(((34-thermocouple.readCelsius())*(0.9822-0.9813))/(36-37)));
// Print the flow rate for this second in litres / minute
Serial.print("Flow rate: ");
Serial.print(flowRate, 5); // Print the integer part of the variable
Serial.print("L/min");
Serial.print("\t"); // Print tab space
// Print the cumulative total of litres flowed since starting
Serial.print("Volume: ");
Serial.print(totalLiters);
Serial.print("mL");
Serial.print("\t"); // Print tab space
Serial.print("PULSE: ");
Serial.print(pulseCount);
Serial.print("p/s");
Serial.print("\t"); // Print tab space
// Print temperature
Serial.print("Temp: ");
Serial.print(thermocouple.readCelsius());
Serial.print("°C ");
Serial.print("\t");
//Print Density
Serial.print("Density: ");
Serial.print(density);
Serial.print("kg/m3");
Serial.println("\t");
// Write data to CSV file
dataFile.print(millis() / 1000); // Time in seconds
dataFile.print(",");
dataFile.print(flowRate); // Flow rate
dataFile.print(",");
dataFile.print(totalLiters); // Volume
dataFile.print(",");
dataFile.print(thermocouple.readCelsius()); // Temperature
dataFile.print(",");
dataFile.println(density);
dataFile.flush(); // Flush data to SD card
dataFile.close();
// LCD
lcd.setCursor( 0, 0); // set the cursor to column 0, line 0
lcd.print("Flow: ");
lcd.print(flowRate);
lcd.print(" L/min"); // Print the volumetric flow rate in Liters per minute:
lcd.setCursor( 0, 1); // set the cursor to column 0, line 1
lcd.print("Volume: ");
lcd.print(totalLiters);
lcd.print(" mL");
lcd.setCursor(0, 2); // Set the cursor to column 0, line 2
lcd.print("Temp: ");
lcd.print(thermocouple.readCelsius());
lcd.print(" °C");
lcd.setCursor (0,3);
lcd.print("Density: ");
lcd.print(density);
lcd.print("kg/m3");
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(sensorInterrupt, pulseCounter, HIGH);
}
}
/*
Insterrupt Service Routine
*/
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;}
10 posts - 5 participants