control pins independently without delay()

I am trying to make a control board that can turn on an doff multiple pins at different times. I can't use the delay(), and the milli() will clock out after a period of time (50 days?). I want to essentially make this :

http://www.efx-tek.com/topics/ez-8.html

Eventually, I want use the arduino mega...I can do basic coding, but this seems pretty advanced.

thanks for any help.

If your delays are all below 49 days, you can use the function millis(). Just don't write your code in a stupid way so it will behave properly with the roll over.

If your delays are longer than 49 days or a resolution of 1 second is good enough, use the Time Library.

Korman

Thanks Korman. I guess I am mis understanding the milli() function. The actual series of events will only last no more that 5 minutes. Sort of like: button is pushed and then various LED's ( actually there are motors and lights and sound) will turn on and off at different times. I will post some code when I get it written and if you could, let me know if I am heading in the right direction.

Here's a posting where I explained a little how you wont affected by the roll over. In the end, it's very simple and no big secret. You can replace enditme with millis() directly.

Korman

Hello Korman,

Here is some code I cobbled together. Eventually I would like to have as many pins being controlled as the arduino will allow (duemillanove, mega...). Currently the code seems to just toggle 2 pins, where as I would like to be able to pick a time when the pin is "on" and then turns "off". I created a function called "sequence" that is called when the switch goes HIGH. This is probably bad code, but it is a begining. Any help and insight would be appreciated.

int buttonPin = 2;
int buttonState = 0;

int value = 0;
int event1 = 9;
int event2 = 10;
int value1=0, value2=0;
long time1, time2;

void setup() {

pinMode(buttonPin, INPUT);

pinMode(event1, OUTPUT);
pinMode(event2, OUTPUT);

time1=millis(); // set time as now
time2=millis();

}
void sequence(){
if(time1 > millis()) {
digitalWrite(event1, value1); // sets the LED on
if(value1 ==0) value1 =1; else value1 = 0; // toggle led value
event1= millis() +1000; // set next time you want to do anything
}

if(event2>millis()) {
digitalWrite(event2, value2); // sets the LED on
if(value2 ==0) value2=1; else value2=0; // toggle led value
event2= millis() +700; // set next time you want to do anything this is faster
}
}

void loop(){
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
//run the milli() multipe pin function
void sequence();
}}

Please edit that last post, highlight the code and hit the # icon.

Is this the sort of thing you want:-

int buttonPin = 2;
int buttonState = 0;
boolean LEDstate1 = false, LEDstate2 = false;
                       
int event1Pin = 9;                        
int event2Pin = 10;
long LEDonTime1, LEDonTime2;

void setup() {

pinMode(buttonPin, INPUT);

pinMode(event1Pin, OUTPUT);
pinMode(event2Pin, OUTPUT);

}

void loop(){
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
   if (buttonState == HIGH) {  // turn both LEDs on for diffrent times
       digitalWrite(event1Pin, HIGH);
       digitalWrite(event2Pin, HIGH);
       LEDstate1 = true;
       LEDstate2 = true;
       LEDonTime1 = millis() + 2000;  // turn this on for 2 seconds
       LEDonTime2 = millis() + 3000;  // turn this on for 3 seconds
}
// see if we need to turn the LEDs off
  if((LEDstate1 == true) && (LEDonTime1> millis()) ) {
                       digitalWrite(event1Pin, LOW);     // sets the LED off
                       LEDstate1= false;
                       }
  if((LEDstate2 == true) && (LEDonTime2> millis()) )  {
                       digitalWrite(event2Pin, LOW);     // sets the LED off
                       LEDstate2 = false;
                      }
}

When a button is pushed the two LEDs will come on, one for 2 seconds the other for 3 seconds. You can add any number of inputs and outputs but the principle is the same. Something initiates an action and sets the time when that action (LED lit in this case) will end. The loop checks for the action and checks for the end of the action. Boolean variables keep track of the states of your LEDs so you are not constantly turning them off when they are off already.

Hey Mike, thanks for the code. I loaded it up and it seems to only pull the pin HIGH when the button is HIGH.

here is a very simple thing I tried, but it did not work:

const int buttonPin = 2;//button attached to pin 2
int buttonState = 0;//variable to store the state of button

                      
int event1 = 13;//ssr to be connected to pin 9 for lights
long eventtime1 = 0;//clock value to be stored at the time milli() is called


void setup() {

pinMode(buttonPin, INPUT);

pinMode(event1, OUTPUT);


}

void loop(){
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
   if (buttonState == HIGH) {  //when button is pushed...
     
      eventtime1 + 500 == millis(); //wait 1/2 a second...

digitalWrite(event1, HIGH);//turn on pin 13 
if(eventtime1 > 3000){  //after 2 1/2 seconds...
  digitalWrite(event1, LOW);//turn off pin 13 

} 
   }
      }

here is an awkward "drawing" of what I am attempting to achieve:

this taking place over a 5 minute period, and when a button is pushed...

Pin
1 ---------||||||||||||---------

2 -----||||||||||||||-----------

3 ---||||||||||||||||||||||||---

4 ------------------||||||||----

5 --------------|||||||||||||---

---- = off(LOW)
|||| = on(HIGH)

thanks

Untested

#define buttonPin 2 //button attached to pin 2
#define event1 13 //ssr to be connected to pin 9 for lights

int buttonState = 0;//variable to store the state of button
unsigned long eventtime1 = 0;//clock value to be stored at the time milli() is called

void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(event1, OUTPUT);
}

void loop()
{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:

  if (buttonState == HIGH && eventtime1 == 0)//when button is pushed...
  {
    eventtime1 = millis() + 500; //Now, plus 500ms
    digitalWrite(event1, HIGH); //turn on pin 13
  }

  if ((millis() >= eventtime1) && (eventtime1 != 0))
  {
    eventtime1 = 0;
    digitalWrite(event1, LOW); //turn off pin 1
  }
}

Shorter still untested

#define buttonPin 2 //button attached to pin 2
#define event1 13 //ssr to be connected to pin 9 for lights

unsigned long eventtime1 = 0; //clock value to be stored at the time milli() is called

void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(event1, OUTPUT);
}

void loop()
{
  if (digitalRead(buttonPin) == HIGH && eventtime1 == 0)//If button is pushed, and eventtime1 is 0 then...
  {
    eventtime1 = millis() + 500; //Set eventtime1 to now + 500ms
    digitalWrite(event1, HIGH); //turn on event1 pin
  }

  if ((millis() >= eventtime1) && (eventtime1 != 0)) //If eventtime1 is now or later than now, and eventtime1 isn't 0, then...
  {
    eventtime1 = 0;
    digitalWrite(event1, LOW); //turn off event1 pin
  }
}

Another untested

#define buttonPin 2 //button attached to pin 2
#define event1 13 //ssr to be connected to pin 9 for lights

unsigned long eventtime1 = 0; //clock value to be stored at the time milli() is called

void setup()
{
  pinMode(event1, OUTPUT);
  attachInterrupt(0, btnDown, RISING); //0 = digital pin 2 or 1 = digital pin 3
}

void loop()
{
  if ((millis() >= eventtime1) && (eventtime1 != 0)) //If eventtime1 is now or later than now, and eventtime1 isn't 0, then...
  {
    eventtime1 = 0;
    digitalWrite(event1, LOW); //turn off event1 pin
  }
}

void btnDown()
{
  if (eventtime1 != 0) return;
  eventtime1 = millis() + 500; //Set eventtime1 to now + 500ms
  digitalWrite(event1, HIGH); //turn on event1 pin
}

Last untested

#define buttonPin 2 //button attached to pin 2
#define event1 13 //ssr to be connected to pin 9 for lights

unsigned long eventtime1 = 0; //clock value to be stored at the time milli() is called

void setup()
{
  pinMode(event1, OUTPUT);
  attachInterrupt(0, btnDown, RISING); //0 = digital pin 2 or 1 = digital pin 3
}

void loop()
{
  if ((millis() - eventtime1 >= 500) && (eventtime1 != 0)) //If eventtime1 is now or later than now, and eventtime1 isn't 0, then...
  {
    eventtime1 = 0;
    digitalWrite(event1, LOW); //turn off event1 pin
  }
}

void btnDown()
{
  if (eventtime1 != 0) return;
  eventtime1 = millis(); //Set eventtime1 to now + 500ms
  digitalWrite(event1, HIGH); //turn on event1 pin
}

They should all do the same (if they work at all), just different ways of doing it.

@cip
Can you explain what you think this code is doing?

      eventtime1 + 500 == millis(); //wait 1/2 a second...

It is almost certainly NOT doing that.

eventtime1 = millis() + 500;

...
if ((millis() >= eventtime1) ...
...

Bzzzt - you just created two bugs. Cert, they appear only every 49 days, but the code will still fail. The way you wrote it, this will fail at the roll-over of the millis() counter.

If you want to do it correctly so that it won't fail use only:

if (millis() - starttime > 500) ....

Korman

Well, I know it is not doing what I want, obviously, what I was attempting was to delay the turning on of a pin .5 seconds after the mill() was called. I am not clear on how to implement the milli() command, and my thinking was that I was adding 500 milliseconds on to the time that the milli() command was first called.

I will look at bld's helpful response and see if that will clear things up.

Looking at the mistake you did, you might want to read about this = - Arduino Reference and this http://arduino.cc/en/Reference/If

This is the two you mixed up :slight_smile:

Thanks for the examples bld. I tested them and they didn't do what I am looking to get done. Unfortunately, if( time ==money) it is just easier and cheaper to get the ez-8 from efx-tek. I appreciate all the help, and I was hoping that it would have been easier, but I have to step away from this for awhile. I am also looking at cubloc to tackle this.

I reviewed the pages that you suggested, and I see the issues I was tripping up on...but I still am having problems "seeing" how the milli() function is called and used.

I'll stick to the single pin delay stuff for awhile and leave the multiple pin control to other products.

Didn't my example turn the led on, waited 500ms, then turned it off again?

to use millis(); is like using everything else

what-to-set = what-to-set-it-to;

just like you set the int and long in the top to zero

unsigned long now = 0;

setup()
{
  now = millis();
}

or

setup()
{
  now = millis() + 500;
}

the first will set it to what the current millis is, and the next will set it to the current plus 500

setup()
{
  now + 500 = millis();
}

wont work, because you want to set now + 500 to millis() but there are no now+500 but it don't catch it because it is not a syntax error, because you can do

if (now+500==millis())

and millis is just a number, counting how many milliseconds has passed since it was turned on. Lets say the arduino have been on for 1 second, and you press the button.

void btnDown()
{
  if (eventtime1 != 0) return;
  eventtime1 = millis(); //Set eventtime1 to now
  digitalWrite(event1, HIGH); //turn on event1 pin
}

eventtime1 will then be set to 1000, because 1 second = 1000 millis

the loop will then check the time passed

if(millis() - eventtime1 >= 500)

after 500ms millis() will then be 1500 because it is 500ms since it was powered up

if 1500 minus 1000 is, or bigger than 500 then...

eventtime1 = 0;
digitalWrite(event1, LOW); //turn off event1 pin

I hope this helps you to be able to use millis() :slight_smile:

Just tested my last example on my duemilanove and it is doing exactly what you were trying to do in your first attempt

And when I got started... I couldn't stop again...

#define buttonPin 2 //button attached to pin 2

#define led1 13
#define led2 12
#define led3 11
#define led4 10
#define led5 9

unsigned long btnMillis = 0; //clock value to be stored at the time milli() is called

void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);

  attachInterrupt(0, btnDown, RISING); //0 = digital pin 2 or 1 = digital pin 3
}

void loop()
{
  if (btnMillis != 0)
  {
    unsigned long timePassed = millis() - btnMillis;
    int timeOn = 0;
    int timeOff = 0;

    //LED 1
    timeOn = 0;
    timeOff = 1500;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led1, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led1, LOW); //turn off event1 pin
    }

    //LED 2
    timeOn = 1200;
    timeOff = 2000;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led2, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led2, LOW); //turn off event1 pin
    }

    //LED 3
    timeOn = 1000;
    timeOff = 3000;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led3, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led3, LOW); //turn off event1 pin
    }

    //LED 4
    timeOn = 2500;
    timeOff = 6000;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led4, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led4, LOW); //turn off event1 pin
    }

    //LED 5
    timeOn = 3000;
    timeOff = 5500;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led5, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led5, LOW); //turn off event1 pin
    }

    //Longest off time, to re-enable the button
    timeOff = 6000;
    if (timePassed >= timeOff)
    {
      btnMillis = 0;
    }
  }
}

void btnDown()
{
  if (btnMillis != 0) return;
  btnMillis = millis(); //Set eventtime1 to now + 500ms
}

And a bigger version, this time with 8 leds turning on and off, plus 1 led on pwm fading up and down while the other 8 leds are turning on and off

#define buttonPin 2 //button attached to pin 2

#define led1 13
#define led2 12
#define led3 11
#define led4 10
#define led5 9
#define led6 8
#define led7 7
#define led8 6
#define fled 3 //Led on digital pin 3

unsigned long btnMillis = 0; //clock value to be stored at the time milli() is called

//Fade a led without delaying the rest of the code
//START
unsigned long fadeMillis = 0;
boolean fadeUp = true;
int fadeValue = 0;
void analogFade()
{
  if (millis() - fadeMillis >= 5)
  {
    fadeMillis = millis();
    
    if (fadeUp == true)
    {
      if (fadeValue < 255)
      {
        fadeValue++;
      }
      else
      {
        fadeUp = false;
        fadeValue--;
      }
    }
    else
    {
      if (fadeValue > 0)
      {
        fadeValue--;
      }
      else
      {
        fadeUp = true;
        fadeValue++;
      }
    }
    analogWrite(fled, fadeValue);
  }
}
//STOP

void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);

  attachInterrupt(0, btnDown, RISING); //0 = digital pin 2 or 1 = digital pin 3
}

void loop()
{
  analogFade();

  if (btnMillis != 0)
  {
    unsigned long timePassed = millis() - btnMillis;
    int timeOn = 0;
    int timeOff = 0;

    //LED 1
    timeOn = 0;
    timeOff = 1500;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led1, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led1, LOW); //turn off event1 pin
    }

    //LED 2
    timeOn = 1200;
    timeOff = 2000;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led2, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led2, LOW); //turn off event1 pin
    }

    //LED 3
    timeOn = 1000;
    timeOff = 3000;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led3, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led3, LOW); //turn off event1 pin
    }

    //LED 4
    timeOn = 2500;
    timeOff = 6000;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led4, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led4, LOW); //turn off event1 pin
    }

    //LED 5
    timeOn = 3000;
    timeOff = 5500;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led5, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led5, LOW); //turn off event1 pin
    }

    //LED 6
    timeOn = 2000;
    timeOff = 5500;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led6, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led6, LOW); //turn off event1 pin
    }

    //LED 7
    timeOn = 4000;
    timeOff = 5000;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led7, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led7, LOW); //turn off event1 pin
    }

    //LED 8
    timeOn = 1200;
    timeOff = 1500;

    if (timePassed >= timeOn && timePassed <= timeOn+50)
    {
      digitalWrite(led8, HIGH); //turn off event1 pin
    }

    if (timePassed >= timeOff && timePassed <= timeOff+50)
    {
      digitalWrite(led8, LOW); //turn off event1 pin
    }

    //Longest off time, to re-enable the button
    timeOff = 6000;
    if (timePassed >= timeOff)
    {
      btnMillis = 0;
    }
  }
}

void btnDown()
{
  if (btnMillis != 0) return;
  btnMillis = millis(); //Set eventtime1 to now + 500ms
}

um...uh...well..

Looks like I wasted my time creating the entire solution, or it was too easy to just copy and use...