Go Down

Topic: Led Strobe Lights (Multi Patterns) Help (Read 7483 times) previous topic - next topic

Tissy

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

marco_c

Check if your code is the same as posted as I corrected an error in the FULL_BRIGHT section soon after I posted it.
Arduino libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

Tissy

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

Tissy

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: [Select]

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

marco_c

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.
Arduino libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

Tissy

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: [Select]

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



Tissy

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!

marco_c

#22
Nov 17, 2012, 08:09 pm Last Edit: Nov 17, 2012, 08:11 pm by marco_c Reason: 1
This is probably your problem

Code: [Select]
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.
Arduino libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

Tissy

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

marco_c

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.
Arduino libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

Go Up