Delays and Interrupts

The "Eleven" is our Uno-equivalent Arduino-compatible board, but with a number of improvements including prototyping area, a mini-USB connector, LEDs mounted near the edge, and the D13 LED isolated using a FET. [Product page]
Post Reply
adelspark
Posts: 7
Joined: Sat Feb 23, 2013 7:20 am

Delays and Interrupts

Post by adelspark » Sat Feb 23, 2013 7:54 am

Hi Folks,

I've got my new Eleven and 4 Channel Relay Board and just learnt that I can't use Delays in Interrupts but unfortunately not much explanation on the right way to fix my code.

What I'm doing is opening two separate valves from a first flush rainwater device every two weeks, but am trying to include a rain sensor so that the valves won't open when it's raining (in fact only open about an hour after it stops raining). As you can see I've tried to use the noInterrupts() function to disable the rainsensor causing a delay when the valve is already trying to open. That is, if it did start raining when the valve was open, it should finish draining (two minutes) and then close before the Interrupt can stop the program.

I've temporarily turned the code that was causing issues into a comment (//) so I can get it to work partially and with shorter test times.

Hope I've given you enough information.

Patrick


/*
* This sketch turns the stormwater valves on every 14 days
* for 2 minutes and then off again. It allows for 2 valves
* and their opening/closing is staggered by 1 hour. The optional
* rain sensor input will delay the opening of any valve by 1hr.
* 1st relay, OpnCls, determines the polarity sent to the
* other relays. 2nd & 3rd relays, SouthVlv/NorthVlv control
* the output from OpnCls and send it to the appropriate valve.
*/

#define OpnCls 10
#define SouthVlv 11
#define NorthVlv 12
#define SpareOut 13

int RainSense = 0; //interrupt 0 is on digital pin 2
//volatile int state = HIGH;

#define MinDelay 20000UL //(1 * 60000UL)
#define HrDelay 30000UL //(1 * 3600000UL)
#define DayDelay 60000UL //(14 * 86400000UL - 3883000)

void setup() {
pinMode(OpnCls, OUTPUT);
pinMode(SouthVlv, OUTPUT);
pinMode(NorthVlv, OUTPUT);
pinMode(SpareOut, OUTPUT);

digitalWrite(OpnCls, LOW);
digitalWrite(SouthVlv, LOW);
digitalWrite(NorthVlv, LOW);
digitalWrite(SpareOut, LOW);

attachInterrupt(RainSense, stateChange, LOW);
delay(5000); //delay 5 secs for startup stabilisation
}

void loop() {
//noInterrupts();
digitalWrite(OpnCls, HIGH);
delay(2000UL);
digitalWrite(SouthVlv, HIGH);
delay(10000UL);
digitalWrite(SouthVlv, LOW);
delay(2000UL);
digitalWrite(OpnCls, LOW);
delay(MinDelay);
digitalWrite(SouthVlv, HIGH);
delay(10000UL);
digitalWrite(SouthVlv, LOW);
//interrupts();
delay(HrDelay);
//noInterrupts();
digitalWrite(OpnCls, HIGH);
delay(2000UL);
digitalWrite(NorthVlv, HIGH);
delay(10000UL);
digitalWrite(NorthVlv, LOW);
delay(2000UL);
digitalWrite(OpnCls, LOW);
delay(MinDelay);
digitalWrite(NorthVlv, HIGH);
delay(10000UL);
digitalWrite(NorthVlv, LOW);
//interrupts();
delay(DayDelay);
}

void stateChange()
{
digitalWrite(SpareOut, HIGH);
//delay(30000UL);
digitalWrite(SpareOut, LOW);
}

adelspark
Posts: 7
Joined: Sat Feb 23, 2013 7:20 am

Re: Delays and Interrupts

Post by adelspark » Tue Feb 26, 2013 5:38 am

The timing isn't critical and I'm running it off a solar panel 12V SLA battery so no power outage issues. I'm just more concerned about how I get the sketch to work so that the rain sensor won't stop an open (or opening) valve from closing as soon as it starts raining.

Kaka-bird
Posts: 5
Joined: Thu Feb 14, 2013 8:19 am
Location: Auckland, New Zeland

Re: Delays and Interrupts

Post by Kaka-bird » Thu Feb 28, 2013 1:20 am

Hi Patrick,
My suggestion is that your main loop wants to be that - it is a loop that always runs from top to bottom and then repeats. Within the loop is checks to see if time has expired to fire a task off.

You have a number of tasks here:
- check the rain sensor
- control the outputs at preset times

The trick then is to monitor the time (I use milliseconds) and if I am past the required time I fire the task.

I expect that you would like some sample code...
long ledMillis = 0 ; // will store last time LED was updated
const long intervalOff = 950 ; // LED off time
const long intervalOn = 50 ; // LED on time

void loop()
{
// here is where you'd put code that needs to be running all the time.

// Check to see if it's time for a bit of activity. This is achieved by
// determining the difference between the current time and last time some activity
// occurred.
unsigned long currentMillis = millis();

if (currentMillis - ledMillis > ledInterval) { // time to do something
ledMillis = currentMillis ; // save the time you blinked the LED
if (ledState == LOW) { // if the LED is off turn it on and vice-versa:
ledState = HIGH; // turn LED on
ledInterval = intervalOn ;
}
else {
ledState = LOW; // turn LED off
ledInterval = intervalOff ;
}
digitalWrite(ledPin, ledState); // set the LED with the ledState of the variable:
}
}

The above is my heartbeat code that I use in all my projects - it shows that the main loop is executing. Hopefully it should give you some food for thought on your time monitoring and control.

Let us know how you get on,
Graham

adelspark
Posts: 7
Joined: Sat Feb 23, 2013 7:20 am

Re: Delays and Interrupts

Post by adelspark » Wed Mar 06, 2013 11:13 am

Thanks Graham,

That's definitely given me something to think about. Once I get my head around the idea I'll get back to you.

Cheers

Patrick

bwooce
Posts: 21
Joined: Mon May 28, 2012 11:15 am

Re: Delays and Interrupts

Post by bwooce » Wed Mar 20, 2013 3:35 am

For a system of your complexity you can implement a simple thing with a fancy name -- a Finite State Machine.

In your case, a counter and a switch statement would be enough e.g. something like:

Code: Select all

void loop() {
  switch (counter) {
    case 0:
        Do first thing;
        counter = counter + 1; (or better, counter++)
        break;
    case 1:
        if_enough_time_passed { counter++; }
        break;
    case 2:
        ...
        break;
  }
}
It takes you linearly (in your case) through the items you want to do. It makes it very clear about what step you're up to, and would if you wanted to let you skip steps.

Remember to reset the counter to 0 at the end of your task list, and don't forget the break; statements.

adelspark
Posts: 7
Joined: Sat Feb 23, 2013 7:20 am

Re: Delays and Interrupts

Post by adelspark » Wed Mar 20, 2013 5:26 am

Thanks bwooce,

I'll look into that. Might be a simpler way to go.

Cheers

Post Reply