I need some help with the following
I am reading the flow rate and temperature from a hall sensor, on pin 2 and Analog in A0 on a 2x16 LCD display this works and a UNO board
Now I would like to either flip a relays or power a LED on pin 3, when the flow is below a threshold or 0,
Eventually (optional) i would like the same for the temperature, to create an output if the temp is too high ,
see below my code
#include <Wire.h>
#include "rgb_lcd.h"
const int ledPin = 3; // the number of the LED pin
const int flowsensor = 2;
volatile int flow_frequency;
float vol = 0.0,l_minute;
unsigned long currentTime;
unsigned long cloopTime;
const unsigned long NO_FLOW_TIMEOUT = 300; //milliseconds. If we don't get a pulse within this time, consider that flow has stopped.
const unsigned long WAIT_PERIOD = 20000; //milliseconds. The amount of time that flow must exist before turning off the output LED.
// variables will change:
unsigned long LastPulseDetected = 0;
unsigned long FirstFlowDetected = 0;
float current;
int termPin = 0; // The analog pin to which the thermistor is connected is A0
int termNom = 10000; // Thermistor reference resistance
int refTemp = 25; // Temperature for reference resistance
int beta = 3950; // Beta factor
int resistance = 10000; // value of resistance in series in the circuit
rgb_lcd lcd;
const int colorR = 255;
const int colorG = 0;
const int colorB = 0;
void flow () // Interrupt function to increment flow
{
flow_frequency++;
}
void setup()
{
pinMode(flowsensor, INPUT);
attachInterrupt(digitalPinToInterrupt(flowsensor), flow, RISING); // Setup Interrupt
Serial.begin(9600);
analogReference(EXTERNAL);
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
lcd.begin(16, 2);
lcd.setRGB(colorR, colorG, colorB);
lcd.print("Flow & Temp");
currentTime = millis();
cloopTime = currentTime;
}
void loop ()
{
currentTime = millis();
if(currentTime >= (cloopTime + 1000)) // Every second, calculate and print litres/hour
{
cloopTime = currentTime; // Updates cloopTime
if(flow_frequency != 0)
{
l_minute = (flow_frequency / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Rate: ");
lcd.print(l_minute);
lcd.print(" L/M");
l_minute = l_minute/60;
flow_frequency = 0; // Reset Counter
}
else {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Flow: ");
lcd.print( flow_frequency );
lcd.print(" L/M");
}
int sensorState = digitalRead(flowsensor); // read the state of the sensor value:
if (sensorState == HIGH) {
if(millis() - LastPulseDetected > NO_FLOW_TIMEOUT) {
//flow has just started
FirstFlowDetected = millis();
} else {
//pulse arrived within timeout, flow is still flowing
LastPulseDetected = millis(); //record that we got a pulse
}
}
if(millis() - LastPulseDetected < NO_FLOW_TIMEOUT && millis() - FirstFlowDetected > WAIT_PERIOD) {
//flow is still flowing and it has been flowing for more than the wait period
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
{
//measuring the voltage on the thermistor
current = analogRead(termPin);
// Convert the measured value to the thermistor resistance
current = 1023 / current - 1;
current = resistance / current;
//Calculation of temperature according to the relation for the beta factor
float temperature;
temperature = current / termNom; // (R/Ro)
temperature = log(temperature); // ln(R/Ro)
temperature /= beta; // 1/B * ln(R/Ro)
temperature += 1.0 / (refTemp + 273.15); // + (1/To)
temperature = 1.0 / temperature; // The inverted value
temperature -= 273.15; // Convert from Kelvin to degrees Celsius
lcd.setCursor(0,1);
lcd.print("Temp:");
lcd.setCursor(6,1);
lcd.print(temperature,1);
lcd.print("C");
lcd.print(" ");
delay(250); //delay of LCD print
}
}
}
The existing logic mostly works, but sensorState is not used correctly in determining when to trigger the LED.
Instead of checking sensorState, it's better to use flow_frequency directly.
#include <Wire.h>
#include "rgb_lcd.h"
const int ledPin = 3; // LED or relay output pin
const int flowsensor = 2; // Flow sensor input pin
volatile int flow_frequency;
float vol = 0.0, l_minute;
unsigned long currentTime;
unsigned long cloopTime;
const unsigned long NO_FLOW_TIMEOUT = 300; // ms without pulses → no flow
const unsigned long WAIT_PERIOD = 20000; // ms of continuous flow before LED turns off
unsigned long LastPulseDetected = 0;
unsigned long FirstFlowDetected = 0;
// Temperature sensor variables
const int termPin = A0; // Analog pin for thermistor
const int termNom = 10000; // Thermistor reference resistance
const int refTemp = 25; // Temperature reference
const int beta = 3950; // Beta coefficient
const int resistance = 10000; // Series resistor value
const float TEMP_THRESHOLD = 50.0; // Temperature threshold (change as needed)
rgb_lcd lcd;
const int colorR = 255, colorG = 0, colorB = 0;
void flow() { // Interrupt function for flow sensor
flow_frequency++;
}
void setup() {
pinMode(flowsensor, INPUT);
attachInterrupt(digitalPinToInterrupt(flowsensor), flow, RISING);
Serial.begin(9600);
analogReference(EXTERNAL);
pinMode(ledPin, OUTPUT);
lcd.begin(16, 2);
lcd.setRGB(colorR, colorG, colorB);
lcd.print("Flow & Temp");
currentTime = millis();
cloopTime = currentTime;
}
void loop() {
currentTime = millis();
if (currentTime >= (cloopTime + 1000)) { // Update every second
cloopTime = currentTime;
if (flow_frequency != 0) {
l_minute = (flow_frequency / 7.5); // Flow rate in L/min
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Rate: ");
lcd.print(l_minute);
lcd.print(" L/M");
flow_frequency = 0; // Reset counter
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Flow: 0 L/M");
}
// Determine flow status
if (flow_frequency > 0) {
LastPulseDetected = millis(); // Flow detected
if (FirstFlowDetected == 0) FirstFlowDetected = millis();
}
if ((millis() - LastPulseDetected < NO_FLOW_TIMEOUT) &&
(millis() - FirstFlowDetected > WAIT_PERIOD)) {
digitalWrite(ledPin, LOW); // Flow is OK, turn off LED
} else {
digitalWrite(ledPin, HIGH); // No flow, turn on LED
}
}
// Read temperature
float current = analogRead(termPin);
current = 1023.0 / current - 1;
current = resistance / current;
float temperature = current / termNom;
temperature = log(temperature);
temperature /= beta;
temperature += 1.0 / (refTemp + 273.15);
temperature = 1.0 / temperature;
temperature -= 273.15;
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temperature, 1);
lcd.print("C ");
// Turn on LED if temperature is too high
if (temperature > TEMP_THRESHOLD) {
digitalWrite(ledPin, HIGH);
}
delay(250);
}
The code I posted would not compile and so could never be uploaded. Maybe you meant to say that you combined my code with your code and uploaded that? If so, do you think it is possible you made an error when you combined them? Do you think it might be helpful if you posted that combined code so the forum could check it?
Another unprotected read of flow_frequency. Are there are others too?
Your code is already reading flow_frequency in a protected way and storing the value in current_flow_frequency. So why not use that instead of doing more unprotected reads?
I was looking for where FirstFlowDetected is ever reset to zero. I haven't read the code very closely, perhaps your algorithm does ot require that.
Also, you have
Serial.begin(9600);
but you make no use of it. The serial monitor is easier to use than printing to the LCD. I would place print statements all over to verify the values in the variables and confirm that the flow through the code is what you think.
Here, for example
if ((millis() - LastPulseDetected < NO_FLOW_TIMEOUT) &&
(millis() - FirstFlowDetected > WAIT_PERIOD)) {
digitalWrite(ledPin, LOW); // Flow is OK, turn off LED
} else {
digitalWrite(ledPin, HIGH); // No flow, turn on LED
}
I'd want to see what the two terms being anded were each, and confirm that anything ever writes ledPin LOW or see that nthing does and expand the question whynot?