Go Down

Topic: How can I make LED's blink at random? (Read 1 time) previous topic - next topic

morgan1

Hi Everyone,

I am new to arduino and to programming in general. I want to connect a series of Leds (8) to my arduino board and make them all blink at random. Here is my very first piece of code XD. I was wondering wether I was going the right way (sorry it's probably very basic).

void setup() { 
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
 
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);

}

void loop() {
  digitalWrite(1, HIGH);
  delay(3000);
  digitalWrite(1, LOW);
  delay(3000);
  digitalWrite(2, HIGH);
  delay(4000);
  digitalWrite(2, LOW);
  delay(4000);
  digitalWrite(3, HIGH);
  delay(3500);
  digitalWrite(3, LOW);
  delay(3500);
  digitalWrite(4, HIGH);
  delay(1200);
  digitalWrite(4, LOW);
  delay(1200);

  digitalWrite(5, HIGH);
  delay(2000);
  digitalWrite(5, LOW);
  delay(2000);
  digitalWrite(6, HIGH);
  delay(2000);
  digitalWrite(6, LOW);
  delay(2000);
  digitalWrite(7, HIGH);
  delay(1000);
  digitalWrite(7, LOW);
  delay(1000);
  digitalWrite(8, HIGH);
  delay(3000);
  digitalWrite(8, LOW);
  delay(3000);   
}

floresta

Quote
... and make them all blink at random

Do they truly have to blink at random or do they just have to appear to blink at random such as 'twinkling' holiday decorations.

Also - I don't think you want to use delay().  Look for 'Blink without delay' whose more correct name should really be 'Blink without delay()'.

Don

CrossRoads

#2
Nov 20, 2011, 05:55 am Last Edit: Nov 20, 2011, 05:47 pm by CrossRoads Reason: 1
So you have 8 LEDs.

Use Blink without delay and an  array with random() for the on/off times.
We'll use 3 arrays.
1 will have 8 values for the on/off time amounts
1 will have the 8 I/O pins being used
1 will have the state of the I/O pin
Code: [Select]

int ledArrayTime[8]; // 8 element array of 16 bit numbers, load it up in setup
byte ledArray[8];  // array for the I/O pins
byte ledArray[] = {2,3,4,5,6,7,8,9};   // use 2-9 vs 1-8, keep 0/1 free for downloading sketches
// thus  ledArray[0] = I/O pin 2, up to ledArray[7] = pin 9
byte ledState[8]; // array to hold the state of the I/O pins
ledState[] = {0,1,0,1,0,1,0,1};  // load the the states with 0,1 to start (or all 0,s, or all 1's)
byte x;  // will use this as the array index pointer

void setup (){
// declare the outputs using the array
for (x=0; x<8; x=x+1){ // walk x from 0 to 7
pinMode (ledArray[x], OUTPUT);
digitalWrite (ledArray[x], ledArrayState[x]); // write the outputs hi/lo
}
// and load up the array with variable times
for (x= 0; x<8; x=x+1;){  loop from 0 to 7 to load the array
// find a random number from 1200 to 4000
randNumber = random(1200, 4000);  //[edit - original post had 400 here, a typo]
// load the array
ledArrayTime[x] = randNumber;
}
} // end setup

void loop(){

//now turn the lights on/off based the times in the array
// here's the blink without delay part
unsigned long startTime = millis(); // capture the current time
for (x=0; x<8; x=x+1;){
if ( (millis() - startTime) > ledArrayTime[x] ){
ledState[x] = 1-ledState[x];  // this should toggle the bit.
// if the value at ledState[5] for example was 1, then the new value will be 1-1 = 0,  and if 0, then 1-0 = 1
digitalWrite (ledArray[x], ledState[x]);  // turn the led on or off
} // end if time passed
} // end 0-7 loop
} // end void loop

Now, if all that works, can add additional code to change the delay times every once in a while
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.


floresta

#4
Nov 20, 2011, 04:22 pm Last Edit: Nov 20, 2011, 04:26 pm by floresta Reason: 1
You didn't answer my question.  You may be making this a lot more complicated than it has to be.

Don

CrossRoads

Yes, may be over complicated, but I enjoyed writing it up as a mental exercise in using arrays to control the state of 8 outputs.

Now that I tried compiling it, I found a few name mismatches, some extra ;s in the for (x ...) statements,
undeclared randNumber variable, and a couple of missing  //s.
Not too bad!
Code: [Select]

int ledArrayTime[8]; // 8 element array of 16 bit numbers, load it up in setup
byte ledArray[8] = {2,3,4,5,6,7,8,9};   // use 2-9 vs 1-8, keep 0/1 free for downloading sketches
// thus  ledArray[0] = I/O pin 2, up to ledArray[7] = pin 9
byte ledArrayState[8] = {0,1,0,1,0,1,0,1};  // load the the states with 0,1 to start (or all 0,s, or all 1's)
byte x;  // will use this as the array index pointer
int randNumber;

void setup (){
  // declare the outputs using the array
  for (x=0; x<8; x=x+1){ // walk x from 0 to 7
    pinMode (ledArray[x], OUTPUT);
    digitalWrite (ledArray[x], ledArrayState[x]); // write the outputs hi/lo
  }
  // and load up the array with variable times
  for (x= 0; x<8; x=x+1){  //loop from 0 to 7 to load the array
      // find a random number from 1200 to 4000
    randNumber = random(1200, 4000);  //[edit - original post had 400 here, a typo]
    // load the array
    ledArrayTime[x] = randNumber;
  }
} // end setup

void loop(){

  //now turn the lights on/off based the times in the array
  // here's the blink without delay part
  unsigned long startTime = millis(); // capture the current time
  for (x=0; x<8; x=x+1){
    if ( (millis() - startTime) > ledArrayTime[x] ){
      ledArrayState[x] = 1-ledArrayState[x];  // this should toggle the bit.
      // if the value at ledState[5] for example was 1, then the new value will be 1-1 = 0,  and if 0, then 1-0 = 1
      digitalWrite (ledArray[x], ledArrayState[x]);  // turn the led on or off
    } // end if time passed
  } // end 0-7 loop
} // end void loop


Morgan1, let me know how it works out please.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Grumpy_Mike

I just finished a tutorial page that might help you sort out using arrays to address pins.
http://www.thebox.myzen.co.uk/Tutorial/Arrays.html

Erni

#7
Nov 21, 2011, 03:45 pm Last Edit: Nov 21, 2011, 03:50 pm by Erni Reason: 1
@ CrossRoads

It workes beatyfull, allthoug i had to make a small change in the delay routine.

Furthermore I changed the random number range, but that is because I tried the Sketch, on my new attiny2313 at 1Mhz


Code: [Select]

int ledArrayTime[8]; // 8 element array of 16 bit numbers, load it up in setup
byte ledArray[8] = {9,11,12,13,4,5,6,7};   // use 2-9 vs 1-8, keep 0/1 free for downloading sketches
// thus  ledArray[0] = I/O pin 2, up to ledArray[7] = pin 9
byte ledArrayState[8] = {0,1,0,1,0,1,0,1};  // load the the states with 0,1 to start (or all 0,s, or all 1's)
byte x;  // will use this as the array index pointer
int randNumber;


void setup (){
  // declare the outputs using the array
  for (x=0; x<8; x=x+1){ // walk x from 0 to 7
    pinMode (ledArray[x], OUTPUT);
    digitalWrite (ledArray[x], ledArrayState[x]); // write the outputs hi/lo
  }
  // and load up the array with variable times
  for (x= 0; x<8; x=x+1){  //loop from 0 to 7 to load the array
      // find a random number from 1200 to 4000
    randNumber = random(120, 400);  //[edit - original post had 400 here, a typo]
    // load the array
   ledArrayTime[x] = randNumber;
}
} // end setup

void loop(){

  for (x=0; x<8; x=x+1){

   //delay
    unsigned long startTime = millis(); // capture the current time
    while ( (millis()- startTime) < ledArrayTime[x] ){
     } // end while time passed

     ledArrayState[x] = 1-ledArrayState[x];  // this should toggle the bit.
      // if the value at ledState[5] for example was 1, then the new value will be 1-1 = 0,  and if 0, then 1-0 = 1
      digitalWrite (ledArray[x], ledArrayState[x]);  // turn the led on or off

 
  } // end 0-7 loop
} // end void loop

This is a great sketch,

How easy would it be for these LEDs to fade on and off instead of blink?

thanks.

Phil

CrossRoads

Well, you would need to change things a bit to use the 6 PWM pins on a '328 Arduino, or fake PWM in software.
I'd have to think about that tonight.
For example, if you hit the start time, start a for:next loop that went from 0-255 & analogWrite pin to fade up, and then 255-0 to fade down at the end time.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

jaredpi

#10
Dec 13, 2011, 03:45 am Last Edit: Dec 13, 2011, 04:15 am by CrossRoads Reason: 1
Code: [Select]
[code]void setup() {
 pinMode(1, OUTPUT);
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);

 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);

}

void loop() {
 digitalWrite(1, HIGH);
 delay(3000);
 digitalWrite(1, LOW);
 delay(3000);
 digitalWrite(2, HIGH);
 delay(4000);
 digitalWrite(2, LOW);
 delay(4000);
 digitalWrite(3, HIGH);
 delay(3500);
 digitalWrite(3, LOW);
 delay(3500);
 digitalWrite(4, HIGH);
 delay(1200);
 digitalWrite(4, LOW);
 delay(1200);

 digitalWrite(5, HIGH);
 delay(2000);
 digitalWrite(5, LOW);
 delay(2000);
 digitalWrite(6, HIGH);
 delay(2000);
 digitalWrite(6, LOW);
 delay(2000);
 digitalWrite(7, HIGH);
 delay(1000);
 digitalWrite(7, LOW);
 delay(1000);
 digitalWrite(8, HIGH);
 delay(3000);
 digitalWrite(8, LOW);
 delay(3000);  
}

Here is some code to make this easier;
Code: [Select]
void setup() {

 Serial.begin(9600);

     for (int thisPin = 2; thisPin < 7; thisPin++) {
       pinMode(thisPin, OUTPUT);
     }
}

void loop() {

 if (Serial.available() > 0) {
   int inByte = Serial.read();
 
   switch (inByte) {
   case 'q':    
     digitalWrite(2, HIGH);
     delay(1000);
     break;
   case 'w':    
     digitalWrite(3, HIGH);
      delay(1000);
     break;
   case 'e':    
     digitalWrite(4, HIGH);
      delay(1000);
     break;
   case 'r':    
     digitalWrite(5, HIGH);
      delay(1000);
     break;
   case 't':    
     digitalWrite(6, HIGH);
      delay(1000);
     break;
     case 'a':    
     digitalWrite(2, HIGH);
     delay(500);
     break;
   case 's':    
     digitalWrite(3, HIGH);
      delay(500);
     break;
   case 'd':    
     digitalWrite(4, HIGH);
      delay(500);
     break;
   case 'f':    
     digitalWrite(5, HIGH);
      delay(500);
     break;
   case 'g':    
     digitalWrite(6, HIGH);
      delay(500);
     break;
      case 'z':    
     digitalWrite(2, HIGH);
     delay(250);
     break;
   case 'x':    
     digitalWrite(3, HIGH);
      delay(250);
     break;
   case 'c':    
     digitalWrite(4, HIGH);
      delay(250);
     break;
   case 'v':    
     digitalWrite(5, HIGH);
      delay(250);
     break;
   case 'b':    
     digitalWrite(6, HIGH);
      delay(250);
     break;
   default:

     for (int thisPin = 2; thisPin < 7; thisPin++) {
       digitalWrite(thisPin, LOW);
     }
   }
 }
}

I just randomly type letters and it creates random blinking LED's.
The disadvantage is that it only works once before it has to be re-uploaded.
Hope this helps.  [/code]

KirAsh4

Try this.  I found a video of a Lilypad doing PWM on all its pins one time and asked the author how he did it and this is what I got.  it does work, and will work on a regular Uno as well, basically any 328P IC.  Just specify your first and last pins to fade:
Code: [Select]
// Fade all IO by Osamu Iwasaki
// November 10, 2010

#include <MsTimer2.h>

#define OUT_MIN 0  // First pin
#define OUT_MAX 19  // Last pin (this includes the analog pins)

byte luminance[20];
byte lumi[20] = {};

void setup()
{
int i;

for(i = OUT_MIN; i <= OUT_MAX; i++){
  pinMode(i, OUTPUT);
  digitalWrite(i,LOW);
}


for(i = OUT_MIN; i <= OUT_MAX; i++){
  digitalWrite(i,HIGH);
  delay(150);
}
for(i = OUT_MIN; i <= OUT_MAX; i++){
  digitalWrite(i,LOW);
  //delay(50);
}
delay(1000);

MsTimer2::set(1, int_pwm);
MsTimer2::start();
}


void int_pwm() {

static int f_wait[20];
static int f_max_time[20];
static int f_speed[20];
static int f_ct[20];
static long f_interval[20];

static int ch;

for(ch = OUT_MIN; ch <= OUT_MAX; ch++){
  if(f_wait[ch] == 0){
    f_wait[ch] = f_speed[ch] + 1;

    if( (f_ct[ch] < 255) )
      if(luminance[ch] != 255)
        luminance[ch] ++;

    if(f_ct[ch] == 255){
      if(f_max_time[ch] == 0)
        f_max_time[ch] = 0; // On Max Time
      else
        f_max_time[ch] --;
    }

    if( (f_ct[ch] > 255) && (f_ct[ch] < 511) && (f_max_time[ch] == 0))
      if(luminance[ch] != 0)
        luminance[ch] --;

    if(f_ct[ch] >= 511){
      if(f_interval[ch] == 0){
        f_interval[ch] = 10 * random(100); // fading seed
        f_speed[ch] = random(1); // fading speed
        f_ct[ch] = 0;
      }
      else
        f_interval[ch] --;
    }
    else
      f_ct[ch] ++;
  }
  f_wait[ch] --;
}
}

void fading(){

static byte counter = 0;
static boolean prev_off[20];
int i;

for(i = OUT_MIN; i <= OUT_MAX; i++){
  if(lumi[i] == 0){
    if(prev_off[i] == HIGH){
      digitalWrite(i,LOW);
      prev_off[i] = LOW;
    }
  }
  else
    lumi[i] --;
}

counter --;

if(counter == 0){
  for(i = OUT_MIN; i <= OUT_MAX; i++){
    if(luminance[i]){
      digitalWrite(i,HIGH);
      prev_off[i] = HIGH;
    }
    lumi[i] = luminance[i];
  }
}
}


void loop(){
fading();
}


By the way, I never bothered trying this on the Tiny family of AVRs, so you're on your own there. :)

CrossRoads

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

KirAsh4

Playground?  http://www.arduino.cc/playground/Main/MsTimer2

Go Up