Led Strobe Lights (Multi Patterns) Help

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 :slight_smile:

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.

Having got the LED pattern working (and huge thanks to Marco), I wanted to add a little more hardware to the Arduino.

I wanted to add a little more code that listens to one of the pins for various PWM signals and if they are within a certain range, action by calling a subroutine.

However it seems to lock out some of the LED patterns. I essentially want to the LED pattern to continue if that is possible ?

Can anyone suggest where I have gone wrong please ?

#include "Multi_Blink2.h"  // type definitions
#include <multiCameraIrControl.h>

Sony Nex5(9);
int z=100; 

// 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
{ 

  { 11, 0, 0, {{MB_LOW, 1500, 0}, {MB_HIGH, 35, 0}}, 0 },  //
  { 0, 0, 0, {{MB_HIGH, 20, 0}, {MB_LOW, 50, 0}, {MB_LOOP, 3, 0}, {MB_HIGH, 250, 0}, {MB_LOW, 450, 0}}, 0 },  //
  { 1, 0, 0, {{MB_HIGH, 20, 0}, {MB_LOW, 50, 0}, {MB_LOOP, 3, 0}, {MB_HIGH, 250, 0}, {MB_LOW, 450, 0}}, 0 },  //
  { 5, 0, 0, {{MB_LOW, 450, 0}, {MB_HIGH, 20, 0}, {MB_LOW, 50, 0}, {MB_LOOP, 3, 1}, {MB_HIGH, 250, 0}}, 0 },  //
  { 7, 0, 0, {{MB_LOW, 450, 0}, {MB_HIGH, 20, 0}, {MB_LOW, 50, 0}, {MB_LOOP, 3, 1}, {MB_HIGH, 250, 0}}, 0 },  //
  { 2, 0, 0, {{MB_HIGH, 35, 0}, {MB_LOW, 1500, 0}}, 0 },  
  
};

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

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

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

#define	 FRONT_LED	 11

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

void setup()
{
  Serial.begin(9600);      // Debug via serial window
  delay (2500);
  pinMode(FRONT_LED, OUTPUT);
  pinMode (11, OUTPUT);    // On board status LED 
  pinMode(A0, INPUT);      // RC PMM Signal input
//  pinMode(LED_PIN2, OUTPUT);
  
  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()
{
  z = pulseIn(A0, HIGH, 20000);

if (z>1155 && z<1170) {
  Nex5.shutterNow();
  }
  
if (z>1780 && z<1820) {
  Nex5.shutterNow();
  delay(1500);
  }

if (z>1430 && z<1500) {
  Nex5.videoToggle();
  delay(500);
  }  

  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;
      }
    }
  }
}

Anyone able to assist in the above please.

I'm trying to maintain the blinking LEDs, but also respond to a PWM input by activating an infrared LED for an IR remote.

I think i'm getting the "multitasking" bit round my neck!

This is probably your problem

z = pulseIn(A0, HIGH, 20000);

The last value is the timeout in microseconds. From the online reference:

timeout (optional): the number of microseconds to wait for the pulse to start; default is one second (unsigned long)

20k microseconds is 20 milliseconds. This is like putting a delay() of 20 milliseconds every time through the loop. Some of the patterns are only on/off for that amount of time, so you would see interference.

I would suggest making this much smaller. Experiment as to where the limit is by putting in a call to delayMicroseconds() instead of pulseIn() and play with the values until you find one that provides acceptable response. This will probably have to be a small fraction of the time that the fastest pattern executes.

Thanks for taking time to reply Marco, it's appreciated.

I've reduced the timeout as suggested and also it would appear the serial.begin command was causing an issue. All works now, well, sort of ;-)......

Is there a way that you know of to keep the LEDs flashing whilst the Arduino performs another function.

At the moment when the pulseIn command is between the preset values and it goes off and calls another command, obviously this stops the LED pattern.

It's essentially an IR remote for a Sony Camera on a drone helicopter. So I want the LED pattern to continue whilst the camera functions are being actioned.

Do you know of a way I can achieve this?

I can post the entire code if necessary, but its just a small sequence to flash an IR LED at different rates depending on what is being called.

Thank you again for your help :slight_smile:

You should have plenty of processing power to do everything you need. Initially make sure that you have no delay() or waiting timeouts in the code. This is usually the killer for most new programmers as even 1 millisecond repeated in a loop can cause a big delay. Eliminate these by implementing Finite State Machine techniques.

What else you can do depends on what your priorities are. If the LEDs are secondary priority to the IR then putting up with a slightly irregular pattern may be easiest.

Look at interrupt routines to receive and send the IR characters. I use an IR library (IRRemote) that does not cause me delays http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com. If nothing else you may want to see how this person has implemented his code.