Trouble getting an LED to stay on for a random time period, Photon

As part of a home laminar water fountain jet project, I’m trying to make an LED stay on for a random amount of time before cycling off. With the following code, I get a new random number at startup but then it doesn’t change until the next startup. I keep moving the random number generator to different parts of the code but I can’t get it to work properly. Once I see that the random number generator is working correctly, I’ll replace my current millis delay with the random number (as noted under “void doStuff”). Can someone point me in the right direction? Thanks.



const pin_t LED_PIN = D7;

const pin_t SENSOR_PIN = A2;

int analogvalue;

int LEDflash = random(10);

unsigned long printMillis;
unsigned long printDelay = 1000;
unsigned long previousPrint = 0;

unsigned long doStuffMillis;
unsigned long doStuffDelay = 2000;
unsigned long previousStuffMillis = 0;

unsigned long lightThreshold = 2;

bool dark = false;

int ledState = LOW;

void setup() {

  pinMode(LED_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
  digitalWrite(LED_PIN, LOW);

  Serial.begin(9600);

}


void lightSensor() {

  analogvalue = analogRead(SENSOR_PIN);

  if (analogvalue > lightThreshold) {
    dark = false;
  }
  else {
    dark = true;
  }

}

void printStuff() {

  printMillis = millis();

  if (printMillis - previousPrint > printDelay) {

    if (dark == false) {
      Serial.println(analogvalue);
      Serial.println("LIGHT");
    }

    else {
      Serial.println(analogvalue);
      Serial.println("DARK");
      Serial.print("Random Number =  ");
      Serial.println(LEDflash);
    }

    previousPrint = printMillis;

  }
}

void doStuff() {


  if (dark == false) {

    digitalWrite(LED_PIN, LOW);

  }

  if (dark == true) {

    doStuffMillis = millis();

    if (doStuffMillis - previousStuffMillis > 3000) { // replace the 3000 with LEDflash once I figure it out

      previousStuffMillis = doStuffMillis;

      if (ledState == LOW) {
        ledState = HIGH;
      }

      else {
        ledState = LOW;

      }

    }

    digitalWrite(LED_PIN, ledState);

    long LEDflash = random (10);

  }
}

void loop() {

  lightSensor();
  printStuff();
  doStuff();

}

Once I can make it generate a new random number each time it blinks, the line in the code will look like this:

    if (doStuffMillis - previousStuffMillis > LEDflash * 1000)

You have two variables LEDflash - a global one which you only set once and a local one which you set again and again but as soon as you set it, it will vanish into thin air as you leave the function.

You should define your global variable as uint32_t LEDflash = random(10); and then later in your code only write LEDflash = random(10); in order to reuse the global version instead of declaring a local one.

Alternatively, if you need LEDflash only in doStuff() then you could drop the global variable and move the declaration into the function like this

void doStuff() {
  static uint32_t LEDflash = random(10);
  ...
      LEDflash = random(10);
}

A static local variable is only known to that function but will keep its value across individual calls to that function.

BTW, I would place the resetting of LEDflash at the same place as you have the previousStuffMillis = doStuffMillis so that you'll not change the time over and over again while dark == true.
You can also replace your if (ledState == LOW) ... block with a simple ledState = !ledState; to toggle the flag.
And finally, that is personal preference, I find if(dark) more natural to read than if (dark == true) (and respectively if (!dark) - read as "if not dark").

2 Likes

Thanks, once again, ScruffR! I made the changes as you suggested, keeping the global variable so that I could continue to print the random number and use that to adjust the LED = HIGH period to something that looks visually appealing. Thanks, also, for the additional coding suggestions. Since I infrequently code, those types of suggestions are helpful. My final code:

const pin_t LED_PIN = D7;

const pin_t SENSOR_PIN = A2;

int analogvalue;

uint32_t LEDflash = random(3, 15);

unsigned long printMillis;
unsigned long printDelay = 1000;
unsigned long previousPrint = 0;

unsigned long doStuffMillis;
unsigned long doStuffDelay = 2000;
unsigned long previousStuffMillis = 0;

unsigned long lightThreshold = 2;

bool dark = false;

int ledState = LOW;

void setup() {

  pinMode(LED_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
  digitalWrite(LED_PIN, LOW);

  Serial.begin(9600);

}


void lightSensor() {

  analogvalue = analogRead(SENSOR_PIN);

  if (analogvalue > lightThreshold) {
    dark = false;
  }
  else {
    dark = true;
  }

}

void printStuff() {

  printMillis = millis();

  if (printMillis - previousPrint > printDelay) {

    if (dark == false) {
      Serial.println(analogvalue);
      Serial.println("LIGHT");
    }

    else {
      Serial.println(analogvalue);
      Serial.println("DARK");
      Serial.print("Random Number =  ");
      Serial.println(LEDflash);
    }

    previousPrint = printMillis;

  }
}

void doStuff() {

  if (!dark) {

    digitalWrite(LED_PIN, LOW);

  }

  if (dark) {

    doStuffMillis = millis();

    if (doStuffMillis - previousStuffMillis > LEDflash * 200) {

      previousStuffMillis = doStuffMillis;

      LEDflash = random(3, 15);

      if (ledState = !ledState) {
        ledState = HIGH;
      }

      else {
        ledState = LOW;

      }

    }

    digitalWrite(LED_PIN, ledState);

  }
}

void loop() {

  lightSensor();
  printStuff();
  doStuff();

}

As an interesting side note, I fed my previous code into openai.com (chatGPT) and spent about 1/2 hour going back-and-forth with it and it couldn’t figure out how to fix the code. It kept repeating itself with the same suggestions and, finally, it said the problem must be in my wiring or some other part of the code! So, you - and mankind - should feel good that humans are smarter than an AI system (at least for this one problem at this particular point in time!)

Also, thanks for your help about 4 years ago on some programming questions I had for a Argon/Xenon project I was working on at the time. The device has worked non-stop since that time with zero issues!

3 Likes

Glad to hear that and happy to help! :+1:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.