Adafruit M0 Express LED walking stick

I’m having issues with my code. I’m trying to build a walking stick with Adafruit NeoPixel led strips and rings. which has multiple options for animation. I have it compiling and loading and can get most of the animations to work, but I cannot figure out how to get the animations to switch when I push a button. I’m trying to use If statements to switch between modes, but when it boots it only loads the first animation which is just white lights. My code follows. Thanks in advance.

#include <Adafruit_NeoPixel.h>
#include <Adafruit_ZeroDMA.h>
//#include <Adafruit_NeoPXL8.h>

#if defined (ARDUINO_SAMD_ZERO)  && defined(SERIAL_PORT_USBVIRTUAL)
//  Required for Serial on Zero based boards
//#define Serial SERIAL_PORT_USBVIRTUAL
#endif

#define NUM_LEDS 39

//Button Color definitions
int Strip1Pin = 5;
int Strip2Pin = 6;
int RingPin = 9;
int RedPin = 10;
int GreenPin = 11;
int BluePin = 12;
int PowerPin = 3;
int ButtonPin = 13;

int Strip1Count = NUM_LEDS;
int Strip2Count = NUM_LEDS;
int RingCount = 23;

int redValue;
int greenValue;
int blueValue;

int ButtonState = 0;
int LEDState = LOW;
int Reading;

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
int lastButtonState = LOW;   // the previous reading from the input pin

// Parameter 1 = number of pixels in strip
// Parameter 2 = 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)

//int8_t pins[8] = { PIN_SERIAL1_RX, PIN_SERIAL1_TX, MISO, 13, 5, SDA, A4, A3 };  //Used for Feather M0
//int8_t pins[8] = { 13, 12, 11, 10, SCK, 5, 9, 6 };  //Used for Feather M4

Adafruit_NeoPixel Strip1(Strip1Count, Strip1Pin, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel Strip2(Strip2Count, Strip2Pin, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel Ring(RingCount, RingPin, NEO_GRB + NEO_KHZ800);

typedef enum {
MODE_IDLE,
MODE_OOZING,
MODE_DRIBBLING_1,
MODE_DRIBBLING_2,
MODE_DRIPPING
} dropState;

struct {
uint16_t  length;            // Length of NeoPixel strip IN PIXELS
uint16_t  dribblePixel;      // Index of pixel where dribble pauses before drop (0 to length-1)
float     height;            // Height IN METERS of dribblePixel above ground
dropState mode;              // One of the above states (MODE_IDLE, etc.)
uint32_t  eventStartUsec;    // Starting time of current event
uint32_t  eventDurationUsec; // Duration of current event, in microseconds
float     eventDurationReal; // Duration of current event, in seconds (float)
uint32_t  splatStartUsec;    // Starting time of most recent "splat"
uint32_t  splatDurationUsec; // Fade duration of splat
float     pos;               // Position of drip on prior frame
} drip[] = {
// THIS TABLE CONTAINS INFO FOR UP TO 8 NEOPIXEL DRIPS
{ 39,  3, 1 }, // NeoPXL8 output 0 - Leg 1: 16 pixels long, drip pauses at index 7, 0.157 meters above ground
{ 39,  3, 1 }, // NeoPXL8 output 1 - Leg 2: 19 pixels long, pause at index 6, 0.174 meters up
{ 23,  30, 0.195 }, // NeoPXL8 output 2 - Head: etc.
{ 1,  0,  0 }, // NeoPXL8 output 3 - Button Red
{ 1,  0,  0 }, // NeoPXL8 output 4 - Button Blue
{ 1,  0,  0 }, // NeoPXL8 output 5 - Button Green
{ 0,  0,  0 }, // NeoPXL8 output 6
// NeoPXL8 output 7 is normally reserved for ground splats
// You CAN add an eighth drip here, but then will not get splats
};

#define N_DRIPS   (sizeof drip / sizeof drip[0])
int longestStrand = (N_DRIPS < 3) ? N_DRIPS : 0;
//Adafruit_NeoPXL8 *pixels;

void setup() {
pinMode(PowerPin, INPUT_PULLUP);
pinMode(ButtonPin, INPUT);

pinMode(Strip1Pin, OUTPUT);
pinMode(Strip2Pin, OUTPUT);
pinMode(RingPin, OUTPUT);
pinMode(RedPin, OUTPUT);
pinMode(GreenPin, OUTPUT);
pinMode(BluePin, OUTPUT);

digitalWrite(Strip1Pin, LOW);
digitalWrite(Strip2Pin, LOW);
digitalWrite(RingPin, LOW);
digitalWrite(RedPin, LOW);
digitalWrite(GreenPin, LOW);
digitalWrite(BluePin, LOW);

Serial.begin(9600);
randomSeed(analogRead(A0) + analogRead(A5));

Strip1.begin();
Strip2.begin();
Ring.begin();

int Brightness = 25;

Strip1.setBrightness(Brightness);
Strip2.setBrightness(Brightness);
Ring.setBrightness(Brightness);

Strip1.show();
Strip2.show();
Ring.show();  // Initialize all pixels to 'off'

for (int i = 0; i < N_DRIPS; i++) {
  drip[i].mode              = MODE_IDLE; // Start all drips in idle mode
  drip[i].eventStartUsec    = 0;
  drip[i].eventDurationUsec = random(500000, 2500000); // Initial idle 0.5-2.5 sec
  drip[i].eventDurationReal = (float)drip[i].eventDurationUsec / 1000000.0;
  drip[i].splatStartUsec    = 0;
  drip[i].splatDurationUsec = 0;
  if (drip[i].length > longestStrand) longestStrand = drip[i].length;
}
}

void loop() {
Reading = digitalRead(ButtonPin);
if (ButtonState == HIGH) {
  LEDState = LEDState + 1;
}
if (LEDState == 0) {
  Light();
}
else if (LEDState == 1) {
  Fire(55, 120, 15);
}
else if (LEDState == 2) {
  Rain();
}
else if (LEDState == 3) {
  USA();
}
else {
  LEDState = 0;
}
}

Please go to File → Preferences and make sure Compiler Warnings are set to ALL.

I am fairly certain it would tell you that you are setting Reading at the beginning of loop, but you don’t do anything with it. Sometimes you can ignore compiler warnings, but they will often tell you issues that you should look at. You will need to learn to figure out what you can ignore. :slight_smile: We will help you with that.

Additionally, remember loop repeats all the time and it can repeat many thousands of times a second. So, just testing for ButtonState == HIGH will trigger an increment extremely fast.

Some additional hints.

  • Please read the “How to post …” at the beginning of each sub forum. It will give you good tips for posting question. For instance
  • Please use code tags. Your code should look like this. (Try to modify your post)
Your code
  • Remove code that is not necessary for showing your issue or that is not functional because you commented it out.
  • Post code that can compile
  • provide schematic (hand drawn picture taken by phone is OK)
  • provide links to non-Arduino components datasheets

Thank you for the quick response.

I changed the Reading variable to ButtonState and it is switching between two of the four modes.

Do you want me to post the verbose compile in a reply?

dugoon:
Do you want me to post the verbose compile in a reply?

Warnings from code that you did not write, you can mostly ignore for a first round. Try to see which warnings are about your source and then use Google first to figure out what they might mean. If you cannot figure it out by yourself, we can have a look. But my goal is to help you catch the fish yourself. :slight_smile:

Next, add some code to help you figure out what is going on. It is called printf debugging. e.g. print your LEDState variable.

LEDState = LEDState + 1;
Serial.print("LS: ");
Serial.println(LEDState);

Open the Serial Monitor and see what happens.