I'm using a Mega to be an LED Strip controller and I'm trying to use the switch case to cycle through various visual outputs for the LED Strip. The problem I'm running into is that the variable used to count the number of button presses, 'visual', updates fine when the 'Visualize()' isn't included in the loop and only the 'CycleVisual();' is included. Once I add the 'Visualize()' the 'visual' only registers one increment and then doesn't update in the Serial Monitor of any more button presses. I want to assume the logic used in 'CycleVisual();' is ill-suited for 'Visualize();', but I'm lost after a couple of days of trying to figure out the problem. A schematic of the board is included above the code. Please disregard the pot and sound module since I want to include the usage of those after I figure out how to cycle through visuals that don't require sound input for now. Thank you for your time!
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define LED_PIN A5 //Pin for the pixel strand. Can be analog or digital.
#define LED_TOTAL 300 //Change this to the number of LEDs in your strand.
#define LED_HALF LED_TOTAL/2
#define VISUALS 2 //Change this accordingly if you add/remove a visual in the switch-case in Visualize()
#define BUTTON_1 6
Adafruit_NeoPixel strand = Adafruit_NeoPixel(LED_TOTAL, LED_PIN, NEO_GRB + NEO_KHZ800); //LED strand objetcs
uint8_t visual = 0;
void setup() {
Serial.begin(9600);
pinMode(BUTTON_1, INPUT);
digitalWrite(BUTTON_1, HIGH);
strand.begin();
strand.show();
}
void loop() {
Serial.println(visual);
CycleVisual();
delay(10);
}
void CycleVisual() {
if (digitalRead( BUTTON_1 ) == LOW ) {
visual++;
if (visual > VISUALS) visual = 0;
delay(350);
}
}
void Visualize(){
switch (visual) {
case 0: return Sparkle(0xff, 0xff, 0xff, 50);
break;
case 1: return BouncingBalls(0xff, 0xff, 0xff, 5);
break;
case 2: return RunningLights(23, 43, 0, 50);
break;
default: Sparkle(0xff, 0xff, 0xff, 50);
}
}
void showstrand() {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strand.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
FastLED.show();
#endif
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strand.setPixelColor(Pixel, strand.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
#endif
}
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < LED_TOTAL; i++ ) {
setPixel(i, red, green, blue);
}
strand.show();
}
void Sparkle(byte red, byte green, byte blue, int SpeedDelay) {
int Pixel = random(LED_TOTAL);
setPixel(Pixel,red,green,blue);
strand.show();
delay(SpeedDelay);
setPixel(Pixel,0,0,0);
digitalWrite(BUTTON_1, HIGH);
}
void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
int Position=0;
for(int j=0; j<LED_TOTAL*2; j++)
{
Position++; // = 0; //Position + Rate;
for(int i=0; i<LED_TOTAL; i++) {
// sine wave, 3 offset waves make a rainbow!
//float level = sin(i+Position) * 127 + 128;
//setPixel(i,level,0,0);
//float level = sin(i+Position) * 127 + 128;
setPixel(i,((sin(i+Position) * 127 + 128)/255)*red,
((sin(i+Position) * 127 + 128)/255)*green,
((sin(i+Position) * 127 + 128)/255)*blue);
}
strand.show();
delay(WaveDelay);
}
}
void BouncingBalls(byte red, byte green, byte blue, int BallCount) {
float Gravity = -9.81;
int StartHeight = 1;
float Height[BallCount];
float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight );
float ImpactVelocity[BallCount];
float TimeSinceLastBounce[BallCount];
int Position[BallCount];
long ClockTimeSinceLastBounce[BallCount];
float Dampening[BallCount];
for (int i = 0 ; i < BallCount ; i++) {
ClockTimeSinceLastBounce[i] = millis();
Height[i] = StartHeight;
Position[i] = 0;
ImpactVelocity[i] = ImpactVelocityStart;
TimeSinceLastBounce[i] = 0;
Dampening[i] = 0.90 - float(i)/pow(BallCount,2);
}
while (true) {
for (int i = 0 ; i < BallCount ; i++) {
TimeSinceLastBounce[i] = millis() - ClockTimeSinceLastBounce[i];
Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i]/1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i]/1000;
if ( Height[i] < 0 ) {
Height[i] = 0;
ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
ClockTimeSinceLastBounce[i] = millis();
if ( ImpactVelocity[i] < 0.01 ) {
ImpactVelocity[i] = ImpactVelocityStart;
}
}
Position[i] = round( Height[i] * (LED_TOTAL - 1) / StartHeight);
}
for (int i = 0 ; i < BallCount ; i++) {
setPixel(Position[i],red,green,blue);
}
digitalWrite(BUTTON_1, HIGH);
strand.show();
setAll(0,0,0);
}
}
