Pages: 1 [2] 3   Go Down
Author Topic: For loops??  (Read 2136 times)
0 Members and 1 Guest are viewing this topic.
Sydney, Australia
Online Online
Edison Member
*
Karma: 27
Posts: 1188
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Sydney, Australia
Online Online
Edison Member
*
Karma: 27
Posts: 1188
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Offline Offline
Newbie
*
Karma: 0
Posts: 39
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: September 03, 2012, 05:59:37 pm by faeve » Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 212
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
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(.....)
}
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 241
Posts: 24480
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 553
Posts: 46287
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 241
Posts: 24480
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Quote
code is real short i guess it should work, not
sp. "Code is real short I guess it should work. Not!"
« Last Edit: September 04, 2012, 05:19:38 am by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.gammon.com.au/blink
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Sydney, Australia
Online Online
Edison Member
*
Karma: 27
Posts: 1188
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Code:
 { 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
Code:
 { 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:
Code:
 { 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.

« Last Edit: November 30, 2012, 07:59:08 pm by marco_c » Logged

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

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: December 02, 2012, 03:39:37 pm by Antennas » Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: 1 [2] 3   Go Up
Jump to: