Led Strobe Lights (Multi Patterns) Help

So, for one of my projects is to make a Emergency strobe light controller for LEDS.

I wrote some code for a Sweet Flash pattern (shown below), and I wanted to interface a few buttons.

I was hoping to set it up so; I power up the Controller, then with press of button 1 = The cool pattern i designed Flashes, press of button 2 = shuts off the first pattern and plays another pattern (Hazard light type Flash), and button 3 = dim running lights

Im not sure how i should set this up... can anyone help me with this? -Thanks 8)

Code;

/* Strobe Light Flasher by KB1VSP KB1VSP@usa.com */

int led = 13; int led2 = 12;

void setup() {

pinMode(led, OUTPUT); pinMode(led2, OUTPUT); }

void loop() { digitalWrite(led2, LOW) //Strobe ; digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(250); digitalWrite(led, LOW); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(250); digitalWrite(led2, LOW); delay(10); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(250); digitalWrite(led, LOW); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(250); digitalWrite(led2, LOW); delay(10); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(250); digitalWrite(led, LOW); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(250); digitalWrite(led2, LOW); delay(10); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(250); digitalWrite(led, LOW); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(250); digitalWrite(led2, LOW); //Dual Flasher delay(10); digitalWrite(led, HIGH); delay(100); digitalWrite(led, LOW); delay(10); digitalWrite(led2, HIGH); delay(100); digitalWrite(led2, LOW); delay(10); digitalWrite(led, HIGH); delay(100); digitalWrite(led, LOW); delay(10); digitalWrite(led2, HIGH); delay(100); digitalWrite(led2, LOW); delay(5); digitalWrite(led2, LOW); //Dual Flasher delay(5); digitalWrite(led, HIGH); delay(80); digitalWrite(led, LOW); delay(5); digitalWrite(led2, HIGH); delay(80); digitalWrite(led2, LOW); delay(5); digitalWrite(led, HIGH); delay(80); digitalWrite(led, LOW); delay(5); digitalWrite(led2, HIGH); delay(80); digitalWrite(led2, LOW);

}

You won't be able to respond to the buttons with all the delay statements. You need to look at the 'Blink without delay' example to work out how to restructure your code.

When you have done that it will be clearer what you need to do. In case it is not - use the button press to increment a variable that tells you what pattern number you are supposed to execute, then in the code you go to the right pattern depending on what that variable says it should be.

ok, Im going to try that

Ok, I now understand how it is done. But this Pattern im looking for is a bit more complicated. does anyone know gow i should convert this code into without delay?

More simplified version of it...>

int led = 13; int led2 = 12;

void setup() {

pinMode(led, OUTPUT); pinMode(led2, OUTPUT); }

void loop() { digitalWrite(led2, LOW) //Strobe ; digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(20); digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(250); digitalWrite(led, LOW); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(20); digitalWrite(led2, LOW); delay(50); digitalWrite(led2, HIGH); delay(250); digitalWrite(led2, LOW); }

You can use the code in http://arduino.cc/forum/index.php/topic,118230.msg891644.html#msg891644

See my explanation of setting up the blink pattern in reply #5.

Yes, I read that Reply post, I now understand alot better how this works, im confused on the code part...

Can you possibly give me an example of a code that would flash two leds, say like 3 times each?

Or, how does the code work...

Anotherwords, What is a code I can Write that will make this work.....

led1 will Flash;

HIGH 20ms LOW 50ms HIGH 20ms LOW 50ms HIGH 20ms LOW 50ms HIGH 250ms LOW 20ms

then led2 will do the same and repeats

??? really confused, I tried many types of code and nothing works for me

I'm at work so cannot test this code but would this do? Strobe pattern only changes at the end of the pattern NOT when the button is pressed.

const int led = 13;
const int led2 = 12;
const int button1 = 5;          // Button pin
const int maxStrobeMode = 3;    // Max strobe number

int strobeMode = 0;             // Current strobe number

void setup() {               
    pinMode(button1,INPUT_PULLUP);
    pinMode(led, OUTPUT);   
    pinMode(led2, OUTPUT); 
}

void loop() {
    switch (strobeMode) {
        case 0:
            digitalWrite(led2, LOW);         //Strobe
            digitalWrite(led, HIGH);   
            myDelay(20);               
            digitalWrite(led, LOW);   
            myDelay(50);               
            digitalWrite(led, HIGH);   
            myDelay(20);               
            digitalWrite(led, LOW);   
            myDelay(50);             
            digitalWrite(led, HIGH);
            myDelay(20);
            digitalWrite(led, LOW);
            myDelay(50);
            digitalWrite(led, HIGH);   
            myDelay(250);             
            digitalWrite(led, LOW);
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);               
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);                 
            digitalWrite(led2, HIGH); 
            myDelay(250);               
            digitalWrite(led2, LOW);
            break;
        case 1:
            digitalWrite(led2, LOW);         //Strobe
            digitalWrite(led, HIGH);   
            myDelay(20);               
            digitalWrite(led, LOW);   
            myDelay(50);               
            digitalWrite(led, HIGH);   
            myDelay(20);               
            digitalWrite(led, LOW);   
            myDelay(50);             
            digitalWrite(led, HIGH);
            myDelay(20);
            digitalWrite(led, LOW);
            myDelay(50);
            digitalWrite(led, HIGH);   
            myDelay(250);             
            digitalWrite(led, LOW);
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);               
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);                 
            digitalWrite(led2, HIGH); 
            myDelay(250);               
            digitalWrite(led2, LOW);
            break;
        case 2:
            digitalWrite(led2, LOW);         //Strobe
            digitalWrite(led, HIGH);   
            myDelay(20);               
            digitalWrite(led, LOW);   
            myDelay(50);               
            digitalWrite(led, HIGH);   
            myDelay(20);               
            digitalWrite(led, LOW);   
            myDelay(50);             
            digitalWrite(led, HIGH);
            myDelay(20);
            digitalWrite(led, LOW);
            myDelay(50);
            digitalWrite(led, HIGH);   
            myDelay(250);             
            digitalWrite(led, LOW);
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);               
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);                 
            digitalWrite(led2, HIGH); 
            myDelay(250);               
            digitalWrite(led2, LOW);
            break;
        case 3:
            digitalWrite(led2, LOW);         //Strobe
            digitalWrite(led, HIGH);   
            myDelay(20);               
            digitalWrite(led, LOW);   
            myDelay(50);               
            digitalWrite(led, HIGH);   
            myDelay(20);               
            digitalWrite(led, LOW);   
            myDelay(50);             
            digitalWrite(led, HIGH);
            myDelay(20);
            digitalWrite(led, LOW);
            myDelay(50);
            digitalWrite(led, HIGH);   
            myDelay(250);             
            digitalWrite(led, LOW);
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);               
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);
            digitalWrite(led2, HIGH);   
            myDelay(20);               
            digitalWrite(led2, LOW);   
            myDelay(50);                 
            digitalWrite(led2, HIGH); 
            myDelay(250);               
            digitalWrite(led2, LOW);
            break;
    }
}

void myDelay(int delayTime){
    if (digitalRead(button1) == LOW){
        strobeMode++;                       // Increment strobe mode
        if (strobeMode > maxStrobeMode){
            strobeMode = 0;                 // Reset if beyond maximum strobe mode
        }
    }
    delay(delayTime);                       // Do the delay
}

I'm new to Arduino UNO but if I were thinking of doing something like this, I would use a loop approach with a table set up to sort out the pattern required etc. A simple state-machine would be nice and easy with no resulting problems with delay() holding everything else up. I've used this approach to drive a Servo and an LCD display with some success.

Basically, I just want to know how to make that One whole flash pattern without delay. then i can make it so i can toggle it on and off with a switch...

I have modified my Multi_Blink example in the Playground to do the cool pattern you are looking for. Hope this helps.

Mulri_Blink2.h

// Multi_Blink2.h
//
// Blink lots of LEDs at diffreent frequencies simultaneously
//
// Header file is required to be able to define the structured types
//
#include <Arduino.h>

#ifndef  MULTIBLINKH
#define  MULTIBLINKH

// State values for FSM
#define  MB_NULL  0
#define  MB_LOW   1
#define  MB_HIGH  2
#define  MB_LOOP  3

#define  LOOP_UNDEF  255

typedef struct
{
  uint8_t  activeVal;     // state value for this state to be active (MB_* defines)
  uint16_t activeTime;    // time to stay active in this state stay in milliseconds or loop counter 
  uint8_t  nextState;     // If MB_LOOP this is the state to loop back/forward to 
} stateDef;

typedef struct
{
  uint8_t  ledPin;         // Arduino I/O pin number
  uint8_t  currentState;   // current active state
  uint8_t  currentLoop;    // current position in the cycle
  stateDef state[5];       // the MB_* state definitions. Add more states if required
  uint32_t nextWakeup;     // the 'time' for the next wakeup - saves the millis() value
} ledTable;

#endif

Multi_Blink2.ino

// Multi_Blink2
//
// Blink lots of LEDs at different frequencies simultaneously, include delays and loops in patterns
//
// Marco Colli - September 2012
//
// Demonstrates the way to carry out multiple time based tasks without using the delay() function
// Demonstrates the use of structures (and structures within structures)
// Demonstrates a data driven approach to programming to create compact, reusable code
//

#include "Multi_Blink2.h"  // type definitions

// Blink Table T - Modify this table to suit whatever the output requirements are 
// Add or delete lines as required to achieve the desired effects.
// To add additional states the structure in the header file needs to be modified
//
ledTable  T[] =
//Pin  St Lopp  State 0          State 1            State 2          State 3         State 4          Wkup
{ 
  { 13, 0, 0, {{MB_HIGH, 20, 0}, {MB_LOW, 50, 0}, {MB_LOOP, 3, 0}, {MB_HIGH, 250, 0}, {MB_LOW, 450, 0}}, 0 },
  { 12, 0, 0, {{MB_LOW, 450, 0}, {MB_HIGH, 20, 0}, {MB_LOW, 50, 0}, {MB_LOOP, 3, 1}, {MB_HIGH, 250, 0}}, 0 },
};

// Self adjusting constants for loop indexes
#define  MAX_STATE  (sizeof(T[0].state)/sizeof(stateDef))
#define  MAX_LED    (sizeof(T)/sizeof(ledTable))

void setup()
{
  for (int i=0; i < MAX_LED; i++)
  {
    pinMode(T[i].ledPin, OUTPUT);
    
    T[i].nextWakeup = 0;
    digitalWrite(T[i].ledPin, LOW);
    T[i].currentLoop = LOOP_UNDEF;
  }
}

void loop()
{
  for (int i=0; i < MAX_LED; i++)
  {
    // check if the state active time has expired (ie, it is less than current time)
    if (millis() >= T[i].nextWakeup)
    {
      T[i].nextWakeup = millis() + T[i].state[T[i].currentState].activeTime;

      switch (T[i].state[T[i].currentState].activeVal)
      {
        case MB_LOW:
        case MB_HIGH:    // Write digital value
          digitalWrite(T[i].ledPin, T[i].state[T[i].currentState].activeVal == MB_HIGH ? HIGH : LOW);
          T[i].currentState = (++T[i].currentState) % MAX_STATE;
          break;
          
        case MB_LOOP:  // loop back to specified state if there is still count left
          // first time in this state set the loop counter
          if (T[i].currentLoop == LOOP_UNDEF)
          {
            T[i].currentLoop = T[i].state[T[i].currentState].activeTime;
          }

          // loop around or keep going?          
          if (T[i].currentLoop-- > 0)
          {
            T[i].currentState = T[i].state[T[i].currentState].nextState;
            T[i].nextWakeup = 0;  // do it immediately
          }
          else 
          {
            T[i].currentLoop = LOOP_UNDEF; // set up loop counter
            T[i].currentState = (++T[i].currentState) % MAX_STATE;
          }
          break;  
          
        default:  // just move on - handles NULL and any stupid states we may get into
          T[i].currentState = (++T[i].currentState) % MAX_STATE;
          break;
      }
    }
  }
}

I was searching this forum for multiplexing LEDs and like this pattern a lot :slight_smile:

I’m installing navigation lights on a model aircraft.

Along with this flash pattern, I would also like to include an LED that gives the impression of a rotating beacon.

I have come up with the pattern as below based on PWM, but how would this be included that whilst the LEDs from the above pattern are doing there thing, the beacon is also running.

Thank you for any suggestions / help.

void Beacon()
{
  for(value = 1 ; value <= 30; value+=1) // fade in (from min to max)
  {
    analogWrite(5, value);	     // sets the value (range from 0 to 255)
    delay(45);				    // waits for 30 milli seconds to see the dimming effect
  }
  digitalWrite (5, HIGH);
  delay (70);
  for(value = 30; value >=1; value-=1)   // fade out (from max to min)
  {
    analogWrite(5, value);
    delay(45);
  }
}

This should do the same thing without blocking. I have not compiled or tested this code, so there could be some errors.

This function could be added anywhere to give the fading as it is self contained.

#define	FADE_IN	0
#define	FULL_BRIGHT	1
#define	FADE_OUT	2

#define	FADE_DELAY	45	//ms
#define	FULL_DELAY	70	//ms

#define	LED_PIN		5
#define	FADE_MAX	30	// max PWM value
#define	FADE_MIN	1

void Beacon()
{
  static uint32_t	nextWakeup = 0;
  static uint8_t	currentState = FADE_IN;
  static uint8_t	fadeValue = FADE_MIN;

  if (millis() <= nextWakeup)
    return;  // do nothing as time has not expired

  switch (currentState)
  {
    case FADE_IN:
      analogWrite(LED_PIN, fadeValue++);
      if (fadeValue >= FADE_MAX)
      {
        currentState = FULL_BRIGHT;
        fadeValue = FADE_MAX;
      }
      nextWakeup = millis() + FADE_DELAY;
    break;

    case FULL_BRIGHT:
      digitalWrite(LED_PIN, HIGH);
      currentState = FADE_OUT;
      nextWakeup = millis() + FULL_DELAY;
    break;

    case FADE_OUT:
      analogWrite(LED_PIN, fadeValue--);
      if (fadeValue <= FADE_MIN)
      {
        currentState = FADE_IN;
	fadeValue = FADE_MIN;
      }
      nextWakeup = millis() + FADE_DELAY;
    break;

    default:	// error catch all - restart the sequence
      currentState = FADE_IN;
      fadeValue = FADE_MIN;
    break;
  }

  return;
}

Many thanks, where would the Beacon() function be called from within the main original group.

Essentially, I want the LEDs to be flashing as per the original example, along with the other LED running the Beacon routine.

Thanks for your help :slight_smile:

Put it either at the start of loop or at the end of loop.

I thought that would be the case but wanted to check as the beacon LED just illuminates and stays on without any dimming.

Any ideas please.

Kind regards,

Steve

Check if your code is the same as posted as I corrected an error in the FULL_BRIGHT section soon after I posted it.

Spot on, I obvioulsy included your code as soon as you posted it and didn't realise it had been changed.

Thanks very much, does exactly what i want and looks very cool :)

Sorry to be pop up again, I wanted to add another LED onto another PMW pin, such as IO3.

The below code works, but is this method the most efficient to achieve the same PWM pattern on 2 IO pins ?

Many thanks for your help,

#define	 FADE_IN	 0
#define	 FULL_BRIGHT	 1
#define	 FADE_OUT	 2

#define	 FADE_DELAY	 45	 //ms
#define	 FULL_DELAY	 70	 //ms

#define	 LED_PIN1	 5
#define	 LED_PIN2	 3

#define	 FADE_MAX	 30	 // max PWM value
#define	 FADE_MIN	 1

Void Beacon()
{
  static uint32_t	 nextWakeup = 0;
  static uint8_t	 currentState = FADE_IN;
  static uint8_t	 fadeValue1 = FADE_MIN;
  static uint8_t	 fadeValue2 = FADE_MIN;  

  if (millis() <= nextWakeup)
    return;  // do nothing as time has not expired

  switch (currentState)
  {
    case FADE_IN:
      analogWrite(LED_PIN1, fadeValue1++);
      analogWrite(LED_PIN2, fadeValue2++);      
       if (fadeValue1 >= FADE_MAX)
      {
        currentState = FULL_BRIGHT;
        fadeValue1 = FADE_MAX;
      }
       if (fadeValue2 >= FADE_MAX)
      {
        currentState = FULL_BRIGHT;
        fadeValue2 = FADE_MAX;
      }      
      nextWakeup = millis() + FADE_DELAY;
    break;

    case FULL_BRIGHT:
      digitalWrite(LED_PIN1, HIGH);
      digitalWrite(LED_PIN2, HIGH);      
       currentState = FADE_OUT;
      nextWakeup = millis() + FULL_DELAY;
    break;

    case FADE_OUT:
      analogWrite(LED_PIN1, fadeValue1--);
      analogWrite(LED_PIN2, fadeValue2--);      
       if (fadeValue1 <= FADE_MIN)
      {
        currentState = FADE_IN;
	 fadeValue1 = FADE_MIN;
      }
       if (fadeValue2 <= FADE_MIN)
      {
        currentState = FADE_IN;
	 fadeValue2 = FADE_MIN;
      }
      
      nextWakeup = millis() + FADE_DELAY;
    break;

    default:	 // error catch all - restart the sequence
      currentState = FADE_IN;
      fadeValue1 = FADE_MIN;
      fadeValue2 = FADE_MIN;      
    break;
  }
  return;
}

In the case of 2 LEDs it is probably ok. You could consider just electrically joining them if they are supposed to be identical, but software is probably easier.

In the more general case where you may want to do lots of LEDs and these could be at different times and out of phase, then you need to keep the data and the code separated so that each LED has its own context (eg, pin, timer, status, etc). The data is then passed to the code (in this case as a parameter to the function, maybe) implementing the Finite State Machine (FSM) to run the FSM on the data supplied. This is the essence of what MultiBlink2 does and Beacon is very similar.

If you are new to programming it is worth studying these pieces of code as they are the key to how you do things on the Arduino (or any single tasking computer) without holding anything else up. Maybe start by reading about FSM and then look at how they are implemented in this code - Beacon is a lot simpler than MultiBlink.