Only loops once when I send a command wirelessly.

I have an arduino with an xbee receiver and I’m sending commands using a hyperterminal to run RGB LEDs. Basically, I press the ‘a’ button on my keyboard to toggle through my if statements. The problem is, I want the loop to run continuously until I press the ‘a’ button again, but it only runs the loop once. When I press ‘a’ again, it runs the next loop once, and so forth. I thought by using a state change that it would run the loop until the state changed. Any suggestions? Here’s some of the code after void loop()

 if (Serial.available()){
  int characterRead = Serial.read();
  
  if (characterRead == 'a') {
    state++; }
    
    if (state==14) {
      state=0;
    }
    
    
if (state==1) {
                                     //fadeinfadeout
   for (int i=0;i<31;i+=5) {
     for (int j=0;j<NUM_LEDS;j++) { 
  BL.setPixel(j,i,0,0); 
  BL.show();
  delay(5);}
 
 }
  
  for (int i=31;i>0;i-=5) {
     for (int j=0;j<NUM_LEDS;j++) {
  BL.setPixel(j,i,0,0);
  BL.show();
  delay(5);}
  
  }
  blank();
  
  
   
  }
  else if (state==2){
  for(int i=0;i<20;i++)                                                      // Strobe Effect
   strobe(30);
   blank();
  }else if (state==3){
   
  
    for (int i=0;i<150;i++){
    BL.setPixel(random(0,NUM_LEDS),0,31,0);
    BL.show();
    delay(15);
    blank();}
 BL.setRange(0,NUM_LEDS,BL.color(0,0,0));
  BL.show();
  }
 else if (state==4){

   
  for(Counter=0;Counter < 5;Counter++)                                      // Color Wipe Effect
  {
    ColorUp(BL.color(random(0,32),random(0,32),random(0,32)));
    delay(100);
  }blank();
  
  
 }

You need to use the Autoformat tool in your IDE and you need to post the whole sketch.

Autoformat is in the Tools menu, the shortcut is usually Ctrl-T.

The problem is, I want the loop to run continuously until I press the 'a' button again, but it only runs the loop once.

Then, you need to move your existing code into two functions - getSerialData() and useSerialData(). Do this so that YOU pay attention to which code goes in which function.

Here's a hint. What you want to do with the last character received goes in useSerialData(), but the way your code is structured now, getSerialData() calls useSerialData(), instead of loop() calling useSerialData().

PaulS:

The problem is, I want the loop to run continuously until I press the 'a' button again, but it only runs the loop once.

Then, you need to move your existing code into two functions - getSerialData() and useSerialData(). Do this so that YOU pay attention to which code goes in which function.

Here's a hint. What you want to do with the last character received goes in useSerialData(), but the way your code is structured now, getSerialData() calls useSerialData(), instead of loop() calling useSerialData().

WELL PUT!

Seriously, Karma for you, Paul!

Thanks PaulS! I’ll work on it.

GoForSmoke:
You need to use the Autoformat tool in your IDE and you need to post the whole sketch.

Here’s the whole sketch for any further suggestions:

#include <BLIP_LEDS_SPI_LPD6803.h>

/
#define NUM_LEDS 24
// Set the number of LEDs in use here
int state = 0;

void setup() 
{  
  BL.setLeds(NUM_LEDS);                   // Initialisation functions
  BL.init();                              // SPI interrupt will now send out data to LEDs. This happens in the background, pretty fast.

  // If you arrange your LEDs in a grid, you must define the grid size here.
  //Assume LEDS are layed out in a zig zag manner eg for a 5x5 (viewed from front):
  //0 9 10 19 20
  //1 8 11 18 21
  //2 7 12 17 22
  //3 6 13 16 23
  //4 5 14 15 24

  BL.gridHeight=5;                        // Grid dimensions for LINE and BOX effect functions are defined here. Also used for Spectrum Analyzer function.
  BL.gridWidth=5;

  // Set all the LEDs to black (off)
  BL.setRange(0, NUM_LEDS, BL.color(0,0,0));
  BL.show();

  Serial.begin(9600);


}

void loop() 
{

  unsigned int Counter, Counter2, Counter3;

  //BL.color returns a 16bit number with the colors for red,green and blue all represented as 5 bit numbers
  //Values for r,g,b can be 0 to 31 (thats a 5 bit number!)
  //Note that the order that you pass the red, green and blue parameters depends on how the LEDs are physically connected to the
  //pins on the controller chip.  This varies with different revisions of the pixels, so you need to check this with your own
  //pixels and change the code accordingly. support@bliptronics.com

  //Set LEDs 0 to 4 as blue.




  if (Serial.available()){
    int characterRead = Serial.read();

    if (characterRead == 'a') {
      state++; 
    }

    if (state==14) {
      state=0;
    }


    if (state==1) {
      //fadeinfadeout
      for (int i=0;i<31;i+=5) {
        for (int j=0;j<NUM_LEDS;j++) { 
          BL.setPixel(j,i,0,0); 
          BL.show();
          delay(5);
        }

      }

      for (int i=31;i>0;i-=5) {
        for (int j=0;j<NUM_LEDS;j++) {
          BL.setPixel(j,i,0,0);
          BL.show();
          delay(5);
        }

      }
      blank();



    }
    else if (state==2){
      for(int i=0;i<20;i++)                                                      // Strobe Effect
        strobe(30);
      blank();
    }
    else if (state==3){


      for (int i=0;i<150;i++){
        BL.setPixel(random(0,NUM_LEDS),0,31,0);
        BL.show();
        delay(15);
        blank();
      }
      BL.setRange(0,NUM_LEDS,BL.color(0,0,0));
      BL.show();
    }
    else if (state==4){


      for(Counter=0;Counter < 5;Counter++)                                      // Color Wipe Effect
      {
        ColorUp(BL.color(random(0,32),random(0,32),random(0,32)));
        delay(100);
      }
      blank();


    }
    else if (state==5){


      for (int i=0;i<5;i++) {
        for(Counter=0; Counter < 96 ; Counter++)                                   // Color Wheel Effect
        {
          for(Counter2=0; Counter2 < NUM_LEDS; Counter2++)
          {
            BL.setPixel(Counter2, BL.Wheel((Counter)%96));
            Counter3+=(96 / NUM_LEDS);
          }    
          BL.show();
          delay(25);
        }
        blank();

      }
    }

    else if(state==6){

      for (int i=0;i<150;i++){
        BL.setPixel(random(0,NUM_LEDS),31,0,0);
        BL.show();
        delay(30);
        blank();

      } 
    }
    else if(state==7){
      for (int i=0;i<5;i++) {
        for(Counter=0; Counter < 96 ; Counter++)                                   // Scrolling Rainbow Effect
        {
          for(Counter2=0; Counter2 < NUM_LEDS; Counter2++)
          {
            BL.setPixel(Counter2, BL.Wheel((Counter2*2 + Counter)%96));
            Counter3+=(96 / NUM_LEDS);
          }    
          BL.show();
          delay(25);
        }
        blank();
      }

    }
    else if(state==8){  
      BL.setRange(0,NUM_LEDS,BL.color(31,0,31));
      BL.show();
      delay(50);

    }
    else if(state==9){  
      BL.setRange(0,NUM_LEDS,BL.color(31,31,0));
      BL.show();
      delay(50);

    }
    else if(state==10){  
      BL.setRange(0,NUM_LEDS,BL.color(0,31,31));
      BL.show();
      delay(50);

    }
    else if(state==11){  
      BL.setRange(0,NUM_LEDS,BL.color(31,0,0));
      BL.show();
      delay(50);
      blank();

    }
    else if(state==12){  
      BL.setRange(0,NUM_LEDS,BL.color(0,31,0));
      BL.show();
      delay(50);
      blank();

    }
    else if(state==13){  
      BL.setRange(0,NUM_LEDS,BL.color(0,0,31));
      BL.show();
      delay(50);
      blank();

    }
    else if(state==14){  
      ON_Fade();
      blank();

    }
    else{
      blank();
    }
  }
}

//***********************************************************************************************************

void blank()
{
  BL.setRange(0, NUM_LEDS, BL.color(0,0,0));
  BL.show();

}

void ColorUp( unsigned int ColorToUse)
{
  byte Counter;
  for(Counter=0;Counter < NUM_LEDS; Counter++)
  {
    BL.setPixel(Counter, ColorToUse);
    BL.show();
    delay(25);
  }  
}


void ON_Fade ()
{
  byte Counter;
  unsigned int a=0xff,b=0xff,c=0xff;

  for(Counter=0;Counter < NUM_LEDS; Counter++)
  {  
    BL.setPixel(Counter,BL.color(31,31,31));
  }
  BL.show();
  delay(10);

  for(int i = 0; i<31;i++)
  {
    for(Counter=0;Counter < NUM_LEDS; Counter++)
    { 
      BL.setPixel(Counter,BL.color(a,b,c));
    }
    BL.show();
    delay(10);
    a--;
    b--;
    c--; 
  }
}


void strobe(int flash_rate)
{
  for(int i=0;i < NUM_LEDS; i++)
  {  
    BL.setPixel(i,BL.color(31,31,31));
  }
  BL.show();
  delay(flash_rate);

  BL.setRange(0, NUM_LEDS-1, BL.color(0,0,0));
  BL.show();
  delay(flash_rate);
}

It looks like the only time your if-else's run is when a serial character is available.
What you have done is to mesh the action code inside of the event capture code.

You would also do well to check out switch-case as a replacement for those if-else's.

    if (state==1) {
      //fadeinfadeout
      for (int i=0;i<31;i+=5) {
        for (int j=0;j<NUM_LEDS;j++) { 
          BL.setPixel(j,i,0,0); 
          BL.show();
          delay(5);
        }

All of this (and a whole lot more) belongs in the useSerialData() function. Move it there. Then, it will be easy to figure out where the call to useSerialData() belongs.

Hey gang,
Just got back to working on this and figured it out, thanks to your suggestions! Works perfectly now!