Creating callable sequence's

Hi Everyone

I have a 4 leds and want to program a series of patterns or sequences. What i want i want to be able to do is call the sequence by saying something such as seqOne etc. The project was inspired by hacking a bunch of Christmas themed solar lamps.

This will translate into if button push advance to next sequence programmed.

Cheers

Joker94_ic

Pseudo code:

void setup()
{
  seq = 1;  // this will effectively always start with sequence 1 being displayed when you first turn the thing on
  maxSeq = 2; // how many sequences are defined
  ... do your various pin setup ...
}

void seqOne()
{
  define what sequence one would look like
}

void seqTwo()
{
  define what sequence two would look like
}

void loop()
{
  if (button has been pressed)
  {
    seq++;
    if (seq > maxSeq) seq = 1;  // reset it back to 1 if we've exceeded maxSeq
  }
  switch (seq)
  {
    case 1:
      seqOne();
      break;
    case 2:
      seqTwo();
      break;
  }
}

Now, there are two ways of approaching that. Either you do it like that, where the various sequences being defined do one thing and exit (back into the main loop) and get called again when the main loop cycles through. This also means that you can't do anything else within the main loop while the sequence is running, so if you have things like delay() within the sequence, you'll have to wait till it's completed and returns to the main loop.

The other way is to follow the Blink Without Delay example and set elapsed timers within each sequence.

I did a similar project as this, except mine automatically advances to the next sequence. And because I needed to also be checking an RF module for incoming data, I made the whole thing without delay() in the sequences. The main loop runs constantly and the specific sequence gets called over and over again. For a sequence where the lights are fading, it's one step per sequence call (which can be multiple cycles within the main loop.) Basically I set the fade speed to say 40ms, so every 40ms it needs to fade by one step brighter or darker. The main loop runs continuously and checks the sequence timer. If it's >40ms, then call the sequence to advance one step, return to the main loop and wait another 40ms. This allows me to do other things within the main loop during those 40ms that I'm waiting (like checking for incoming data on the RF module.)

See video here: http://www.youtube.com/watch?v=-3ex1k8f_Nk

Thanks very much for your help!

The problem i am running into now is that i am getting the error message

a function-definition is not allowed here before ‘{’ token

. I am getting it infront of the ‘{’ of the first attempt at ’ void seqOne(). I have identified it with the comment marks /************/.

void setup(){
  {
    lcd.begin(16, 2);

    seq = 1;
    maxSeq = 4;

    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(11, OUTPUT);

    pinMode(7, INPUT);    // set pin for button

  }

  void seqOne()  /*************/
  {
    digitalWrite(8, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(11, HIGH);
    delay(1000);
    digitalWrite(8, LOW);
    delay(200);
    digitalWrite(10, LOW);
    delay (200);
    digitalWrite(9, LOW);
    delay(200);
    digitalWrite(11, LOW);
    delay(1000);
  }

What is going wrong and what is the best way to over come it?

cheers

Joker94_ic

Joker94_ic:

void setup(){   <== you open the bracket here

{  <== then again here?

Thanks very much. You got it, it was a problem with the way I had placed he brackets. After i fixed this i dont have this error message anymore!

Thanks again.

You might want to have a look at my various approaches of blinking 20 LEDs here http://www.blinkenlight.net. Some of the examples allow to switch between different effects. I also have examples where the blinking happens interrupt driven thus keeping the main loop free for other things.

KirAsh4: http://www.youtube.com/watch?v=-3ex1k8f_Nk

Hello guys,i am so sorry to bring back an old topic,i just want to ask if would you mind sharing the code for your led display.I am most interested on making the raining effect,and i still cant get it to work. Thank you!

Keep in mind this was written for bit banging, but it should do the job with SPI as well.

This is for ONE single string. I have 16 strings total in my setup. The random calls in the code takes care of each string having a different start time and speed. This is a callable routine. You need the appropriate variables in your setup() for it to work:

#define STRIP_LENGTH 10 // this is the amount of LEDs in the string
int pause = 0, string = 0, fallSpeed = 0;
long strip_colors[STRIP_LENGTH];
int tCol = 0xFF;
long prevMillis;
int SDI = 2;  // data pin
int CKI = 3;  // clock pin
// Falling snow, random speed
void snowFlakes() {
  if (pause > 0) {
    if (millis() - prevMillis > ((string > 0) ? fallSpeed : pause)) {
      pushString();
      long color = 0;
      for (int x = 0; x < 3; x++) {
        color <<= 8;
        color |= tcol;
      }
      strip_colors[0] = ((tcol > 0) ? color : 0);
      postFrame();
      prevMillis = millis();
      string++;
      if (string > (STRIP_LENGTH + 8)) {
        string = 0;
        pause = random(250, 1000);
        tcol = 0xFF;
        fallSpeed = random(40, 61);
      }
      else {
        tcol >>= 1;  // this effectively halves the current color from 0xFF to 0x0 in 8 steps.
      }
    }
  }
  else {
    pause = random(0, 1000);
    fallSpeed = random(40, 61);
    prevMillis = millis();
  }
}

The calls to pushString() and postFrame() are what actually do the task of moving the sequence down the line:

pushString():

void pushString(int ledString) {
    // push string : FWD
    for (int px = (STRIP_LENGTH - 1); px > 0; px--) {
      strip_colors[px] = strip_colors[px - 1];
    }
}

postFrame():

void post_frame(int side) {
  for(int LED_number = 0 ; LED_number < STRIP_LENGTH ; LED_number++) {
    long this_led_color = strip_colors[LED_number]; //24 bits of color data

    for(byte color_bit = 23 ; color_bit != 255 ; color_bit--) {
      //Feed color bit 23 first (red data MSB)
      digitalWrite(CKI, LOW); //Only change data when clock is low

      long mask = 1L << color_bit;
      //The 1'L' forces the 1 to start as a 32 bit number, otherwise it defaults to 16-bit.

      if(this_led_color & mask) 
        digitalWrite(SDI, HIGH);
      else
        digitalWrite(SDI, LOW);

      digitalWrite(CKI, HIGH); //Data is latched when clock goes high
    }
  }
  //Pull clock low to put strip into reset/post mode
  digitalWrite(CKI, LOW);
  delayMicroseconds(500); //Wait for 500us to go into reset
}

Thought I'd explain some more on how to achieve it in case you want to write your own. Basically you're only doing one thing, which is to push a bright dot down a string. That dot just happens to have a fading trail. So you're creating a loop that pushes the dot down the string with each pass:

start with a single bright dot at the beginning of the string loop move the dot to the next position endloop

That's the very basic idea. As you move the dot, you're turning off the previous one, otherwise you end up with the whole string lighting up.

Now, it's very easy to simply move the entire string down one position, as opposed to one single dot. Just loop through all of your LEDs and move them. I do that in an array ( strip_colors[STRIP_LENGTH] ) that holds the color values. So, I created a loop that simply takes one pixel, and assign it the color value of the previous pixel in the strip. Take ten LEDs in a strip (and call them pixels if you will.) The pushString() loop counts backwards and assigns each pixel the color for the previous one, effectively moving the whole string one spot over.

Since the loop pushed everything over, you are now left with the very first pixel without any data (or at least, it has the same data in it because the loop doesn't assign it anything.) This is now the one you can change to a different color value. In my case, since I'm simply fading the color down the string, I take whatever the value is and half it by pushing the bits to the right: tcol >>= 1

As you push the string, and add in the new color at the top, you'll end up with a fade effect as the bright dot travels down the line.

You can get crazy and add any random color at the top of the string (the very first pixel), the pushString() loop simply moves it down the line each time. Makes for a very colorful string, as opposed to a single white dot traveling down.

The double drops that I have further in the video is the same method, except the string is divided into two, an upper and lower half. The same thing happens though, the top half I move the pixels up, while the bottom half I move them down. And I add random colors instead of just white.

Keep in mind that if you want to use RGB colors though, you're going to have to break it up and half each separate channel before recombining it again. You can't half the whole value as is, you end up with color shifts. For example, an orange dot will fade to red first before it goes off. By separating the channels, halving each one separately, then recombining to the final RGB color, you will retain the orange color fading to off consistently.