For loops??

I am not really sure what I need just yet. I only have about 3 days under my belt with the arduino.

What I am looking to do is blink a pair of LED's at one rate while blinking another pair at a different rate. What I have now is using delay functions and it makes it go through the whole sequence before it starts again which isn't working. I want to blink lights like in a police car. The red and blue go fast and the headlights blink slowly (wig,wag). I think it would be a good learning project but I haven't found anything similar yet online to look at.
Just a nudge in the right direction would be appreciated.
It's taking longer to pick this up than I thought, I am not 20 anymore darn it. LOL.... :blush:

Thank you all.

Andrew

Look at the Blink Without Delay example.

After looking at blink without delay, look at this tutorial I wrote on millis(), which shows how to blink 2 LEDs at different rates:

http://www.cmiyc.com/blog/2011/01/06/millis-tutorial/

And just to add another, you can look at MultiBlink. This is probably a bit challenging at your level of understanding, but it will stretch your thinking.

Thanks Gents. I will look and try to learn as I read. I appreciate your replies, thank you.

Andrew

Hey Marco-C I am looking at that multibink. But I think it needs a library MultiBlink.h ?? Where do I get that or how does that work...you are right that is very new for me..but hey I can maybe learn about it now.

Thank you.

Andrew

The header file is part of the posting. You will need to split them as there was no easy way to do that in the playground. It is the first part of the code up to the #endif, as per the comments in the program.

So I saved the header file as a .h in the directory of the sketch. But now the sketch won't compile as it doesn't like the table T..says <Multi_blink:47: error: 'T' was not declared in this scope" what do I need to modify in this line??
Also if you say that it needs to go into the sketch dir, well I can't find it..tried many things..it's not in the documents and I don't see one where it should be..I know it's obviously around somewhere but I can't find it. It's supposed to work with the .ino file right??

Andrew

Post your code. We can't tell you what you did wrong without seeing what you did. Sounds like you aren't properly declaring your LedTable T, but that's just a guess without any code to look at.

It wasn't my code it is from the Muilti_Blink on the play ground. Everyone seemed so aware of it I didn't post. But here it is.

/ Multi_Blink
//
// Blink lots of LEDs at different frequencies simultaneously
//
// Marco Colli - May 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_Blink.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.
//
ledTable  T[] =   // THIS LINE HERE 
//Pin  St   State 0      State 1  LastTime
{ 
  { 3, 0, {{HIGH, 300}, {LOW, 300}}, 0 },
  { 4, 1, {{HIGH, 300}, {LOW, 600}}, 0 },
  { 5, 0, {{HIGH, 500}, {LOW, 500}}, 0 },
  { 6, 1, {{HIGH,  50}, {LOW, 100}}, 0 },
  { 7, 0, {{HIGH, 100}, {LOW,  50}}, 0 },
  { 8, 1, {{HIGH, 500}, {LOW, 500}}, 0 },
  { 9, 0, {{HIGH, 400}, {LOW, 600}}, 0 },
  {10, 0, {{HIGH, 600}, {LOW, 400}}, 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].lastTransTime = millis();
    digitalWrite(T[i].ledPin, T[i].state[T[i].currentState].activeVal);
  }
}

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].lastTransTime + T[i].state[T[i].currentState].activeTime)
    {
      // switch to the next state with wrapround
      T[i].currentState = (T[i].currentState + 1) % MAX_STATE;

      // write out the next state value
      T[i].lastTransTime = millis();
      digitalWrite(T[i].ledPin, T[i].state[T[i].currentState].activeVal);
    }
  }
}

Moderator edit: [code] ... [/code] tags added. (Nick Gammon)

If you put code tags around it, we'll be able to read it as you intended.

I'll look for code tags, but that what I intended. It works now I guess I needed to restart the sketch or arduino. I tried to add more lines but it won't work it says ulti_blink:22: error: too many initializers for 'stateDef [2]'"
As I modified the line to read.. { 5, 0, {{HIGH, 100}, {LOW, 100}, {HIGH, 100}, {LOW, 100}}, 0 },

Can you not do that? I want to make the LED flash quickly 3 times then wait as another LED flashes the same , then back.

Antennas:
I'll look for code tags, but that what I intended. It works now I guess I needed to restart the sketch or arduino. I tried to add more lines but it won't work it says ulti_blink:22: error: too many initializers for 'stateDef [2]'"
As I modified the line to read.. { 5, 0, {{HIGH, 100}, {LOW, 100}, {HIGH, 100}, {LOW, 100}}, 0 },

Can you not do that? I want to make the LED flash quickly 3 times then wait as another LED flashes the same , then back.

No, you can not do that. Statedef is a struct that declares two fields, a state (either HIGH or LOW) and a duration. LedTable is another struct that declares a statedef array of two elements, so you can't put more than 2 elements into it, and you are trying to put 4 in.

Multiblink isn't really suited to what you want to do because it's designed to flash multiple LEDs completely asynchronously, and you want synchronous behavior.

I'll look for code tags, but that what I intended.

You intended it to turn to italics two thirds of the way through?

Ha, no I did not dxwood. Well taken. I meant the code looked as it was right to me. Formatting aside.

jraskell, what do you suggest? I thought multiblink was exactly what I wanted as the LED's don't have to have any relation at all except for in pairs. Such as two blink back and forth or two blink fast then off as the other blinks.

I would welcome any code help at all. Thanks for your replies.

What you can do with Multiblink as it stands is blink one LED fast (say at 50 ms) and then another one slowly (say at 150ms) by creating a table of 2 elements.

What will happen is that on the third blink the second LED will light at the same time as the first. That is probably not what you are looking for,

There is a way to modify multblink to include the cycling a pattern and then adding in a delay at the end of the cycle. You could then define that one led will cycle 3 times at 50ms then delay 100ms before starting the cycle again. The second LED would not need this as it only goes off once. The change is relatively easy to do and I can help with that if I have described it correctly.

OK, so I modified MultiBlink to add the concept of looping in patterns. I think this does what you want from a flashing lights perspective, and I have a more flexible program to boot!

Let me know how you go with this.

Multi_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[4];       // 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         Wkup
{ 
  { 3, 0, 0, {{MB_HIGH, 50, 0}, {MB_LOW, 100, 0}, {MB_LOOP, 4, 0}, {MB_LOW, 800, 0}}, 0 },
  { 4, 0, 0, {{MB_LOW, 100, 0}, {MB_HIGH, 50, 0}, {MB_LOOP, 4, 0}, {MB_LOW, 800, 0}}, 0 },
  { 5, 0, 0, {{MB_LOW, 800, 0}, {MB_HIGH, 50, 0}, {MB_LOW, 100, 0}, {MB_LOOP, 4, 1}}, 0 },
  { 6, 0, 0, {{MB_LOW, 800, 0}, {MB_LOW, 100, 0}, {MB_HIGH, 50, 0}, {MB_LOOP, 4, 1}}, 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;
      }
    }
  }
}

Hi Marco,

thanks for sharing your code.
I have tried your first version of your Multiblink, I have created a doc.h called Multi_Blink.h and saved it in the same folder as Multi_Blink.ino, I have also created a folder and placed it in the Arduino Library folder.
It was giving me this type of error 'leadTable does not name a type'.
Then I have created a Multi_Blink2.h file, placed it in the same folder, closed everything, and it now works like a charm.
Many thanks for sharing!

Best

F

ok just wrote something simple.. you can ad more if lines if you have more leds, code is real short i guess it should work, not tested it.

setup{
state1=false;
state2=false;
int pin1=1;
int pin2=2;
int x =0;
PinMode(pin1,OUTPUT);
PinMode(pin2,OUTPUT);
}

// a short method using modulo function >> % <<

void loop(){
x++
if(x%3==0)   {state1=!state1;digitalWrite(pin2,state2);}
if(x%13==0) {state2=!state2;digitalWrite(pin2,state2);}

delay(.....)
}

If you like ( I do), you can use the IDE's auto format feature to help make your code more legible before you post it.