For loops??

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.

And that big key at the bottom of the keyboard? You know which one. Use it more often. Ditto for that big one on the middle row of characters, on the right.

And scope.
You need to pay more attention to scope.

code is real short i guess it should work, not

sp. "Code is real short I guess it should work. Not!"

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

That doesn't even compile, right?

Read this before posting a programming question

I have tried that code Marco_C and I like it. I don't really get most of it yet... But in these lines here
ledTable T[] =
//Pin St Lopp State 0 State 1 State 2 State 3 Wkup
{
{ 3, 0, 0, {{MB_HIGH, 25, 0}, {MB_LOW, 25, 0}, {MB_LOOP, 3, 0}, {MB_LOW, 300, 0}}, 0 },
{ 4, 0, 0, {{MB_HIGH, 25, 0}, {MB_LOW, 25, 0}, {MB_LOOP, 3, 0}, {MB_LOW, 300, 0}}, 0 },
{ 5, 0, 0, {{MB_LOW, 250, 0}, {MB_HIGH, 250, 0}, {MB_LOW, 250, 0}, {MB_LOOP, 4, 1}}, 0 },
{ 6, 0, 0, {{MB_LOW, 250, 0}, {MB_LOW, 250, 0}, {MB_HIGH, 250, 0}, {MB_LOOP, 4, 1}}, 0 },
{7, 0, 0, {{MB_LOW, 0, 0}, {MB_LOW, 500, 0}, {MB_HIGH, 500, 0}, {MB_LOOP, 4, 1}}, 0 },
};

I have fiddled with them somewhat. But I want the LED on pin 3 to do it's thing and it does..I have it flashing 3 times quickly and then wait, but I want it's mate on pin 4 to wait while it flashes then flash 3 times and then back to pin 3. They are a pair one flashes 3 times quickly then the other, on and off like that, but I can't get it work. They just flash together at the same time. How could I change it?

Also why is the loop in a different spot in two of the lines? (MB_LOOP)? I guess you can move it around to fit your LED state changes??

Thanks for the help ...

Andrew

Please edit your post, select the code, and put it between [code] ... [/code] tags.

You can do that by hitting the # button above the posting area.

Here is the explanation:

  • MB_HIGH and MB_LOW are pretty obvious. They keep the LED on or off for the specified time.
  • MB_LOOP makes the pattern loop back to the nominated array element in the pattern for the specificed number of times.

So the data

  { 3, 0, 0, {{MB_HIGH, 25, 0}, {MB_LOW, 25, 0}, {MB_LOOP, 3, 0}, {MB_LOW, 300, 0}}, 0 },

does this:
0 LED on for 25 ms
1 LED off for 25 ms
2 Loop back to element 0 and repeat it 2 more time (3 total)
3 LED off for 300 ms - this is just a delay while the 'other' LED does its thing

So if we want to have a paired LED that works in tandem with this one we need to have the logic
0 LED off for 300 ms - this is just a delay while the 'other' LED does its thing
1 LED on for 25 ms
2 LED off for 25 ms
3 Loop back to element 1 and repeat it 2 more time (3 total)

which provides to table entry

  { 4, 0, 0, {{MB_LOW, 300, 0}, {MB_HIGH, 25, 0}, {MB_LOW, 25, 0}, {MB_LOOP, 3, 1}}, 0 },

So if we look at them as a pair:

  { 3, 0, 0, {{MB_HIGH, 25, 0}, {MB_LOW, 25, 0}, {MB_LOOP, 3, 0}, {MB_LOW, 300, 0}}, 0 },
  { 4, 0, 0, {{MB_LOW, 300, 0}, {MB_HIGH, 25, 0}, {MB_LOW, 25, 0}, {MB_LOOP, 3, 1}}, 0 },

You can see that the second MB_LOOP (pin 4) is in a different spot in the sequence and it loops back to a different place in the array. That is because we need to add the initial delay to the second LED while the sequence for pin 3 is executing.

Thanks Marco. It is making more sense now. I will play around with it and see what I can get going. I learn a tidbit from each piece of code others write, so thank you.

I am sure I will have other questions and I'll post them soon!! :slight_smile:

Thank you to everyone for their input so far. I'll try and remember the "code" thingy to make it easier for you to read.

Andrew

I am digging around in that code Marco, thanks. Now can I just load that into an ATTiny85? I think it will fit?
Does most code work with the different chips?

I tried to just upload the code and it took it. But...the LED's stay on after they blink instead of stay off. I tried playing with some numbers in the table but no luck. Any ideas? (I say that but I am sure you already know...LOL)

Sorry for the noob questions, but I find you folks are very helpful!!

Andrew

Fairly easy: send a set of patterns to the leds and that pattern determines how fast they blink.

For example, if '1' means on and '0' means off,

0b11 -> both leds are on
0b01 -> bit 0 is still on, but bit 1 is blinking
0b10 -> bit 0 is blinking and bit 1 is blinking
0b00 -> bit 1 is blinking and bit 0 isn't.

A sequence like that will blink one led at 1/2 of the speed of the other led.

You can expand this approach to cover multiple leds at multiple speed.