Parts work separately, not together

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
  }

}

You have a couple of errors in your code.

int const timestep_data = 5000;  // time in ms between each data output

You have declared an integer named const. I am not sure why the preprocessor didn't kick this line out.

if (Pause = true) {

I think you mean

if (Pause == true) {

Also, it is poor practice to start variable names with an upper case letter. "BatchNumber" should be "batchNumber". Again, this is for readability- it will still compile OK. Most of us use camelBack style: "Total_Water_Passed" would be "totalWaterPassed"

That's all I see, but the "=" instead of "==" in your if() may be your problem.

SteveMann:
You have a couple of errors in your code.

int const timestep_data = 5000;  // time in ms between each data output

You have declared an integer named const. I am not sure why the preprocessor didn’t kick this line out.

That is not an error. the ‘const’ keyword can come before or after the type but it is much more common to have it come first.

[quote author=ViaXTquestions link=msg=4354878 date=1572489214]



  if (Pause = true) {
    

}

Will always be TRUE since you set Pause equal to true

An observarion on that from way way back - that is a common error and sometimes finding it can be a bit tough

This is your problem:

if (Pause = true) {
digitalWrite(waterPin, LOW);
digitalWrite(airPin, HIGH);
delay(3600000); // batch finished, wait 1 hour
}

Pause = true assigns the value true to variable Pause, and evaluates as true (regardless of the initial value of pause). Then it gets stuck there waiting for an hour before doing anything else.

Do have a look at BlinkWithoutDelay on how to get rid of those delays. loop() is not a place for using delay(), it can come in handy when testing but not good for final code, ever. This is just one example of where delay() may trip you up badly.

So do make sure to get rid of all of them! (that includes the beeping part - you may also want to update your comment there as you make 5 beeps, not 3).

Ahh. Double =.
That appears to have fixed it. THANK YOU!
As well as an extra Serial.println() to go to a new line.

With delay() code you can make 1 thing happen at a time.

Using millis() or micros() unsigned long time code you can make many things happen together. The code for each thing can be separate from the others, run independently in parallel. You can write tasks and think in code tasks this way.

I like the Nick Gammon tutorial at the 1st address below in my signature space. It's very common sense and complete.