Time limit on for(int loop

see below

Dear god, not the nested for loops…

You need an extra condition in your for loop to check if it’s been 10 minutes since you started.

The first thing to do, it is set a variable to hold the time you started:

unsigned long started = millis();

Then you need to update your for loop’s condition to check if it’s been less than the interval:

for (initialStuff; ( (condition1) && (millis() - started <= someInterval)) ; incrementStuff)

That will tell the for loop to continue while both condition 1 is true, and it’s been less than the someInterval value.

This passes without errors. Is it right?

I int started; and then this code.

unsigned long started = millis();
  for(int i = 0; ((i < mixer) && (millis() - started <=600000));i += diming++)

Ok my head is hurting again. I don’t hink the last code I posted works right but theres another issue as well. Not only do I need the for loop to repeat itself for the random value of time “i < mixer”, but after that value is reached (anywhere from .1-4 seconds) I need it to delay for a random of 1-12 seconds… THEN
I need it to repeat itself with a brand new “mixer” value. Then I need it to continue this rotation for 10 mins total and then end. I think I’m in my deep end here. I’ve tried googling with all the functions I’m trying to use with no luck. Any advise?

The sketch below runs the function I’m looking to inject into another sketch. Since its on its own all alone in this sketch the delay works fine since the whole sketch turns over after the delay. But if I insert it into another script I need to limit its max run time to 10 mins, have the random delay at the end, and repeat with all new random values.

This is at a point that I would pay 5.00 per post if not more for help. I don’t want someone to write this for me since I really enjoy everything I’ve learned from this community and about writing this sketch. But I’m up crap creek without a padle on this one. Please… PLEASE advise, even if its the smallest amount of advice or a post. Even a google keyword at this point. I’m willing to put in the time and effort. Just lost… O so lost.

int led = 11;
int burst; //short burst of light
int big;
int srumble;
int brumble;
int mixer;
int diming;
int delaymix;
int dark;

void setup() {                
 
  pinMode(led, OUTPUT);     
}


void loop() {
  burst = random(10,500); //Short burst of lightning value
  big = random(1000,4000);//long burst of lightning value
  srumble = random(10,40);//lower light lighting value
  brumble = random(10,255);//higher light lightning value
  mixer = random(burst,big);//random pick of short or long bursts of lightning
  dark = random(1000,12000);
 

  for(int i = 0; i < mixer; i += diming++)
  {
  diming = random(10,100);
  analogWrite(led, random(srumble,brumble));//Turn on LED for short or long burst
  delay(diming);//random number delay to remain at set brightness value
}
  digitalWrite(led, LOW);    // turn the LED off
delay(dark);
}

Could you use the blink without delay example with an interval generated with the random function?

http://arduino.cc/en/Tutorial/BlinkWithoutDelay

http://arduino.cc/en/Reference/RandomSeed

http://arduino.cc/en/Reference/Random

I think the best thing to do is to re-implement without the use of delays and for loops. First step is to setup the timer in the global scope:

unsigned long lastCycleTime = 0;
int mixer = 0;

This will be used to check when it's been at least mixer time. When it has, we can set our do nothingflag which will allow us to wait the random 1-12 seconds before we reset our random values and continue. The flag is set in the global scope:

int doNothingFlag = 0;

In our loop body, we are constantly checking the timer. If we are doing something (doNothingFlag is 0) and it's been greater than our mixer time, then we set our do nothing flag to 1 and generate a random time to do nothing for:

unsigned long now = millis();
if ( (doNothingFlag == 0) && (now - lastCycleTime > mixer) ) {
  doNothingFlag = 1;
  lastCycleTime = now;
  doNothingTime = rand(1000, 120000);
}

Now we just need to check if doNothingFlag is set, and it's been at least doNothingTime. If both conditions are true, we can generate new random values:

if ( (doNothing == 1) && (now - lastCycleTime > doNothingTime) ) {
  doNothingFlag = 0;
  lastCycleTime = now;
  // generate new random values
}

Last step is to actually do the actual analogWrites. This almost the exact same thing as the Blink Without Delay code, except that we also change the interval to a random time:

if ( (doNothing == 0) && (now - lastCycleTime > interval) ) {
  // analogWrite stuff
  // generate a random value and set it to the interval
}

The 10 minutes part is pretty easy too, when you understand how to use millis() and the concept of state variables.

Thank you. This are all commands I have yet to use so this will knock a large block out of my learning. I'm sure once I understand them I'll be even more excited about what I can do. I'll do my best to keep questions to the minimum.

Ok so after punching in all the code, clearing errors and reading it over a few times its starting to make since. This is going to be an amazingly useful function. I haven’t added the rest of my loop but I can tell now that it will work fine once I get this nailed. So heres my lightning sketch thanks to Arrch and copiertalk. If you have time, please check.

unsigned long lastCycleTime;
int mixer = 0;
int doNothingFlag;
int led = 11;
int burst; //short burst of light
int big;
int srumble;
int brumble;
int diming;
int delaymix;
int doNothingTime;



void setup() {                
 
  pinMode(led, OUTPUT);     
}

void loop() {
lastCycleTime = 0;
int doNothingFlag = 0;
unsigned long now = millis();

if ( (doNothingFlag == 0) && (now - lastCycleTime > mixer) )
{
  doNothingFlag = 1;
  lastCycleTime = now;
  doNothingTime = random(1000,12000);
  
}
if ( (doNothingFlag == 1) && (now - lastCycleTime > doNothingTime))
{
  doNothingFlag = 0;
  lastCycleTime = now;
  burst = random(10,500); //Short burst of lightning value
  big = random(1000,4000);//long burst of lightning value
  srumble = random(10,40);//lower light lighting value
  brumble = random(10,255);//
  mixer = random(burst,big);//random pick of short or long bursts of lightning
}
  if ( (doNothingFlag == 0) && (now - lastCycleTime < mixer))
  {
    diming = random(10,100);
  analogWrite(led, random(srumble,brumble));//Turn on LED for short or long burst
  delay(diming);//random number
  }}
  if ( (doNothingFlag == 0) && (now - lastCycleTime < mixer))
  {
    diming = random(10,100);
  analogWrite(led, random(srumble,brumble));//Turn on LED for short or long burst
  delay(diming);//random number
  }}

This can be done without the delay if you change the second condition to check if it’s been at least diming time since it was last run.

int doNothingFlag;

This variable only takes on two values - 0 or 1. Making it a boolean, instead, would make your code much more readable.

int doNothingFlag = 0;

Of course, doing so will really screw things up when you have a local variable of the same name and different type. Local and global variables of the same name are rarely a good idea.

if ( (doNothingFlag == 0) && (now - lastCycleTime > mixer) )
{
  doNothingFlag = 1;

would become:

if ( doNothingFlag && (now - lastCycleTime > mixer) )
{
  doNothingFlag = false;
  analogWrite(led, random(srumble,brumble));//Turn on LED for short or long burst

It is possible for brumble to have a value of 15, for example, while srumble has a value of 35, for example. This will cause random() to have issues, since there could be no valid value for it to return. How it deals with that, I do not know, but it is unlikely that analogWrite() will like that value as input.

  }}

There are coding styles that call for the { on the same line as the statement that it goes with, and there are styles that call for it on a new line. There are no styles that allow multiple } on the same line.

PaulS: int doNothingFlag;

  analogWrite(led, random(srumble,brumble));//Turn on LED for short or long burst

It is possible for brumble to have a value of 15, for example, while srumble has a value of 35, for example. This will cause random() to have issues, since there could be no valid value for it to return. How it deals with that, I do not know, but it is unlikely that analogWrite() will like that value as input.

I had this code running already with everuthing hooked up and it worked really well. Just an FYI. I will look at the other stuff and try them out tonight when I get home.

Arrch:

  if ( (doNothingFlag == 0) && (now - lastCycleTime < mixer))

{
    diming = random(10,100);
  analogWrite(led, random(srumble,brumble));//Turn on LED for short or long burst
  delay(diming);//random number
  }}



This can be done without the delay if you change the second condition to check if it's been at least diming time since it was last run.

That delay is to set the length of time between voltage changes to the light inside a lightning strike I don’t want it to effect the time limit on the loop. If I put it in the second line won’t it stop the loop after the value is surpassed?

mcreefer: That delay is to set the length of time between voltage changes to the light inside a lightning strike I don't want it to effect the time limit on the loop. If I put it in the second line won't it stop the loop after the value is surpassed?

You just need another unsigned long to keep track of the last time the analog value changed:

if ( (doNothingFlag == 0) && (now - lastLightChange > interval)) {
  lightLightChange = now;
  // set interval to some random
  // analogwrite stuff
}

PaulS: int doNothingFlag;

This variable only takes on two values - 0 or 1. Making it a boolean, instead, would make your code much more readable.

int doNothingFlag = 0;

Of course, doing so will really screw things up when you have a local variable of the same name and different type. Local and global variables of the same name are rarely a good idea.

if ( (doNothingFlag == 0) && (now - lastCycleTime > mixer) )
{
  doNothingFlag = 1;

would become:

if ( doNothingFlag && (now - lastCycleTime > mixer) )
{
  doNothingFlag = false;

So its like changing the 0&1's to true or flase. And if I go this route I'm not using a 0 or 1 command, I'm using any word I want with a true and false "value". Is that correct?