Exit and Return to loop

Hi,

I need a little help please. I’m using a Nano. What I want to do is as follows:

  1. When I make pin D2 go HIGH, I want pin D4 to go HIGH for 5 minutes.

  2. When I make pin D3 go HIGH, I want pin D5 to go HIGH for 5 minutes.

The problem is I want to perform the second operation when the first operation hasn’t completed, in other words within the 5 minutes.

Therefore I can’t use the delay() function but will need some sort of loop() with a condition to check the state of the D3 pin and a break out of the loop and then return once I’ve checked the state of pin D3.

I need to be able to do the same if I make pin D3 go HIGH first and then pin D2 go HIGH.

Thank you in advance for any help you can give.

Dermot

Thanks for that. I've looked at the BlinkWithoutDelay but didn't fully understand it and so thought it might not be relevant.
I'll re-visit it and see if I can make sense of it now.
Thanks again.

Complete commonsense 101 howto do more than one thing at a time.

That is by Nick Gammon whose site is loaded with such howto's.
He covers the whys along the way, you will know whatcher doing!

1 Like

What is to happen if either signal goes LOW during its respective five minute period?

Then what is to happen if either signal goes HIGH again during its respective five minute period?

If you don't answer all such questions, the code you write will provide answers, answers you might not have even realized there were questions for.

a7

Here's another by Nick Gammon, never a waste of time. Read it like you understand it until you do.

a7

1 Like

Thanks everybody for the help. I have a bit of thinking to do :grinning:

so in order to handle 2 different timing events, you can use arrays to maintain the start time of each event

1 Like

Which Arduino?
What is connected to pins 2 & 3? How are they connected?
What is connected to pins 4 & 5? How are they connected?

Another beginner like 12945 other beginners that have difficulties with this "BWD"-example. Though I have given up the hope that this example will ever be improved.

This video explains it pretty good

I think part of the problem is not realising that you multi task in life all the time, it's just that with a computer it happens much faster.

Think how a restaurant works: a waiter goes from table to table waiting on customers as needed, a waiter doesn't stay by one table waiting for the customer to need them. Similarly in the kitchen, the chef will be cooking several meals at the same time, attending to each when needed, leaving them to cook when appropriate. Multi tasking code is exactly the same in principle, just a lot faster.

You want to do more than one thing at the same time.

That is why I linked you to Nick: you have begun to identify the problem!

[quote]Let's look at an analogy. Say you want to cook breakfast. You need to cook:

  • Coffee - takes 1 minute

  • Bacon - takes 2 minutes

  • Eggs - takes 3 minutes

Now a seasoned cook would NOT do this:

  • Put coffee on. Stare at watch until 1 minute has elapsed. Pour coffee.

  • Cook bacon. Stare at watch until 2 minutes have elapsed. Serve bacon.

  • Fry eggs. Stare at watch until 3 minutes have elapsed. Serve eggs.

The flaw in this is that whichever way you do it, something is going to be cooked too early (and get cold).

In computer terminology this is blocking . That is, you don't do anything else until the one task at hand is over.[/quote]

And then he gives a solution and the code with full comments.
The link's in a post above.

OK, How about doing it like this? (I set them to 2 seconds so you can see 'em work.)

-jim lee

Thanks jimLee for that. A perfect solution.
Thanks to all the other contributors as well. I learned a lot about millis() as well.
Great forum with very helpful people.

Did you notice that if you keep pressing a button, the LED appears to remain on, and stays on until two seconds after the last time its button went pressed?

a7

Yeah. I noticed that. Great solution.

You are very welcome!

-jim lee

1 Like

Hi. I'm back again looking for a bit of help with millis(). I've read up on it and I think I understand it now.
What I am trying to do now is to connect a DTMF Module to my Nano to control the BUILTIN_LED. The DTMF Module is connected to my laptop (later a phone) via an audio cable through which I send data which make the 5 output pins on the module go high or low. These pins are then connected to the A1, A2, A3,A4 and A5 input pins of the Nano.
The A5 pin is connected to the StQ pin on the DTMF which briefly lights up when any key is pressed.
When I press the digit 1 on the DTMF software on the laptop it makes the A1 pin high and the other pins low. When this happens I want the BUILTIN_LED to light for 10 seconds.
Hopefully this will be clearer when you see the code below.
The problem I'm having is that the BUILTIN_LED doesn't stay on for the 10 seconds. The time it stays on varies from 3 to 6 seconds on a random basis so I think it may be a problem with the way I'm using unsigned long etc.
Any help greatly appreciated.
Dermot

const int A1Pin = A1;  //Q1 on DTMF Module
const int A2Pin = A2;  //Q2 on DTMF Module
const int A3Pin = A3;  //Q3 on DTMF Module
const int A4Pin = A4;  //Q4 on DTMF Module
const int A5Pin = A5;  //StQ on DTMF Module
const unsigned long eventInterval = 10000;
unsigned long previousTime = 0;
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(A1Pin, INPUT);  // DTMF Q1
  pinMode(A2Pin, INPUT);  // DTMF Q2
  pinMode(A3Pin, INPUT);  // DTMF Q3
  pinMode(A4Pin, INPUT);  // DTMF Q4
  pinMode(A5Pin, INPUT);  // DTMF StQ
}

void loop() {
  unsigned long currentTime = millis();

  if ((digitalRead(A1Pin) == HIGH) && (digitalRead(A2Pin) == LOW) && (digitalRead(A3Pin) == LOW) && (digitalRead(A4Pin) == LOW) && (digitalRead(A5Pin) == HIGH)) {
    digitalWrite(LED_BUILTIN, HIGH);
  }

  if (currentTime - previousTime >= eventInterval) {
    previousTime = currentTime;

    digitalWrite(LED_BUILTIN, LOW);
  }
}

The place to do that is when you turn on the LED, viz:

  if ((digitalRead(A1Pin) == HIGH) && (digitalRead(A2Pin) == LOW) && (digitalRead(A3Pin) == LOW) && (digitalRead(A4Pin) == LOW) && (digitalRead(A5Pin) == HIGH)) {
    digitalWrite(LED_BUILTIN, HIGH);
    previousTime = currentTime;
  }

TBH I'd have to run the code as you have it to see why you ever get anything lighting up, oh wait, maybe I see it… it is continuously marking off the interval, and your request for LED comes at random inside that interval, so you only get a random "rest of the current interval" amount of joy.

So yeah set/reset the timer when you start the activity to be timed.

a7

That solved it. Thanks a million; I really appreciate that. It's been driving me nuts. :face_with_thermometer:
Dermot

@dermotx if you are going to work with the DTMF chip, here's a nice line of code for you

    byte buttonNumber = (digitalRead(A4) == HIGH ? 8 : 0) + (digitalRead(A3) == HIGH ? 4 : 0) + (digitalRead(A2) == HIGH ? 2 : 0) + (digitalRead(A1) == HIGH ? 1 : 0);

which uses binary weighted addition to turn the four inputs into a number 0..15.

You can do even better if you were to use direct port manipulation. All that needs is for the four bits to be on one port of the microprocessor, then you can read them all at once and very directly get a button number. It's way faster too, but that doesn't always matter too much.

For another day. The digitaRead() expression will work no matter the Arduino, no matter the pins you use for the four bits.

a7