Run two commands at the same time.

Hello Forum...

It has been a while since I have messed with my Arduino and i have some free time but I am still stuck on an old problem and I hope someone can help.

I am trying to write my code so there will be two things the arduino is constantly checking on and then doing the action if triggered. I can get the code I have written to work by themselves but can't figure out how to get them to work at teh same time.

Here are the two things I am trying to do...

I have a Paralax PIR that i want to trigger some light when it senses motion and to only stay on for 30 seconds.

I have a thermistor and i have two small DC fans I want to kick on when the trigger temperature is reached.

I think what i am asking is how to run these two commands at the same time?

I am using a really simple IF ELSE statement for both commands and can I post the code if it would help.

Thanks for any help anyone can provide.

The Arduino doesn't have multi-tasking so you have to implement it yourself.

This means re-writing any code that uses delay() to use millis() or micros() instead.

So instead of thinking "when I see event A I must do B, delay for time t and then do C" you have to think:
"When I see event A I must do B, and record the time that C is supposed to happen". Some other test in the loop() routine has to check for when/if action C is to be done.

The code in loop() must check for the condition for each action that is to happen, but only take a short time on each test.

If you are not needing to use delay() it should be pretty straightforward - just an IF statement for each action to check. No ELSEs are needed

void loop ()
{
  if (condition1)
  {
     action1 () ;
  }
  if (condition2)
  {
     action2 () ;
  }
  ...
}

Okay what you said makes sence but I was using delay () for how long to keep the on the lights and then again for how long to run the fans once the trigger temp was reached.

Can i still do it with the millis() or micros() you mentioned. I'm not familiar with these but if it can work I will look them up.

Can i still do it with the millis() or micros() you mentioned. I'm not familiar with these but if it can work I will look them up.

They are not a direct replacement for delay(). You effectively build a state machine. Each event you want to occur has to check millis() to see if it time to fire. Events could be turn LED on, turn LED off, turn Fan off, turn Fan on, etc.

To help illustrate, here is a tutorial I wrote. The only caveat is that these examples do not handle roll-over correctly:
http://www.cmiyc.com/blog/2011/01/06/millis-tutorial/

SummitSeeker:
Okay what you said makes sence but I was using delay () for how long to keep the on the lights and then again for how long to run the fans once the trigger temp was reached.

Can i still do it with the millis() or micros() you mentioned. I'm not familiar with these but if it can work I will look them up.

The use of millis() and micros() allows you setup as many separate timers as you could ever need. It's just a matter of defining your variables to be used to keep track of each and every event you wish to track. Each task you want to service will require two variables, one to store the starting time for that task sense the last time it was activated and a interval variable to store how much time must pass for that specific event before you take action on it once again. So a unique timer variable will tell you when to start an alarm horn and also start another timer to tell you when it's time to stop the alarm horn, etc, etc, etc.

Then your main loop is just a series of tests (if statements) performed on all your event variables to see if the desired amount of time has passed to take some specific action. Because the main loop can handle many such tests in just milliseconds it will appear as if everything is checked and performed in parallel.

Lefty

Okay after briefly looking at the mills() solution i can see that it will take me a while to get it...

This may be a bad question to ask on an Arduino forum but is there another development board that can multitask and do what i need ti to do???? I love the arduino but if there is something else i should be using i would love to know...

Thanks for the help..

-edit- WHen i was writing this reply I dodn't see some of the more detailed responses... I'll start reading up on how the mills() stuff works and see if I can figure it out...

I'm sure I'll be back soon...

-H-

Do you multi-task? Probably.

Can you type and play the guitar at the same time? Well, unless you are not normal, no.

But YOU could do what you are asking the Arduino to do, and if you can, the Arduino can.

It simply requires a little different mindset.

What you are looking to create is a state machine, with transitions between the states causing certain actions to occur.

Make a list of the states that you would have to deal with. PIR sensing motion. PIR not sensing motion. Thermistor is cold. Thermistor is hot.

Now make a list of the things that trigger a change from one state to another. You read the PIR and see that it is HIGH and was NOT, or is LOW and was not. You read the thermistor temperature and it is above a threshold and was not, or it below a threshold and was not.

Now, define what happens when a state transition is required. For instance, if the PIR was not sensing motion, and it is now, you need to turn a light on, and record when that happened. Or, the temperature went above the threshold, so you turn a fan on. Or the temperature went below a threshold, so you turn the fan off.

You'll see that some states have a time element (PIR not sensing motion and light is on) and some do not (man, it's cold in here). So, some transitions occur when enough time has elapsed.

So, on each pass through loop, you determine whether a transition is required (it got hot enough, it got cold enough, the PIR sensed motion, etc.) based on sensor input. If so, you perform the required transition. Then, you determine if any time-based transitions are required (PIR not sensing motion and the light is on and has been for 30 seconds, for instance). If so, you perform the transition (turn the damned light off, I'm not made of money).

All of these things are easily performed by the Arduino. No multi-tasking required.

is there another development board that can multitask and do what i need ti to do?

Sure. Netduino has multithreading, albeit it's still single core so it's faking it to some extent. Propeller has multiple cores. For what you want to do though, they're massive overkill with a steeper learning curve. Indeed, Arduino is massive overkill, but let's not worry about that. It is fast enough that you'll never know that it isn't doing your multiple tasks simultaneously, you just need to get your head around using millis() - there are many many examples posted in the forums.

(SummitSeeker: is the appropiate time to ask if you have read Arduino Playground - AvoidDelay ?)

Thanks for the great posts... I've been trying to get this down and these posts are very helpful... No I had not read it until now...

Is there a simple example using millis() to do more than one thing at a time...??? or even a very basic example doing anything and using millis()...???

SummitSeeker:
Is there a simple example using millis() to do more than one thing at a time

Not sure if it's simple enough but try this:

http://www.utopiamechanicus.com/114/ardunio-loop-no-delay/

I know its has been a while but I have had some free time to try to work on writing my code using millis() but i need some help.. I followed the tutorial on the link but a few things were fuzzy to me... I get the main jist of the millis() function and principals behind it but just can't figure out exactly how to write the code...

Below is the code i have so far... What I think is wrong and dont understand is the timerLight=msec+5000; part and then the second if statement...

I think i am really close to getting this but would love some tips...

const int fanPin = 13;
const int threshold = 900;
unsigned long timerLight=0;

void setup() {
pinMode(fanPin, OUTPUT);
Serial.begin(9600);
}
void loop() {

int analogValue = analogRead(0);
unsigned long msec=millis();

if (analogValue > threshold)
{
digitalWrite(fanPin, HIGH);
Serial.println(analogRead(0));
Serial.println("HIGH");
timerLight=msec+5000;
}

if ( timerLight && timerLight<msec )
{
digitalWrite(fanPin, LOW);
Serial.println(analogRead(0));
Serial.println("LOW");
timerLight=0;
}

}

Try reading this:

When posting code please use [ code ] tags - select it and hit the "#" button above the input box.

... is there another development board that can multitask and do what i need ti to do????

This board will do what you need to do, easily. You just have to learn a few things. If you got a different board you would also have to learn things, so you aren't that much further ahead.