Hi, first post on here, new to programming with Arduino and am after some guidance with a particular feature of my first project.
I'm using the 'simple pulse counter example' that I found here: Simple Pulse Counter - Programming Questions - Arduino Forum, It works fine when I use it in a sketch on it's own, but once I integrate this feature into my sketch I am experiencing issues, and am having trouble visualising what the sketch is doing to cause the issue.
This is my sketch:
const unsigned long SECOND = 1000UL;
const unsigned long MINUTE = (SECOND*60UL);
const unsigned long HOUR = (MINUTE*60UL); // for the 'clock'
unsigned long waterTimeA = (10*SECOND); //Run time 45sec for solenoid A
unsigned long delayTimeA = (20*SECOND); //Delay time 3Hrs for solenoid A [TIMING]
//-----------------------------------------------------------
const int pumpPin = 2;
const int SolenoidAPin = 3;
const int Hallinput = 12; //Define the physical pins on the board [BOARD]
const int LockoutLED = 5;
const int resetSwitch = 6;
unsigned long previousMillis = 0; // will store last time Solenoid was updated
int SolenoidStateA = HIGH; // State used to set the solenoid,
// HIGH (pump on) on startup
//---------------------------------------------------------------------------------------------------------------------------------------------------------
void setup()
{delay (5000); //gives me a few seconds to open the serial monitor before program starts
Serial.begin(9600);
pinMode(SolenoidAPin, OUTPUT);
pinMode(pumpPin, OUTPUT);
pinMode(Hallinput, INPUT_PULLUP); //set-up pins [BOARD][SETUP]
pinMode(LockoutLED, OUTPUT);
pinMode(resetSwitch, INPUT_PULLUP);
pinsOn(); // pump etc starts on startup until water time has elapsed.
}
void loop()
{
unsigned long currentMillis = millis(); //Current 'time'
if((SolenoidStateA == HIGH) && (currentMillis - previousMillis >= waterTimeA))
{
SolenoidStateA = LOW; // Turn it off
previousMillis = currentMillis; // Remember the time //to do: **************** for '5' times then delay for 9 hrs*****************
pinsOff();
}
else if ((SolenoidStateA == LOW) && (currentMillis - previousMillis >= delayTimeA))
{
SolenoidStateA = HIGH; // Turn it on
previousMillis = currentMillis; // Remember the time
pinsOn();
} //[TIMING][MAIN LOOP]
}
//FUNCTIONS-------------//FUNCTIONS-----------//
void pinsOn(){
digitalWrite(SolenoidAPin, SolenoidStateA);
runPumpProtect();
Serial.println(" pinsOn running") ; // Runs @ watering time
}
//-----------------------------------------------------------
void pinsOff(){
digitalWrite(SolenoidAPin, SolenoidStateA);
digitalWrite(pumpPin, SolenoidStateA);
digitalWrite(Hallinput, SolenoidStateA);
Serial.println(" pinsOff running - Solenoid OFF Hall OFF pump OFF ") ; // Runs to turn pump etc. off
}
//-----------------------------------------------------------
void runPumpProtect(){
digitalWrite(pumpPin, HIGH);
Serial.println("PumpProtect running");
delay (10); // delay for pump priming
hallSensor(); // runs Hall sensor to check flow is OK
}
//-----------------------------------------------------------
void hallSensor(){
int pulse = 0; // Variable for saving pulses count.
int var = 0;
unsigned long currentTime = millis();
while (currentTime + 5000 > millis()){
if(digitalRead(Hallinput) > var)
{
var = 1;
pulse++;
Serial.print(pulse);
Serial.print(" pulse recieved ");
}
if(digitalRead(Hallinput) == 0) {var = 0;}
delay(50); // debouncing.
} //pulses counted over a period of 5seconds (5000 millis)
if (pulse >= 5){
Serial.print(" 5+ pulses recieved- flow is OK"); //Continues rest of program until waterTimeA =! TRUE
}
else if (pulse <5){
Serial.print("LOCKOUT"); //lockout requires all pins = OFF
LOCKOUT(); //runs lockout if <5 pulses recieved in time frame
}
else{
Serial.print("not sure whats happening"); // this should never run
LOCKOUT();
}
}
//-----------------------------------------------------------
void LOCKOUT(){ //Runs if Hall sensor recieves <5 pulses in 5 sec. **Dry run protection for the pump.**
digitalWrite(SolenoidAPin, LOW);
digitalWrite(pumpPin, LOW);
digitalWrite(Hallinput, LOW);
digitalWrite(LockoutLED, HIGH);
digitalWrite(resetSwitch, HIGH);
Serial.println("EMERGENCY LOCKOUT") ;
int L = 1;
while (L == 1) {
if (digitalRead (resetSwitch)== LOW){
Serial.println("reset pressed");
digitalWrite(LockoutLED, LOW);
break;}
};
}
In a nutshell, this will water my greenhouse, the plan is for it to water the tomatoes for 45 seconds every 3 hours, but I have changed the timing in this example to water for 10seconds every 20 seconds and to print what it's doing to the serial monitor, just so i can visualise what is happening.
The problem I am facing is in the hallSensor() function. I'm planning on using a hall effect water flow sensor to count the water flow over 5 seconds once the pump is started, if the water flow sensor detects pulses (ie the water is flowing) then the pump will continue to run for the full 45 second watering time, if the flow sensor detects no water flow this would mean the water butt is empty and the program would run an emergency lockout code to provide protection to the pump to stop it running dry. (reset switch would need to be pressed to resume normal operation.)
Like I said before, the 'simple pulse counter example' (Link above) works well on its own, but once i use it in my sketch, it works ok in the first run through the loop- it detects no flow and then goes into 'Lockout' (runs the lockout() function). Once I hit my reset switch (pin 6) it runs the code again then the pulse counter is counting loads of pulses in the 5 second time window meaning the 'pump' is continuing to run when it shouldn't.
If anyone can give me some help visualising what is going on to make the code behave like this I would be grateful, i suspect the fault lies with the while loop in the HallSensor() function, but can't fathom out why, as it works when running as it's own example.
If anyone would like to make other suggestions to simplify the code or tell me what other noob errors I've made then feel free. If you need any more info or clarification please let me know. Using an Arduino Leonardo.
Thank you for any guidance.