Infamous GOTO or Interupt question

Hi Everyone,
Let me explain my program first so the code makes sense, not that its that hard to understand at all. Basically I want to read in a byte, or some bytes from the serial input of my UNO. That serial data will then trigger a RGB LED to either light up with a single color, or cycle through a pattern of colors. If the LED is cycling through the pattern, I want to give the user the ability to "exit" the pattern if new serial data arrives and execute that new request. Reason being is the color cycling may take like 3 minutes to complete (when I tweek that code). So I dont want serial data to sit in the buffer and the user to have to wait until the color cycling is over before their "new" request is acted upon.

Here is a simple proof of concept I came up with to test out this theory which will then be incorporated into a larger program later. Now when I execute this, if I enter a value of 1, it does what it should which is paint the ring RED. But If I enter the 9, it does nothing but the serial println prints out. It has to do with the If Serial available line, because if I comment that out, the ring lights up. Any thoughts??? I really just want the code to "interupt" when serial data arrives, read it in, and start the whole loop over again, sounds easy :slight_smile: LOL thanks in advance!

Note: This uses a Adafruit NeoPixel ring, which is the reason for the NeoPixel library naturally

#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

#define PIN 6	// connected to NeoPixel ring

/* 	Parameter 1 = number of pixels in strip
 		Parameter 2 = Arduino pin number (most are valid)
		Parameter 3 = pixel type flags, add together as needed:
	  	NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
   		NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
	   	NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
   		NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
*/

Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

/* IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
	 pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
	 and minimize distance between Arduino and first pixel.  Avoid connecting
	 on a live circuit...if you must, connect GND first.
*/

//**********SETUP FUNCTION***************************************
void setup() {
  Serial.begin(9600);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

// *******************LOOP FUNCTION********************************
void loop() {

  if (Serial.available() > 0) {  // If serial data is present
     start:  // GOTO label
     int inByte = Serial.read();  // read it in (will only be one byte for this POC)
  		  
				  
    if(inByte=='1') {
      Serial.println("Case statement 1 Colorwipe Red executed");
      for(uint16_t i=0; i<strip.numPixels(); i++) {
        strip.setPixelColor(i, 255,0,0);
        strip.show();
        delay(50);
      }
    } // end inByte 1 IF statement
    
    if(inByte=='9') {
      Serial.println("Case statement 9 RainbowCycle executed");	  
      for(uint16_t j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
        for(uint16_t i=0; i< strip.numPixels(); i++) {
          if(Serial.peek() !=-1) {goto start;}  // if serial data is NOT present then continue else goto
          strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));          
        }  // end i loop        
        strip.show();
        delay(20);
      } // end j loop
    }  // end inByte 9 IF statement
   } // end Serial IF statement
}  // End LOOP



// **********************UINT32 FUNCTION********************************
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}

Get rid of all the stupid loops! Take a look at this Demonstration code for several things at the same time - Project Guidance - Arduino Forum.

Mark

Get rid of the GOTO!

There's nothing you can do with GOTO that you can't do without it, and your code will be much easier to understand and maintain than it would have been using goto.

so while I appreciate the feedback, I'm really looking for some help rather than people just saying to get rid of the goto. If getting rid of the goto in fact does the trick, I'm all for it, but then what would my code look like?

Also in regards to the if statements and replacing them with switches, its all relative. Its just another way of looking at loops IMO, but that isnt the topic here at hand.

Ideally I just need a way to interupt the code and move back to the top of the main LOOP. Any help is accomplishing this is appreciated, thanks!!!

Again - Get rid of the for loop and read the link you where given.

Mark

but then what would my code look like?

Better, cleaner, easier to debug and for others to read.

As well as using the approach in several things at a time which you have already been given a link to, it would probably also be a good idea to use one of the examples in serial input basics for receiving the data. They are simple, reliable and non-blocking.

You may also find some useful ideas in planning and implementing a program.

...R

To get rid of the goto, change this:

 if (Serial.available() > 0) {  // If serial data is present
     start:  // GOTO label

to this:

 while (Serial.available() > 0) {  // while serial data is present

and change this:

         if(Serial.peek() !=-1) {goto start;}  // if serial data is NOT present then continue else goto

to this:

         if(Serial.available() > 0) continue;  //if serial data is present go get it, otherwise proceed with the display

Pete