Drop delay() for millis in lightning storm

Hi, I have some code that I adjusted slightly for a lightning storm. It works great as posted however its using delay() in 2 instances which I don't like as it ties up the processor. I tried very hard to switch delay for millis but can't get it working, can anyone help?

void lightningStorm()
{
  lightningStormStart=1;
  Serial.print("lightningStormStart ");
  Serial.print(lightningStormStart);
  Serial.print("\n");
  //Random lighting storm of bursts and flickers
  unsigned long now = millis();
  lightningtime = 120000;
  lightningtimer = now;

  if (now - lightningtimer < lightningtime)
  {
    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,120);//higher light lightning value
    mixer = random(burst,big);//random pick of short or long bursts of lightning
    dark = random(1000,10000);//random pick of time gap for lightning
    for(int i = 0; i < mixer; i += diming++)
    {
      diming = random(1,150);
      pwm.setPWM(0, 0, random(srumble,brumble));
      analogWrite(ledRedPin, random(srumble,brumble));//Turn on LED for short or long burst
      delay(diming);//random number delay to remain at set brightness value
    }
    digitalWrite(ledRedPin, LOW);    // turn the LED off
    delay(dark);
  }  
}

robsworld78:
Hi, I have some code that I adjusted slightly for a lightning storm. It works great as posted however its using delay() in 2 instances which I don't like as it ties up the processor. I tried very hard to switch delay for millis but can't get it working, can anyone help?

void lightningStorm()

{
 lightningStormStart=1;
 Serial.print("lightningStormStart ");
 Serial.print(lightningStormStart);
 Serial.print("\n");
 //Random lighting storm of bursts and flickers
 unsigned long now = millis();
 lightningtime = 120000;
 lightningtimer = now;

if (now - lightningtimer < lightningtime)
///////////That will always be true



millis() = now = lightningtimer
now - lightningtimer will be zero, give or take a millis or two.
Move all your timing initialisation to the start of your program.

or declare them local like this:

void lightningStorm()
{
  static unsigned long lightningtimer; // make sure you don't have it as a global variable if you use it this way
  lightningStormStart=1;
  Serial.println("lightningStormStart 1");//<<<<<<<<<<< one line instead of 3
  //Serial.print(lightningStormStart); // when will this not print a '1'???
  //Serial.print("\n"); // do you know about serial.println() ?
  if (millis() - lightningtimer < 120000UL)  // two minutes
  {
    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,120);//higher light lightning value
    mixer = random(burst,big);//random pick of short or long bursts of lightning
    dark = random(1000,10000);//random pick of time gap for lightning
    for(int i = 0; i < mixer; i += diming++)
    {
      diming = random(1,150);
      pwm.setPWM(0, 0, random(srumble,brumble));
      analogWrite(ledRedPin, random(srumble,brumble));//Turn on LED for short or long burst
      delay(diming);//random number delay to remain at set brightness value //<<<<<<<<<<<<<<< find a way 
    }
    digitalWrite(ledRedPin, LOW);    // turn the LED off
    delay(dark);//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< <<<<<<<<<<<<<<<<<<<<<<<<<<< to avoid these
    
  } 
  else
  {
    lightningtimer = millis() // <<<<<<<<<<<< very important to reset the timer
  }
}

Thanks, I was able to get it to work with your help and eliminated one of the delay()'s but can't lose the other. How would that work? Also having trouble adding a millis delay so the lightning storm only runs for a set amount of time and when it expires it sets lightningStormStart=0 Currently I have this located in the loop() section.

  if (lightningStormStart==1)
  {
    unsigned long currentMillis2 = millis();

    if(currentMillis2 - previousMillis > interval) 
    {
      interval = random(1000,20000); //random pick of time gap for lightning
      previousMillis = currentMillis2;   
      unsigned long previousMillis = millis();

      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,120);//higher light lightning value
      mixer = random(burst,big);//random pick of short or long bursts of lightning
      for(int i = 0; i < mixer; i += diming++)
      {
        diming = random(1,150);
        pwm.setPWM(0, 0, random(srumble,brumble)); //Turn on LED for short or long burst
        delay(diming);//random number delay to remain at set brightness value
      }
      currentMillis2 = 0;
    }
  }

I'm new to all this, doing good but have trouble with these loops. BulldogLowell not sure what you mean by "declare them local"? Do that mean I don't need this in the loop() section? That would be nice so that section stays small.

The idea of this is a button gets pressed in the GUI which sets lightningStormStart=1 and the lightning storm starts, this part works. Then it runs till a set time expires and sets lightningStormStart=0, still to be added.

For Serial.printIn I know nothing about it except its good for troubleshooting and used for retrieving data from sensors etc... I have no use for it except for telling me what variables are at certain sections of the code, very useful for seeing where things go wrong, its helped me countless times. I know it can be written better but I don't mind all the lines, makes me feel better because I wrote 3 lines of code instead of 1. :slight_smile:

I realize those delay()'s are bad and that's what I'm trying to eliminate, one down one to go. Any chance you can help me with that remaining delay()?

      for(int i = 0; i < mixer; i += diming++)
      {
        diming = random(1,150);
        pwm.setPWM(0, 0, random(srumble,brumble)); //Turn on LED for short or long burst
        delay(diming);//random number delay to remain at set brightness value
      }

However, you not only need to lose the "delay()", but you need to lose the for loop, so you'll need to explain what the for loop is doing.
It's quite difficult to figure out what that loop is doing, because the value of "diming" changes in the body of the loop.

It would be helpful for you to explain just what you want to do.

I did a PWM thunderbolt with fade-in/out on a weather station I did about 8 months back, if you want I can share how I did it... no delays.

Flashes of light on one led while the other led faded up and down. (clouds slowly fading up and down in blue and lightning flashing on top of that)

If you are interested, I can try to break out the old code and show you.

robsworld78:
l I know it can be written better but I don't mind all the lines, makes me feel better because I wrote 3 lines of code instead of 1. :slight_smile:

hmmm... do you get paid by the line?! :slight_smile:

if you work that way, your programs naturally become more complex and thus harder to debug (e.g. your example above) and difficult for others to understand.

keep things simple. I am always amazed when an experienced programmer boils 15 lines of my code down to three or four. Amazed and thankful to see the easier method!

I'll remove the for loop and see if it still works, I didn't write this so I don't know what the for loop does, I just assumed it was needed and haven't tried without it.

BulldogLowell if you could share your code that would be appreciated. I'm building an all in one aquarium controller, 80% complete, now I want to add cloud cover and lightning effects. There will be an option in the GUI to turn on or off random thunderstorms plus there will be a button on the home page which will start the storm when pressed.

I really like the lightning effects from the code I posted, I was going to save the variables to eeprom so user can change intensity, speed, duration through the GUI. When the storm starts I want the lights to fade to a certain point and when it finishes fade back to the current schedule. I'm using the adafruit 815 12-bit PWM board for the LED's.

I was joking about the 3 lines of code, I wish I got paid by the line if that was the case this would be double spaced. :slight_smile: I'm just doing this for fun, maybe some day I can make money coding. I do try to keep things as simple as possible but that can be hard when you don't really know what your doing. :slight_smile: