Hi,
we are Olli and Devani and we are currently working on a mod for a Pinball machine.
What we want to happen is that the ball will trigger a switch that will then play a specific LED sequence that looks a bit like a wave. The speed of the wave can be set via a potentiometer.
We use the NeoPixel library and as a starting point we use this example, called "meteor rain":
So what is the actual problem?
We have a switch connected and it will trigger the sequence just fine. The problem is that in the game there is multiball mode that will give you 3 balls and you are supposed to hit the ramp (therefore the switch) three times in a relatively short time.
What we hope to do is that whenever the switch will be activated, it will also send another sequence on top of the running one. We managed to make it send a second "wave" by now which will interrupt the first one after it finished.
We tried a lot but we didn't manage to get a third wave. It will just not trigger, even though we do it exactly the same way we managed to make the second wave go. It's not the cleanest solution ever, but we managed to do so by checking for the switch state inside the meteorRain function, and calling for a second function (which is basically a copy from the first function). Yet, it won't work with a third function, and we don't get why.
We hope for some input from you guys. What we hope for is:
- We can activate 3 waves via button press
- Each wave will finish instead of being interrupted by the next one
Attached is a link to a video that shows you where we are at for now. I pressed the button again at the end of the first sequence to trigger the second one. For another round, we have to wait for the fading to go totally dark.
Video Example
Best regards from Germany,
Devani + Olli
#include <Adafruit_NeoPixel.h>
#define PIN 2
#define NUM_LEDS 95
#define Switch 4 //define input pin for switch
int val ;
int val2;
int potPin = A0;
int val3 = 0;
// 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)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
// strip.show(); // Initialize all pixels to 'off'
pinMode(Switch,INPUT_PULLUP);
val = 0;
val2 = 0;
}
void loop() {
val3 = analogRead(potPin) / 8;
while (digitalRead(Switch)==LOW){
delay(50);
val = 1;
}
if (val == 1 and val2 ==0){
meteorRain(0, 0, 255, 3, 280, true, 0);
val2 = 1;
}
setup();
}
void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
//setAll(0, 0, 0);
for (int i = 0; i < NUM_LEDS + NUM_LEDS; i++) {
// fade brightness all LEDs one step
for (int j = 0; j < NUM_LEDS; j++) {
if ( (!meteorRandomDecay) || (random(10) > 5) ) {
fadeToBlack(j, meteorTrailDecay );
}
if (digitalRead(Switch)==LOW){
delay(50);
meteorRain_2(0, 0, 255, 4, 280, true, 0);
setAll(0, 0, 0);
setup();
}
}
// draw meteor
for (int j = 0; j < meteorSize; j++) {
if ( ( i - j < NUM_LEDS) && (i - j >= 0) ) {
setPixel(i - j, red, green, blue);
strip.setPixelColor(i+1, strip.Color(30, 30, 255));
strip.setPixelColor(i+2, strip.Color(80, 80, 180));
strip.setPixelColor(i-3, strip.Color(60, 60, 200));
}
}
showStrip();
delay(val3);
}
setAll(0, 0, 0);
setup();
}
void meteorRain_2(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
//setAll(0, 0, 0);
for (int i = 0; i < NUM_LEDS + NUM_LEDS; i++) {
// fade brightness all LEDs one step
for (int j = 0; j < NUM_LEDS; j++) {
if ( (!meteorRandomDecay) || (random(10) > 5) ) {
fadeToBlack(j, meteorTrailDecay );
}
}
// draw meteor
for (int j = 0; j < meteorSize; j++) {
if ( ( i - j < NUM_LEDS) && (i - j >= 0) ) {
setPixel(i - j, red, green, blue);
strip.setPixelColor(i+1, strip.Color(30, 30, 255));
strip.setPixelColor(i+2, strip.Color(80, 80, 180));
strip.setPixelColor(i-3, strip.Color(60, 60, 200));
}
}
showStrip();
delay(val3);
}
setup();
}
void meteorRain_3(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
//setAll(0, 0, 0);
for (int i = 0; i < NUM_LEDS + NUM_LEDS; i++) {
// fade brightness all LEDs one step
for (int j = 0; j < NUM_LEDS; j++) {
if ( (!meteorRandomDecay) || (random(10) > 5) ) {
fadeToBlack(j, meteorTrailDecay );
}
}
// draw meteor
for (int j = 0; j < meteorSize; j++) {
if ( ( i - j < NUM_LEDS) && (i - j >= 0) ) {
setPixel(i - j, red, green, blue);
strip.setPixelColor(i+1, strip.Color(30, 30, 255));
strip.setPixelColor(i+2, strip.Color(80, 80, 180));
strip.setPixelColor(i-3, strip.Color(60, 60, 200));
}
}
showStrip();
delay(val3);
}
setup();
}
void fadeToBlack(int ledNo, byte fadeValue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
uint32_t oldColor;
uint8_t r, g, b;
int value;
oldColor = strip.getPixelColor(ledNo);
r = (oldColor & 0x00ff0000UL) >> 16;
g = (oldColor & 0x0000ff00UL) >> 8;
b = (oldColor & 0x000000ffUL);
r = (r <= 10) ? 0 : (int) r - (r * fadeValue / 256);
g = (g <= 10) ? 0 : (int) g - (g * fadeValue / 256);
b = (b <= 10) ? 0 : (int) b - (b * fadeValue / 256);
strip.setPixelColor(ledNo, r, g, b);
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[ledNo].fadeToBlackBy( fadeValue );
#endif
}
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.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
strip.setPixelColor(Pixel, strip.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 < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue);
}
showStrip();
}