Project: Measure and record water flowing out of a tank, shutting off flow with an ardunio-controlled valve at select points. Bonus beeper.
Components: A scale to read the weight of the water leaving the tank. Two solenoid valves to shut off water flow when certain volumes of water have been drained. All the wiring is functioning as intended.
Code: I used the example code from those linked instructions for both systems, but modified it so that the system takes a reading every 5 seconds and then if else decisions determine whether to close the valves for a certain amount of time based on that reading. I’ve included the code below.
Problem: The scale works fine - I can read how much water has left the system accurately through the serial monitor. The valves work fine - I can set them up to open and close continuously. However, the system only takes a single reading to output to the serial monitor and then it just stops - the void loop() doesn’t loop.
I have had this same problem - unsolved and the project modification was abandoned because of it - when adding a solenoid valve to an already fully functional system with if-else statements to control the valve.
Question: Any suggestions, or experience? Is there something weird going on where it’s hanging up waiting for some other instruction to the solenoid output pins? Is there something special I need to do to allow Arduino logic to get over its fear of solenoid valve control?
#include "HX711.h"
#define calibration_factor -10100.0 //This value is obtained using the SparkFun_HX711_Calibration sketch
/* It is negative because the system will tare with a full tank of water and be reading a "negative"
* weight as water leaves the system.
* Will need to open valve until certain (irregular) summed weight targets are reached, at which point
* the 30 minute delay kicks the valve off for a certain amount of time.
*/
#define DOUT A1
#define CLK A0
HX711 scale;
int const timestep_data = 5000; // time in ms between each data output
float init_WeightReading = 0;
float WeightReading = 0;
float Live_Vol_Passed = 0;
float Batch_Volume = 0;
int BatchNumber = 0; // Planning to do 1/2 gallon batches per each cartridge, so each increment should be 1 gallon
float Total_Water_Passed = 0;
const int gallon_lbs_weight = 8.4; // 1 gallon weighs 8.34 lbs. Scale was calibrated to read 1 gallon as approx 8.4 lbs
// For working in metric:
const int gallon_to_liter = 3.785; // 1 gallon is equal to 3.785 liters
const int kilogram_to_lbs = 2.2; // 1 kilogram is equal to 2.2 lbs
const int liter_kg_weight = 1; // 1 liter weighs 1 kilogram
const int waterPin = A8;
const int airPin = A9;
const int buzzerPin = 9;
///////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(waterPin, OUTPUT); //Sets the pin as an output
pinMode(airPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
scale.begin(DOUT, CLK);
scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0
Serial.println("CLEARDATA");
Serial.println("LABEL,TIME,TIMER,Weight Reading (lbs),Volume Passed (gal),TOTAL Volume Passed (gal),Batches Passed");
digitalWrite(waterPin, HIGH);
digitalWrite(airPin, LOW);
delay(3000); // wait for 3 seconds
}
void loop() {
// put your main code here, to run repeatedly:
// Time = millis(); //start time (ms)
boolean Pause = false;
WeightReading = scale.get_units();
Live_Vol_Passed = (WeightReading - init_WeightReading)/gallon_lbs_weight;
init_WeightReading = WeightReading;
//Decide what this data means
if (Live_Vol_Passed < -1) { // A refill has (most likely) occured, retry
delay (5000);
WeightReading = scale.get_units();
Live_Vol_Passed = (WeightReading - init_WeightReading)/gallon_lbs_weight;
}
Batch_Volume = Batch_Volume + Live_Vol_Passed;
Total_Water_Passed = Total_Water_Passed + Live_Vol_Passed;
if (Batch_Volume > 1) { // An "influent batch has been passed and the system should pause for between 30 to 90 minutes
BatchNumber = BatchNumber + 1;
digitalWrite(waterPin, LOW);
digitalWrite(airPin, HIGH);
// make noise, 3 buzzes
for (int buzz = 0; buzz < 5; buzz++) {
tone(buzzerPin, 1000);
delay(1000);
noTone(buzzerPin);
delay(1000);
}
Pause = true; //establish wait 60 minutes
}
// LABEL,TIME,TIMER,Weight Reading (lbs),Volume Passed (gal),TOTAL Volume Passed (gal),Batches Passed
Serial.print("DATA,TIME,TIMER,"); //outputs the time of data and a timer to the first two columns of excel sheet
Serial.print(String(WeightReading) + ","); //outputs the current weight read by the scale
Serial.print(String(Live_Vol_Passed) + ","); //outputs the volume of water that passed since last reading
Serial.print(String(Total_Water_Passed) + ","); //outputs the total volume of water that has passed since test start
Serial.print(String(BatchNumber) + ","); //outputs the number of influent batches that have been passed through the filters
if (Pause = true) {
digitalWrite(waterPin, LOW);
digitalWrite(airPin, HIGH);
delay(3600000); // batch finished, wait 1 hour
}
else {
delay(timestep_data); // keep collecting data, 5 second interval
}
}