No Response from Hardware (Hardware not Broken)

Hi,

I’ve very recently got into coding and am doing a piece of it for my college project. I have attached an Adafruit Neo_Pixel Shield to an Arduino Uno and want the LEDs to flash the SOS sequence when the button is pushed, and to stop the sequence when the button is pushed a second time.

For some reason unknown to me, the hardware shows absolutely no sign of working when the button is pressed however I know that its the software incorrect as I’ve loaded other pieces of code onto it that are correct and it works just fine. The code I’m uploading is as follows:

#include <Adafruit_NeoPixel.h> //includes NeoPixel Shield Library

#define PIXELS 6 //sets pin 6 as routing for Neo_Pixels in strip definition of Neopixels

#define NUM_PIX 40

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIX, PIXELS, NEO_RGB + NEO_KHZ800); //defines parameters of neopixel shield

boolean Latch = true; //sets the latch norm as true

const int ButtonPin = 9; //sets pin number 9 as the pushbutton pin

const int PixPin = 6; //sets pin number 6 as the neopixel pin

volatile int ButtonState = 0; //sets button state norm as 0 (LOW)

void setup() {

strip.begin();

strip.show(); //initialise all pins to OFF

strip.setBrightness(100); //sets pixel brightness as 100%

pinMode(ButtonPin,INPUT); //sets button pin as an input

pinMode(PixPin, OUTPUT); //sets pixel pin as an output

attachInterrupt(digitalPinToInterrupt(ButtonPin),pixOFF,RISING); //creates interrupt so that 2nd press of button will turn all pixels off

}

void loop() {

strip.begin();

strip.show();

ButtonState = digitalRead(ButtonPin); //reads the state of button value

if (ButtonState = HIGH) {

if (Latch = true)

Latch = false; //turns latch to OFF if button is pressed and latch is already ON

else

Latch = true; //turns latch to ON if button is pressed and latch is already OFF

}

if (Latch = true)

SOS_Signal(); //plays SOS loop if latch is ON

else

pixOFF(); //keeps pixels OFF if latch is OFF

}

void pixOFF(){

int pix;

for(pix=0; pix<40; pix++){

strip.setPixelColor(pix, 0, 0, 0); //reverts all pixels back to OFF

}

}

void pixON(){

int pix;

for(pix=0; pix<40; pix++){

strip.setPixelColor(pix, 255, 0, 0); //turns on every pixel

}

}

void SOS_Signal() {

int shortdelay=300; //one time unit in morse code

int longdelay=900; //three time units in morse code

pixON();

delay(shortdelay);

pixOFF();

delay(shortdelay);

pixON();

delay(shortdelay);

pixOFF();

delay(shortdelay);

pixON();

delay(shortdelay);

pixOFF();

delay(longdelay); //3 dots (S) and a space

pixON();

delay(longdelay);

pixOFF();

delay(shortdelay);

pixON();

delay(longdelay);

pixOFF();

delay(shortdelay);

pixON();

delay(longdelay);

pixOFF();

delay(longdelay); //3 dashes (O) and a space

pixON();

delay(shortdelay);

pixOFF();

delay(shortdelay);

pixON();

delay(shortdelay);

pixOFF();

delay(shortdelay);

pixON();

delay(shortdelay);

pixOFF();

delay(longdelay); //3 dots (S) and a space

strip.show();

}

It’s quite messy but please could anyone help with this as I don’t know where I’ve gone wrong at all!

Thanks a lot,

NoobCoderTom

A few things

  • use code tags when posting code so that indentation is maintained; it makes it easier to read

  • = is an assignment, == is a comparison so if (Latch = true) {} will set latch to true and then always do the if since true is true…

  • strip.begin() only needs to be executed once, so it should only be in setup(), not loop()

  • strip.show() needs to be called whenever you want changes to show up on the strips; the end of pixON() and pixOFF() is the right place.

  • Buttons bounce; when pressed or are released, the contacts open and close many times. Do a Google search for ‘ganssle debounce’ for more info and some code to handle this.

  • You are using a mix of interrupts and polling on the button; buttons tied directly to interrupt pins isn’t a good idea due to bouncing. Also, latch will misbehave if the button is held down. I would just use digital read and keep track of the previous state; if the current debounced state is different than the previous state, then either do pixOFF or SOS_Signal as appropriate.

This is some pseudocode:

uint8_t previousValue = 0; // button starts not being pressed
loop()
{
  static uint8_t buttonDebounce = 0;    // Used to debounce button.  Must be stable for 8 times through loop()
  static boolean isSecondPress = false; // Is this an odd or even time the button has been pressed.  Only pay attention to the even
  static boolean isPixelOff = true;     // Used to toggle the state of the LED strip

  buttonDebounce = (buttonDebounce << 1) | digital.read(,,,);
  if (buttonDebounce == 0xFF)
  {
    if (previousValue == 0x00)
    {
      // button is pressed, but it wasn't last time
      previousValue = 0xFF;
      if (isSecondPress == false)
      {
         // Only do things on every other press of the button
         isSecondPress = true;
         // Alternate the LEDs - either off or SOS
         if (isPixelOff)
         {
           isPixelOff = false;
           SOS_Signal();
         }
         else
         {
           isPixelOff = true;
           pixOff();
         }
      }
      else isSecondPress = false;
    }
  }
  else if (buttonDebounce == 0x00)
    previousValue = 0x00; // Button has been released
}

/mike

Also, your button will need an external pulldown resistor. Alternately, you can use the internal pullup and modify your program so that it is active low instead of high.

Hi mike,

Thanks for getting back to me, I’ve moved a few things about and got it to work on the button press. Thanks a lot for your help!

Tom