Pages: 1 [2]   Go Down
Author Topic: Led Strobe Lights (Multi Patterns) Help  (Read 6352 times)
0 Members and 1 Guest are viewing this topic.
Harlow, Essex, UK
Offline Offline
Jr. Member
**
Karma: 1
Posts: 67
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1273
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Harlow, Essex, UK
Offline Offline
Jr. Member
**
Karma: 1
Posts: 67
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley
Logged

Harlow, Essex, UK
Offline Offline
Jr. Member
**
Karma: 1
Posts: 67
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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,

Code:
#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;
}
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1273
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Harlow, Essex, UK
Offline Offline
Jr. Member
**
Karma: 1
Posts: 67
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ?

Code:
#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;
      }
    }
  }
}


Logged

Harlow, Essex, UK
Offline Offline
Jr. Member
**
Karma: 1
Posts: 67
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1273
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is probably your problem

Code:
z = pulseIn(A0, HIGH, 20000);

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

Quote
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.
« Last Edit: November 17, 2012, 02:11:55 pm by marco_c » Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Harlow, Essex, UK
Offline Offline
Jr. Member
**
Karma: 1
Posts: 67
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 :-)
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1273
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Pages: 1 [2]   Go Up
Jump to: