1

Good evening all,

I'm having an issue with a quick "test" project that I am tinkering with (learning the "do's" and "don'ts") the NeoPixel LED strip. I've been piecing together excerpts from other folks and so far everything is great.

I'm doing it over serial sending switch/case with numbers from the keyboard for different options. The issue I am currently having is "case 1:", when I hit the "1" key and it fires off, I want to be able to interrupt it immediately by using key "0". So basically, I'd like it to loop forever after hitting key "1" but terminate after hitting "0".

However, when hitting key "1", then key "0" immediately, the while loop repeats twice, then breaks. I haven't done any C/C++ since I was 12 and now I'm 38 so now it is all trial and error based so please pardon my syntax. Any help would be appreciated.

#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>

#define PIN 6
#define LEDs 16

int LED_Fade_Interval = 5;

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

void setup() {

  Serial.begin(9600);

  strip.begin();
  strip.show(); 

}

void loop() {

  while (Serial.available() == 0);

  int numKey = Serial.read() - '0';

  uint32_t low = strip.Color(0, 0, 0); 

  switch(numKey)
  {

    case 1:
      Serial.println("LED Strip is ON - BLUE FADE");  
      while (numKey != 0)
      {
        int numKey = Serial.read() - '0';
        delay(50);

        ws2812_FadeInOut(0, 0, 255, LED_Fade_Interval);

        if (numKey == 0)
        {

          for( int i = 0; i<LEDs; i++){
            strip.setPixelColor(i, low);
            strip.show();
          }

          break; 

        }

      }

    case 0:
      Serial.println("LED Strip is OFF");    
      for( int i = 0; i<LEDs; i++){
          strip.setPixelColor(i, low);
          strip.show();
      }
      break;
   }
}

// ******************************************* 
// FADER Function
// *******************************************
void ws2812_FadeInOut(uint8_t red, uint8_t green, uint8_t blue, uint8_t wait) {
  for(uint8_t b = 0; b <255; b++) {
     for(uint8_t i=0; i < strip.numPixels(); i++) {
        strip.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
     }

     strip.show();
     delay(wait);
  };

  for(uint8_t b=255; b > 0; b--) {
     for(uint8_t i = 0; i < strip.numPixels(); i++) {
        strip.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
     }
     strip.show();
     delay(wait);
  };
};
  • What you are doing is a Scheduler. You can look for already made solutions like jm_Scheduler: git.io/v1L0a – nico Nov 28 '16 at 16:28
1

Serial.read() reads one character from the Serial stream, or returns -1 if there are no characters to read.

When you send a 1 from the Serial Monitor, the Arduino board first receives an Ascii 1, and then receives a line-end character (eg, an LF from Linux) or characters (eg, a CR and LF from MSWindows).

Since none of 1, CR, or LF are equal to an Ascii 0, the numkey value computed at the fourth line of case 1 is not 0, so the exit condition isn't met. Thus the fade loop continues running, until it sees a 0 character.

Instead of continuing to read characters within while loops within the switch/case statement, test if more serial input is available. Note, avoid exiting early from case 1, after you read a digit at the beginning of loop(), read and discard the line-ending characters that follow.

1

NeoPixels' timing requirements are pretty tight - not necessarily high frequency but high accuracy, for at least certain parts of the serial pulse train. To achieve that, I believe the (Adafruit) NeoPixel library takes over one of the timers during the transmission and turns off interrupts for at least some of the time. That will have a negative impact on any background processes. Read through the NeoPixel library code; it should be clear.

However, while researching my answer (so as to not embarrass myself too badly!), I found this article at josh.com that describes driving NeoPixels with a much lower impact and goes on to demonstrate his technique with a video of a 1000 NeoPixel string(!) driven at 30 FPS by an old, apparently Atmega 168-based, Duemilanove.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.