Random lighting

Hi I am adding random lighting to a model railroad building and want to have one pin flicker like a florescent light each time it comes on.
I'm using published code that works fine but have no idea how to achieve this extra effect.
Cheers and stay well. Bob

Secret published code? :slight_smile: Do you have a link, or? ...

It's impossible to write code to slot into code that can't be seen, but in the meantime fwiw here's a sketch that does a random number of flickers of random time when the led is turned on.

*** It's an ugly delay()-based version with a for() loop. ***

// https://forum.arduino.cc/index.php?topic=672221.0
// fluorescent light startup flicker
// a bit of an ugly delay()-based version
// random number of flickers, with random timing, when the light switch is closed
//     goes off when switch opened

/*
  BASED ON State change detection (edge detection) changed for INPUT PULLUP
               (button wired from pin to ground)
  https://www.arduino.cc/en/Tutorial/StateChangeDetection
*/

// this constant won't change:
const int  button = 2;
const byte led = 8;

// Variables will change:
bool buttonState;         // current state of the button
bool lastButtonState;     // previous state of the button

void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("fluorescent light startup flicker");
  pinMode(button, INPUT_PULLUP);

  //initialize button states
  buttonState = digitalRead(button);
  lastButtonState = buttonState;

  //turn bulitin led off
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  pinMode(led, OUTPUT);
  //digitalWrite(led, HIGH); delay(500); //test led
  digitalWrite(led, LOW);

  Serial.println(" ");
  Serial.println("setup() done... turn the light on");
  Serial.println(" ");
}

void loop()
{
  checkLightSwitch();
} //loop

void checkLightSwitch()
{
  // read the button:
  buttonState = digitalRead(button);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) // != means not equal, so it changed one way or the other
  {
    if (buttonState == LOW) //... and if it's now low, that's a press
    {
      //Serial.print("New press");
      doMagicStuff();
    }// change to low
    else
    {
      //Serial.println(", new release");
      digitalWrite(led, LOW);
    }//change to high

    // Delay a little bit to avoid bouncing
    delay(50);
  }//change
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;
}//check light switch

void doMagicStuff()
{
  byte howManyFlicks = random(2, 6);
  Serial.println(howManyFlicks);
  for (byte i = 0; i < howManyFlicks; i++)
  {
    digitalWrite(led, HIGH);
    delay(random(100, 200));
    digitalWrite(led, LOW);
    delay(random(100, 200));
  }
  digitalWrite(led, HIGH);
} //doMagicStuff

#define numleds 9
byte ledpins [ ] = { 2,3,4,5,6,7,8,9,10,11,12,13 } ;
void setup( ){
for ( int i=1; i <= numleds; i++ ) {
pinMode ( ledpins [ i ], OUTPUT) ;
digitalWrite ( ledpins [ i ] , HIGH) ;
}
pinMode (2,INPUT); // Pin 2 will be the control pin for this lighting group
digitalWrite (2,HIGH); //This turns the Pull up ON
}
void loop ( ) {

digitalWrite ( ledpins [ random ( 0, numleds+1 ) ], lightsw ( ) ) ;
delay ( 900 ) ;
}
boolean lightsw ( ) {
if (digitalRead(2) == LOW) return LOW; //If the group control pin is LOW ALL lights
// will eventually turn OFF
if ( random (0,100) > 40 ) return LOW ;
else return HIGH ;

Sorry here is the code Im using, what I need is for one led to flicker each time as it comes on

And is that the original published code that works as far as it's meant to, or is that light show stuff your (presumably unsuccessful) attempt to get the flickering working?

In other words, what the status of that code you posted? What does it (not-) do?

thats my attempt at adding a flicker to pin 13 (didnt work) the rest of the code is as published in model rail mag. and works as claimed.
cheers

May I suggest then please that you post the original as original, so it's clear what works :wink: ... If you stick the code in code tags it's easier to read.

You can either tag it manually

[code]sketch goes here [/code]

or use the icon:

(By the way I see in that code, pin2 is both an output in ledpins and an input for what you refer to as a "control pin".... can't be both...)

Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
http://forum.arduino.cc/index.php/topic,148850.0.html.
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom... :slight_smile:

You didn't post the code that works, so it's unclear exactly what you had before you added your code, or obviously what it did.

The code below is a delay()-less, millis()-based version of what I posted earlier, with leds in an array and an array of switches, one per led.

So if you throw any switch on (wire them to ground, input pullups are enabled) its led flickers before going solid on. If you have lots of free fingers you can throw any switches while any already switched are flickering, and they can all flicker happily together.

The leds cycle on/off in setup() as a test.

But since I don't know what your code currently does I can't advise on how to integrate my new code into what you have. But it's all in functions...

// https://forum.arduino.cc/index.php?topic=672221.0
// fluorescent light startup flicker
//    delay()-less millis()-based version
// random number of flickers, with random timing, when the light switch is closed
//     goes off when switch opened

/*
  BASED ON State change detection (edge detection) changed for INPUT PULLUP
               (button wired from pin to ground)
  https://www.arduino.cc/en/Tutorial/StateChangeDetection
*/

// this constant won't change, set these values before compile
const byte led[] = {2, 3, 4}; //pins
const byte howManyLeds = sizeof(led) / sizeof(led[0]); //leave this line alone
const int  button[howManyLeds] = {14, 15, 16}; //pins
const byte minFlicks = 2; //number
const byte maxFlicks = 6; //number
const byte minFlickTime = 50;  //millis
const byte maxFlickTime = 200; //millis

// Variables will change:
bool buttonState[howManyLeds];
bool lastButtonState[howManyLeds];
bool startUp[howManyLeds];
int flickerInterval[howManyLeds];
byte howManyFlicks[howManyLeds];
byte flickCounter[howManyLeds];
bool flickState[howManyLeds];
unsigned long previousFlick[howManyLeds];
byte currentLedToFlick = 0;

void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("fluorescent light startup flicker");
  for (byte i = 0; i < howManyLeds; i++)
  {
    pinMode(button[i], INPUT_PULLUP);
    //initialize button states
    buttonState[i] = digitalRead(button[i]);
    lastButtonState[i] = buttonState[i];
    startUp[i] = false;
    flickerInterval[i] = 0;
    howManyFlicks[i] = 0;
    flickCounter[i] = 0;
    flickState[i] = false;
    previousFlick[i] = 0;

    pinMode(led[i], OUTPUT);
    digitalWrite(led[i], HIGH); delay(500); //test each led
    digitalWrite(led[i], LOW);
  }
  //turn builtin led off
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  Serial.println(" ");
  Serial.println("setup() done... turn a light on");
  Serial.println(" ");
}

void loop()
{
  checkLightSwitches();
  doMagicStuff();
  currentLedToFlick++;
  if (currentLedToFlick == howManyLeds) currentLedToFlick = 0;
} //loop

void checkLightSwitches()
{
  //Serial.print("checking button "); Serial.println(currentLedToFlick);
  // read the button:
  buttonState[currentLedToFlick] = digitalRead(button[currentLedToFlick]);

  // compare the buttonState to its previous state
  if (buttonState[currentLedToFlick] != lastButtonState[currentLedToFlick]) // != means not equal, so it changed one way or the other
  {
    if (buttonState[currentLedToFlick] == LOW) //... and if it's now low, that's a press
    {
      startUp[currentLedToFlick] = true;
      howManyFlicks[currentLedToFlick] = random(minFlicks, maxFlicks);
      //Serial.print("Led "); Serial.print(currentLedToFlick); Serial.print(", Flicks "); Serial.println(howManyFlicks[currentLedToFlick]);
      flickCounter[currentLedToFlick] = 0;
    }// change to low

    // Delay a little bit to avoid bouncing
    delay(50);
  }//change
  // save the current state as the last state, for next time through the loop
  lastButtonState[currentLedToFlick] = buttonState[currentLedToFlick];

  //and if any switch is high (unpressed), nake sure it's off
  if (buttonState[currentLedToFlick]) digitalWrite(led[currentLedToFlick], LOW);
}//check light switches

void doMagicStuff()
{
  if (startUp[currentLedToFlick])
  {
    if (flickCounter[currentLedToFlick] < 2 * howManyFlicks[currentLedToFlick]) //twice thru per flick
    {
      if (millis() - previousFlick[currentLedToFlick] >= (unsigned long) flickerInterval[currentLedToFlick])
      {
        previousFlick[currentLedToFlick] = millis();
        //Serial.print(" ");
        //Serial.print(flickCounter);
        digitalWrite(led[currentLedToFlick], flickState[currentLedToFlick]);
        flickerInterval[currentLedToFlick] = random(minFlickTime, maxFlickTime);
        //Serial.print(" ");
        //Serial.println(flickerInterval);
        flickState[currentLedToFlick] = !flickState[currentLedToFlick];
        flickCounter[currentLedToFlick]++;
      }//time
    }//counter<
    else
    {
      digitalWrite(led[currentLedToFlick], HIGH);
      startUp[currentLedToFlick] = false;
    }//counter>
  }//startup
} //doMagicStuff

cheers I give up!!

dadt:
cheers I give up!!

Why?

My code does the kind of flicker I think you want on any led when it turns on, in this case with a switch, but it wasn't clear what causes your target led to be activated. If you had posted the original code before your edit, it would probably / possibly have been clear where and how to integrate my thinking into your requirement. My code might actually then have been a full solution, at least it would have been a starting point...

That code of mine may look complicated: it is I guess, and getting things to happen delay()-lessly so that they don't block other things from happening is a bit of a complicated task.

But it uses two basic Arduino building blocks, namely:

It's all about building blocks....

I took the view that I'd spend a bit of time making it delay()-less, with the leds and their associated buttons in arrays, so that it's scalable. All that needs to be done to change the number of leds and buttons is to adjust the pin numbers in these 2 lines:

const byte led[] = {2, 3, 4}; //pins
const int  button[howManyLeds] = {14, 15, 16}; //pins

Then adjust the realism here:

const byte minFlicks = 2; //number
const byte maxFlicks = 6; //number
const byte minFlickTime = 50;  //millis
const byte maxFlickTime = 200; //millis

If it's not a switch that turns your target led/s on, say so and let's see if we can integrate my thinking into whatever it is that does turns it/them on .

Or,

dadt:
give up!!