If 2 sensors triggered at same time, one is cancelled

Greetings,

My project consists of the following:
1 Arduino mega
ws2812 lights
1 limit switch
1 vibration sensor

Currently, I have successfully put together the circuit and programmed for the following:

When the limit switch is triggered, a light animation is triggered. When the vibration sensor is triggered, a different light animation is triggered.

Where I am having trouble is when the vibration sensor is triggered but shortly after the limit switch is triggered - the vibration sensor light animation still plays. I have the correct code, but doing some research it doesn't look like the Arduino can do what I am trying to accomplish.

Can an expert chime in on this one? Would this be something that only a Raspberry PI could tackle?

Thank you!

I doubt that.

void loop() {
int val;
val=digitalRead(vib_pin);
limitSwitch.loop(); // MUST call the loop() function first

if(limitSwitch.isPressed())
Strobe(0xff, 0xff, 0xff, 5, 10, 50);

if(val==1)
CylonBounce(0xff, 0, 0, 4, 2, 5);

if((limitSwitch.isPressed()) && (val==1))
Strobe(0xff, 0xff, 0xff, 5, 10, 50);

So this part of the code - " if((limitSwitch.isPressed()) && (val==1))
Strobe(0xff, 0xff, 0xff, 5, 10, 50); "

What would it need to be then? Because the lines before it work fine.

Could you please post your entire code in code tags, per forum guidelines.

1 Like

It appears you have a messed up hardware setup assuming as you say the code is correct which would surprise me. How do you knowthat? Post a schematic, not a frizzy diagram as how you have wired it.

You failed to explain in detail WHAT you are trying to accomplish, so we can't help much.

Your problem is that while the "vibration sensor light animation" (CylonBounce(0xff, 0, 0, 4, 2, 5);) is playing, you aren't able to check the limit switch. Also, while the limit switch light animation (Strobe(0xff, 0xff, 0xff, 5, 10, 50);) is playing you aren't able to check the vibration sensor.

If you want one trigger to override the other you will need to make your "light animations" non-blocking. We can help with that if you show your code.

John,

Thank you so much for the helpful response. I actually found the post where you helped articulate a very similar issue. I am going to try to implement your suggestions from that post - Using an interrupt in code

Great job on that one. I've already modified the code for the Cylon animation, and it compiled successfully.

I will try it out later today on the lights and see if it works.

If I need any help, I will reach back out to you.

Thank you again. You have a good presence on this forum.

  • Sean

John,

I just tried it out, and the limitswitch animation (Strobe) is not overriding the vibration animation (Cylon). Please see the code below:

#include <Adafruit_NeoPixel.h>
#include <ezButton.h>
#define PIN 52
#define NUM_LEDS 30
// 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);
ezButton limitSwitch(7);  // create ezButton object that attach to pin 7;
int vib_pin=3;

void setup() {
  Serial.begin(9600);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  limitSwitch.setDebounceTime(50); // set debounce time to 50 milliseconds
  pinMode(vib_pin,INPUT);
}

void loop() {
  int val;
  val=digitalRead(vib_pin);
  limitSwitch.loop(); // MUST call the loop() function first
  

  if(limitSwitch.isPressed())
    Strobe(0xff, 0xff, 0xff, 5, 50, 500);

   if(val==1) 
   CylonBounce(0xff, 0, 0, 4, 50, 100);
   

//Anything below this is just declaring the LED animations.  So this would be a kind of bottom up coding approach//
    
}

//Strobe code
void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause){
  for(int j = 0; j < StrobeCount; j++) {
    setAll(red,green,blue);
    showStrip();
    delay(FlashDelay);
    setAll(0,0,0);
    showStrip();
    delay(FlashDelay);
  }
 
 delay(EndPause);

}

//Cylon Code//
void CylonBounce(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay){

  for(int i = 0; i < NUM_LEDS-EyeSize-2; i++) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();

    if(limitSwitch.isPressed())
      return;
      
    delay(SpeedDelay);
  }

  delay(ReturnDelay);

  for(int i = NUM_LEDS-EyeSize-2; i > 0; i--) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }
 
  delay(ReturnDelay);

}

//Rest of code for LEDS//
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();


  
}
 

You will notice in the Cylon code, I put "if limitswitch is pressed; return" - similar to the code you recommended in your other posts.

Any help is much appreciated.

Thank you!

Look like you left out this line:
limitSwitch.loop(); // MUST call the loop() function first
before:

    if(limitSwitch.isPressed())
      return;

There might be a problem calling limitSwitch.loop() in CylonBounce() depending on how the ezButton object works. Does .isPressed() return true only once each time the button is pressed? That would mean the CylonBounce() would exit but Strobe() would not start until the next time the button was pressed.

John,

Thank you for pointing that out. I decided to go a simpler route to eliminate the limitSwitch.loop() out of the problem. Looks like the ezbutton module was making things complicated

#include <Adafruit_NeoPixel.h>
#define PIN 52
#define NUM_LEDS 30
#define LIMIT_SWITCH_PIN 10
// 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);
int vib_pin=3;

void setup() {
  Serial.begin(9600);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  
  pinMode(vib_pin,INPUT);
  pinMode(LIMIT_SWITCH_PIN, INPUT);
}

void loop() {
  int val;
  val=digitalRead(vib_pin);
  

  if(digitalRead(LIMIT_SWITCH_PIN)== HIGH)
    Strobe(0xff, 0xff, 0xff, 5, 50, 500);

   if(val==1) 
   CylonBounce(0xff, 0, 0, 4, 50, 100);
   

//Anything below this is just declaring the LED animations.  So this would be a kind of bottom up coding approach//
    
}

//Strobe code
void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause){
  for(int j = 0; j < StrobeCount; j++) {
    setAll(red,green,blue);
    showStrip();
    delay(FlashDelay);
    setAll(0,0,0);
    showStrip();
    delay(FlashDelay);
  }
 
 delay(EndPause);

}

//Cylon Code//
void CylonBounce(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay){

  for(int i = 0; i < NUM_LEDS-EyeSize-2; i++) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();

    if(digitalRead(LIMIT_SWITCH_PIN)== HIGH)
      return;
      
    delay(SpeedDelay);
  }

  delay(ReturnDelay);

  for(int i = NUM_LEDS-EyeSize-2; i > 0; i--) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }
 
  delay(ReturnDelay);

}

//Rest of code for LEDS//
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();


  
}


Note that instead of ezbutton module and limitSwitch.loop, I simply declared pinMode(LIMIT_SWITCH_PIN)

However, the limit switch is still not overriding the Cylon animation. 

Thank you again, sir

John,

Actually, it's working.

Thank you so much for your help. I may circle back for some fine-tuning later on. I will also refer to the other thread as well.

You are amazing. Have a great holiday weekend.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.