# millis help needed

totaly unable to understand millis yet need it as delay stops other code from running, Can some one show me how to use millis in this code Thanks

int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
long int time4 = 4500;
int buttonState1 = 49;
int ledlight;
int ran;
long previousMillis = 0;
long interval = 6000;

void setup()                      // run once, when the sketch starts
{
Serial.begin(9600);
pinMode (led1, OUTPUT); //led 1
pinMode (led2, OUTPUT); //led 2
pinMode (led3, OUTPUT); //led 3
pinMode (led4, OUTPUT); //led 4
pinMode (buttonState1, INPUT); //button
}

void loop()                       // run over and over again scan inputs then play them

{

unsigned long currentMillis = millis();

if (digitalRead(buttonState1) == HIGH) // start the leds turn on 1 led at random then after 4.5 seconds turn on next at random and repeat.

{
ran = random(1,5);
if (ran == 1)
{
digitalWrite (led1, HIGH);

}
if(currentMillis - previousMillis > time4)

digitalWrite (led1, LOW);
}
if (ran == 2)
{
digitalWrite (led2, HIGH);

}
if(currentMillis - previousMillis > time4)

digitalWrite (led2, LOW);

if (ran == 3)
{
digitalWrite (led3, HIGH);

}
if(currentMillis - previousMillis > time4)

digitalWrite (led3, LOW);

if (ran == 4)
{
digitalWrite (led4, HIGH);

if(currentMillis - previousMillis > time4)

digitalWrite (led4, LOW);
}
}

It looks to me that you are never populating previousMillis, so it will always have your initial value of 0.

Perhaps near the end of the loop you should insert the following statement

previousMillis = currentMillis;

Also, your decleration of previousMillis should be the same type as currentMillis. ie:

unsigned long previousMillis = 0;

There is more to simplifying your code, but these changes should get you started.

You should check how to use arrays - http://www.arduino.cc/en/Reference/Array - makes things more compact.

thanks fot the tips

but having changed the two things the leds no longer flash they did rapidly befor ignoring the delay

Ah - I think I have it

I assume you are executing this statement

previousMillis = currentMillis;

at the end of every loop?

If so, the difference is unlikely to ever reach the 45 seconds you are looking at. (4.5 seconds would be 4500 milliseconds, not 45000)

What you want to do is execute it only once the condition has been achieved, in effect resetting your timer.

Perhaps your code should look something like this. (Note. It may not do exactly as you wish due to various missing/unclear curly brackets in your original code)

int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
long int time4 = 45000;
int buttonState1 = 49;
int ledlight;
int ran;
long previousMillis = 0;
long interval = 6000;

void setup()                      // run once, when the sketch starts
{
Serial.begin(9600);
pinMode (led1, OUTPUT); //led 1
pinMode (led2, OUTPUT); //led 2
pinMode (led3, OUTPUT); //led 3
pinMode (led4, OUTPUT); //led 4
pinMode (buttonState1, INPUT); //button
}

void loop() {                      // run over and over again scan inputs then play them

unsigned long currentMillis = millis();

if (digitalRead(buttonState1) == HIGH) { // start the leds turn on 1 led at random then after 4.5 seconds turn on next at random and repeat.
ran = random(1,5);
if (ran == 1) {
digitalWrite (led1, HIGH);
}
else if (ran == 2) {
digitalWrite (led2, HIGH);
}
else if (ran == 3) {
digitalWrite (led3, HIGH);
}
else if (ran == 4) {
digitalWrite (led4, HIGH);
}

if(currentMillis - previousMillis > time4) {
digitalWrite (led1, LOW);
digitalWrite (led2, LOW);
digitalWrite (led3, LOW);
digitalWrite (led4, LOW);
previousMillis = cutrrentMillis; //reset timer
}
}

}

here it is again some comments to help. basicly this Iwould like to be a sub turning on the four leds for 4 seconds each in random i can get it to work with delay but that stops all othe loops. this just flashes the leds fast without the 4 second delay as if it cannot see the mills count if that makes sence

int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
long int time4 = 45000;
int buttonState1 = 49;
int ledlight;
int ran;
long previousMillis = 0;
long interval = 6000;

void setup()                      // run once, when the sketch starts
{
Serial.begin(9600);
pinMode (led1, OUTPUT); //led 1
pinMode (led2, OUTPUT); //led 2
pinMode (led3, OUTPUT); //led 3
pinMode (led4, OUTPUT); //led 4
pinMode (buttonState1, INPUT); //button
}

void loop() {                      // run over and over again scan inputs then play them

unsigned long currentMillis = millis();
ran = random(1,5);

/* hope to place this in a loop to run over and over for mabe four times then check the buttonstat1 as part of a bigger cycle*/

if (digitalRead(buttonState1) == HIGH) { // start the leds turn on 1 led at random then after 4.5 seconds turn on next at random and repeat.

if (ran == 1) {
digitalWrite (led1, HIGH);               //turn this led on when random 1
digitalWrite (led2, LOW);             //make sure all others are off
digitalWrite (led3, LOW);           //make sure all others are off
digitalWrite (led4, LOW);      //make sure all others are off
if(currentMillis - previousMillis > time4)             // has 4.5 seconds gone
digitalWrite (led1, LOW);                       // so turn it off then read random again
}
if (ran == 2) {
digitalWrite (led2, HIGH);              //turn this led on when random
digitalWrite (led1, LOW);              //make sure all others are off
digitalWrite (led3, LOW);          //make sure all others are off
digitalWrite (led4, LOW);            //make sure all others are off
if(currentMillis - previousMillis > time4)                      // has 4.5 seconds gone
digitalWrite (led2, LOW);                                  // so turn it off then read random again and so on to the next random
}
if (ran == 3) {
digitalWrite (led3, HIGH);
digitalWrite (led2, LOW);
digitalWrite (led1, LOW);
digitalWrite (led3, LOW);
digitalWrite (led4, LOW);
if(currentMillis - previousMillis > time4)
digitalWrite (led3, LOW);
}
if (ran == 4) {
digitalWrite (led4, HIGH);
digitalWrite (led2, LOW);
digitalWrite (led1, LOW);
digitalWrite (led3, LOW);
if(currentMillis - previousMillis > time4)
digitalWrite (led4, LOW);

}
// now reset for next 4 randoms

else digitalWrite (led2, LOW);
digitalWrite (led1, LOW);
digitalWrite (led3, LOW);
digitalWrite (led4, LOW);
previousMillis = currentMillis; //reset timer
}

}
if (ran == 1) {
digitalWrite (led1, HIGH);        //turn this led on when random 1
digitalWrite (led2, LOW);       //make sure all others are off
digitalWrite (led3, LOW);      //make sure all others are off
digitalWrite (led4, LOW);      //make sure all others are off
if(currentMillis - previousMillis > time4) // has 4.5 seconds gone
digitalWrite (led1, LOW);     // so turn it off then read random again

Think what happens if next time through "loop", your program picks a new value of "ran".

yes but that is ok for the random led it is the time on that does not make sense
as I say I can not get the millis in my head so failing to get it to stay on for 4 secs
Thanks

but that is ok for the random led it is the time on that does not make sense

No, it isn't alright.

"millis" just returns the number of milliseconds since the Arduino last reset - think of it like a telephone speaking clock service.

1: Do not mix logic. Mixing "which LED do I turn on," and "should I turn any LED off" is a big part of your problem. They are distinct issues, and should be treated distinctly - not only will this generate less code, it will also make it much easier to debug.

2: Avoid redundant code.

Imagine the following:

int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
long int time4 = 4500;
long previousMillis = 0;

...

boolean is_lit = false;
byte cur_led  = led1;

void loop() {

if( ! is_lit && digitalRead(buttonState1) == HIGH ) {

// no led is currently list

cur_led = random(1,4) + 1; // LEDs start at pin 2 and move sequentially to pin 5

digitalWrite(cur_led, HIGH);

previousMillis = millis();
is_lit = true;

}

else {

// an LED is lit currently.

if( millis() - previousMillis() >= time4 ) {
// enough time has passed to turn off the LEd
digitalWrite(cur_led, LOW);
is_lit = false;
}
}

}

Note here the logic is such:

If no LED is lit and button is pressed -> determine which LED to light up + light the LED + indicate time LED was started + indicate that LED is lit up If an LED is lit -> determine if enough time has passed to turn off the LED, if it has - turn it off an indicate that the LED is no longer on

Note that your previous code wouldn't turn off the LED if the button wasn't pressed.

!c

Thanks all
finaly sorted it got rid of the millis idear.
This is what I was trying to do

void speakrand() {

int i;
for (i = 0; i < 4; i++) {
Serial.print(i);
Serial.println("speak");
ran = random(1, 5);
if (ran == 1)
{
digitalWrite (SpeakOutA, HIGH);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutC, LOW);
digitalWrite (SpeakOutD, LOW);
}

if (ran == 2)
{
digitalWrite (SpeakOutB, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutD, LOW);
digitalWrite (SpeakOutC, LOW);
}

if (ran == 3)
{
digitalWrite (SpeakOutC, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutD, LOW);

}

if (ran == 4)
{
digitalWrite (SpeakOutD, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutC, LOW);

}
delay(time1);
}

You really need to work on that indentation.
If you type ctrl-t in the IDE, the IDE will attempt to correct it for you.

if (ran == 1)
{
}
if (ran == 2)
{
}
if (ran == 3)
{
}
if (ran == 4)
{
}
}

If ran is 1, can it be any other value? If it is 3, can it be any other value?

When the values are mutually exclusive, and not changed inside a block, if/else if/else is preferred, so that additional evaluations are not required.

void speakrand() {

int i;
for (i = 0; i < 4; i++) {
Serial.print(i);
Serial.println("speak");
ran = random(1, 5);
if (ran == 1)
{
digitalWrite (SpeakOutA, HIGH);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutC, LOW);
digitalWrite (SpeakOutD, LOW);
}

if (ran == 2)
{
digitalWrite (SpeakOutB, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutD, LOW);
digitalWrite (SpeakOutC, LOW);
}

if (ran == 3)
{
digitalWrite (SpeakOutC, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutD, LOW);

}

if (ran == 4)
{
digitalWrite (SpeakOutD, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutC, LOW);
}
delay(time1);
}
}

Then as PaulS said, these cases are mutually exclusive:

void speakrand() {

int i;
for (i = 0; i < 4; i++) {
Serial.print(i);
Serial.println("speak");
ran = random(1, 5);
if (ran == 1)
{
digitalWrite (SpeakOutA, HIGH);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutC, LOW);
digitalWrite (SpeakOutD, LOW);
}
else if (ran == 2)
{
digitalWrite (SpeakOutB, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutD, LOW);
digitalWrite (SpeakOutC, LOW);
}
else if (ran == 3)
{
digitalWrite (SpeakOutC, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutD, LOW);
}
else if (ran == 4)
{
digitalWrite (SpeakOutD, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutC, LOW);
break;
}
delay(time1);
}
}

In which case you may as well use “switch”:

void speakrand() {

int i;
for (i = 0; i < 4; i++) {
Serial.print(i);
Serial.println("speak");
switch (random (1, 5))
{
case 1:
digitalWrite (SpeakOutA, HIGH);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutC, LOW);
digitalWrite (SpeakOutD, LOW);
break;

case 2:
digitalWrite (SpeakOutB, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutD, LOW);
digitalWrite (SpeakOutC, LOW);
break;

case 3:
digitalWrite (SpeakOutC, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutD, LOW);
break;

case 4:
digitalWrite (SpeakOutD, HIGH);
digitalWrite (SpeakOutA, LOW);
digitalWrite (SpeakOutB, LOW);
digitalWrite (SpeakOutC, LOW);
}
}  // end of switch
delay(time1);
}  // end of speakrand

By the way, you aren’t doing anything for 5, you know that, right?

Hi

...
void loop() {                      // run over and over again scan inputs then play them

.....

You are seeding each time you loop. This is not a good idea.

Nick,

By the way, you aren't doing anything for 5, you know that, right?

The 5 in

ran = random(1, 5);

is excluded.

Parameters min - lower bound of the random value, inclusive (optional)

max - upper bound of the random value, exclusive

-Fletcher

hello.. Using millis is very important and you will need it somewhere again, clear your concept about it, why you got irritated with it, its just the time in milli-seconds since last time reset, and it can work uptill 9 hours after that it gets zero again and start counting time again. You have no problem in using milli's, basically you have problem of programming, so correct that and don't get irritated with milli's because it will help you alot in future programs of arduino.

[quote author=Saad Khalil link=topic=69543.msg519278#msg519278 date=1313952170] hello.. Using millis is very important and you will need it somewhere again, clear your concept about it, why you got irritated with it, its just the time in milli-seconds since last time reset, and it can work uptill 9 hours after that it gets zero again and start counting time again. You have no problem in using milli's, basically you have problem of programming, so correct that and don't get irritated with milli's because it will help you alot in future programs of arduino. [/quote]

9 hours?

From the reference:

Returns the number of milliseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.

Hello.. Yes on website it is written 50 days but i think its wrong, but you go to this http://arduino.cc/playground/Main/ManualsAndCurriculum and download its reference book i-e Arduino-Refernce.pdf book, in which it is written that it resets after 9 hours, and i think that 9 hours are correct because i don't think that it will be storing in a variable which can store the value of milli-seconds of 50 days.

[quote author=Saad Khalil link=topic=69543.msg519301#msg519301 date=1313954264] Hello.. Yes on website it is written 50 days but i think its wrong, but you go to this http://arduino.cc/playground/Main/ManualsAndCurriculum and download its reference book i-e Arduino-Refernce.pdf book, in which it is written that it resets after 9 hours, and i think that 9 hours are correct because i don't think that it will be storing in a variable which can store the value of milli-seconds of 50 days. [/quote]

Prove it to yourself. unsigned long is a 32 bit value, how many millisecond can be held in a 32 bit value? The reference document you site is dated from 2008, millis has been updated sense then.

Hint:

Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes). Unlike standard longs unsigned longs won't store negative numbers, making their range from 0 to 4,294,967,295 (2^32 - 1).

Lefty