Help needed with logic

I have a 'n' irrigation timers, which kick in one after the other with each having a break of >3 minutes in between.
I have a flow meter connected to an Arduino UNO and want to detect which valve in sequence is on.
The Arduino calculates flow and volume with every measure and publishes it via MQTT to an automation system, which takes care of data presentation, etc.

My pseudo code is:

loop
  measureWaterFlow()
    detachInterrupt()
    if flow do waterMeter()
      publish flow and volume
      set timerArctive true
    attachInterrupt()

  identifyTimerInAction()

... and here (after three hours) I got stuck...

basically most of the 24h day we have 0 flow.
then 'a' valve kicks in
water flows
inc valve counter by 1
publish valve n
now some sort of stop timer that gets reset by timerArctive = true, should run for say 60 seconds
if not reset by timerArctive = true
publish valve n off
reset timerArctive to false

It looks like needing a second timer to get this logic working.

What I can provide is a daily message for the Arduino to start stop checking for flow;
So say once getToWork = true, it takes the next flow to start with valve 1
I send a getToWork = false, because I can and think it is helpful

Any pseudo code idea appreciated...

Rather than try to write pseudo code at this stage of your thinking just write down in English the steps that need to happen with one step on each line. I often start with maybe 3 or 4 big-ticket steps and then split each one up into smaller and smaller steps until I have everything accounted for.

At that stage it is generally straightforward to turn the description into code.

As a separate comment I have no idea why you have detachInterrupt() and attachInterrupt() in your pseudo code. I don't even know why there may have been an attachInterrupt() in the first place. There is almost certainly no need to detach an interrupt although it may be necessary to turn interrupts off very very briefly to read a multi-byte value that is updated in an Interrupt Service Routine (ISR). Use noInterrupts() and interrupts() to disable and re-enable interrupts.

...R

Hi,

I have a 'n' irrigation timers, which kick in one after the other with each having a break of >3 minutes in between.

You have "n" irrigation timers, they start one after the other every three minutes.
How long does the timer run, what does it operate, a valve for each timer?

If the flowmeter is measuring TOTAL water flow then, you will be able to workout how many valves are open, but not which ones in particular, unless as they open in 3min sequence, they stay open.

f = flow through one valve
n = number of valve open.
Ftot = Total flow registered by flowmeter.

n = Ftot / f

Can you post a basic diagram of your irrigation system, including vales and flowmeter?

Tom... :slight_smile:

Thanks Robin...
WRT the interrupts... I will look into it... was based on a Gammon article.

Tom: the irrigation timers are self-contained timers with valve and battery.
They start in half hour spacing (e.g. 0800, 0830, 0900, etc.) and run for up to 20 minutes.
There are 7 of these timers.
I can send a message to the Arduino at 0730 to start listening.
Once a timer kicks in the pump starts running, meaning we have flow and volume.
This will go for the duration the timer is set to (10, 15 20 minutes).
So the first flow will be timer 1.
Once it stops, say after 30 seconds, we can say timer 1 is off.
Next flow = next timer
and so forth until timer 7

So, we can detect a timer when we have flow.
the timer stopped when the flow stopped.
giving us hooks for timers to then publish the timer state [on|off]

... now that I have written it all out, I should be fine... (have a cold ATM which sort of takes my brain out).

BTW: the flow and volume calculations are not the issue, have them coded, works.
It is just who triggers a timer start, and how do I progress through them I am wondering about.

MaxG:
BTW: the flow and volume calculations are not the issue, have them coded, works.
It is just who triggers a timer start, and how do I progress through them I am wondering about.

@larryd's State machine and timer tutorial may be useful.

dougp:
@larryd's State machine and timer tutorial may be useful.

Silly me... how could I forget state machines!

You could treat the n timers as

 // these snippets were not compiled or tested.  

const byte num = n;
byte timer;                  // this is the index, it gets incremented at the end of loop(), 1 timer at a time in loop() 

unsigned long startTimer[ num ]; // unsigned long used correctly will cover -up to- 49.71... days wide timing
unsigned long runTimer[ num ];   // unsigned subtraction gets the difference between start and end, never crashes

............ and then down in loop()

  if ( runTimer[ timer ] > 0 ) // only runs if runtime is set
  {
    if ( millis() - startTimer[ timer ]  >= runTimer[ timer ]  ) // if time is up
    {
      runTimer[ timer ] = 0; // timer is off until a task turns it on
      .. do whatever is supposed to happen on time
    }
  }

...................... near the end of loop()

  if ( ++timer = num ) // pre-increment the timer index, it adds then compares
  {
    timer = 0;
  }

} // end of void loop()

Perhaps when a timer finishes, it triggers a scheduler to set the next event(s) in motion.

Thanks for chipping in... :slight_smile:

This is really a simple solution I am after.

I have a 4-valve controller, which gets a messages from the automation system via MQTT to switch a valve on and off at times determined by the automation system. In this case it triggers the first valve, runs it for x time, adds a pause of 1 minute and triggers the next. All good, all working. One benefit of this solution is it graphs water use per valve and flow rate. Both allow to detect anomalies in sprinkler valve or system, and of course give me an idea of whether I am dispensing enough water sprinkler.

I have a second pump station (the one looking for a solution), which has a flow sensor and 7 independent irrigation timers, set to go off 30 minutes after the other, and set to do whatever minutes <25min.
The idea was to collect and graph the data of these 7 timers, by hooking up a UNO.

The Arduino sits there and waits for something to happen, which is 'flow detected', because 'a' timer\valve went off.
Seemingly easy to do... in particular, because I do not have to detect timer valve 1; I simply send a message to the Arduino saying 'start' (before the the first timer goes off). It then knows the next flow is valve 1, next valve 2 and so on.

Let's say the timers finish by 12:00; I send another message "stop looking for flow"; until the next morning when the 'start' comes on.

So I have sorted the 'whoo is timer 1' issue. All the others go like: flow stopped for 10 seconds, tell the automation system the timer is off. Next flow detected increments the timer/valve counter.

I'm not Nick. I just like his blogs. They save a lot of typing and correcting as they're there are they're correct.

I give you an example of event-driven code made simple. Whatever tasks get started are able to run until completed or turned off, it's all in those snipped ............... parts and the // do something ~~~ part.

Throw a switch-case in the do something part and different timers can act different ways.