Push Button State Change

Hello all!

I am creating a laser timing gate for my research lab (fairly new to arduino) and am running into some issues regarding a push button and having excess current. The comments should explain well but the idea is to have a laser timing gate that pings a visual stimulus when the laser is broken. The direction of the stimulus is determined by the switch-case loop.

I am trying to add a push button that will decrement the run value by 1, however, if I even lightly tap the push button the serial monitor shows that the RunValue is all over the place. Any advice? Here’s my full code, thanks.

/*
 
This code is for use with a Light Dependent Resistor as a second device of a timing gate
for UC Health Motion Capture Lab under Dr. Kate Worster. 

This portion of the gate will receive a signal from Gate 1 via an LDR, and signal 
what direction an LED matrix will signal a runner to go. 

This device should be able to output serial monitor data to a MATLAB plot, 
as well as send a 5V pulse to a vicon monitor to be labeled as a general GAIT event
in the Nexus software. 

created 10 Feb 2020
by Gary J Schneider

*/

////////////////////////////Libraries for LED Matrix/////////////////////////////////////////////////////

#include "Adafruit_GFX.h"
#include "Adafruit_HT1632.h"



/////////////////////////////Assign Pins////////////////////////////////////////////////////////////////

const int ledPin1 = 5; // green led pin(5)
const int ledPin2= 6; // red led pin(6)
int photo = A0; // photoresistor pin(A0)
int x = 1; // initial value for x
int i; //creates integer for counter named "i" 
int buttonPin = 7; //declare pin number for pushbutton to pin 7
boolean on=false;
int buttonState = 0;



//////////////////////////////LED Display Pins//////////////////////////////////////////////////////////

#define HT_DATA 2 
#define HT_WR 3
#define HT_CS 4
#define BACKCOLOR 0xF800 // LED matrix color is set to red

Adafruit_HT1632LEDMatrix matrix = Adafruit_HT1632LEDMatrix(HT_DATA, HT_WR, HT_CS);
//creates variable matrix



//////////////////////////////Functions and definitions///////////////////////////////////////////////////////////

void right() //Parameters set for LED to display triangle pointing right
    {
    digitalWrite(ledPin1, LOW); // turn green led off
    digitalWrite(ledPin2, HIGH); // turn red led on
    matrix.fillTriangle(4, 0, 4, 15, 22, 8, BACKCOLOR); //Creates right pointing triangle
    matrix.writeScreen(); //clears LED matrix screen
    delay(1000); //Delay the clearing of the screen so runner has time to read
    }

      
void left() //Parameters set for LED to display triangle pointing left 
    { 
    digitalWrite(ledPin1, LOW); // turn green led off
    digitalWrite(ledPin2, HIGH); // turn red led on       
    matrix.fillTriangle(20, 0, 20, 15, 1, 8, BACKCOLOR); //Creates right pointing triangle
    matrix.writeScreen(); //clears LED matrix screen
    delay(1500); //Delay the clearing of the screen so runner has time to read
    }

   
void lasertact() //If beam is in tact, turn on green LED and clear screen
    {
    digitalWrite(ledPin1, HIGH); // turn green led on
    digitalWrite(ledPin2, LOW); // turn red led off
    matrix.clearScreen(); //clears LED matrix screen
    }
    

void homebound() //function to display"ALL DONE!" on LED Matrix with letters 8 pixels high
    {
    digitalWrite(ledPin1, LOW); // turn green led off
    digitalWrite(ledPin2, HIGH); // turn red led on
    matrix.setTextSize(1);    // size 1 == 8 pixels high
    matrix.setTextColor(1);   // 'lit' LEDs
    matrix.setTextWrap(true); 
    matrix.setCursor(0, 0);   // start at top left, with one pixel of spacing
    matrix.print("YOU DONE!"); //Displays "YOU DONE!" 
    matrix.writeScreen();
    delay(4000);
    }




/////////////////////////////////Set Up/////////////////////////////////////////////////////////////////////
/*
Begin serial monitoring of the photoresistor, ensure the LED's are set
to output. Will provide the users a notifcation of power on through a single
flash of the LED panel that will occur when turned on.
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() 
{
  //LED and Photoresistor setup
  Serial.begin(9600); //serial rate set to 9600
  pinMode(ledPin1, OUTPUT); //set green LED to output
  pinMode(ledPin2, OUTPUT); //set red LED to output
  pinMode(photo, INPUT); //set photoresistor to input source
  pinMode(buttonPin, INPUT);//set button as input
  
  //LED Matrix setup
  matrix.begin(ADA_HT1632_COMMON_16NMOS); //start the LED matrix 
  matrix.fillScreen(); //Tell LED Matrix to turn on all lights at initialization as a start up sign
  delay(1000); //delay time on screen
  matrix.clearScreen(); //clear screen before loop begins 
  
}




//////////////////////////////////Loop/////////////////////////////////////////////////////////////////////

void loop() 
{
  
  x = analogRead(photo); // Serial monitor to read photoresistor data and display
  Serial.print("Reading: "); //print "reading" in serial monitor before number
  Serial.println(x); //print the x value given from the photoresistor on the same line after "reading" 
  Serial.print("\t");  
  Serial.print(i); //print "i" value next to serial monitor data to track switch-case postion
  int runValue = i; //sets the run value of switch-case to the value of the counter "i"
  buttonState = digitalRead(buttonPin);


  if (buttonState == HIGH) {
     i = i - 1;
     delay(50);
    }

   if (i < 0) {
      i = abs(i);  
      delay(50);
    }
  
////////////////////////////////Switch-Case////////////////////////////////////////////////////////////////
/* 
 *  This switch-case loops runs the arduino through 8 direction changes to be displayed on the LED matrix.
 *  This occurs by calling a direction function named either "left" or "right"
 *  Each case should increment the counter number "i" by 1 after each trial to move up the case ladder.
 *  At case 8, LED Matrix will display "all done" from the homebound function. 
 *  Once case 9 is reached, the counter will return to "0" and go back to case 0. 
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////

  if (x < 600)// if link between laser and photoresistor is broken, run through this switch-case loop. 
    {
      switch (runValue) {
     case 0: left();
                for (i == 0; i<1; ++i);
            break;
        case 1: right();
                for (i == 0; i<2; ++i);
            break;
        case 2: right();
                for (i == 0; i<3; ++i);
            break; 
        case 3: left();
                for (i == 0; i<4; ++i);
            break;
        case 4: right();
                for (i == 0; i<5; ++i);
            break;
        case 5: left();
                for (i == 0; i<6; ++i);
            break;
        case 6: right();
                for (i == 0; i<7; ++i);
            break;
        case 7: left();
                for (i == 0; i<8; ++i); 
            break;
        case 8: homebound();
                for (i == 0; i<9; ++i); 
                break;
        case 9:
                for (i == 8; i = 0; i++);
        break;
      }
 
      }
     
    

    
  if (x > 600) //if condition of serial value is below 600, call function lasertact
    {
     lasertact(); //call the function "lasertact" 
    }

  }

You need to provide quite some more informatiion. What is the system setup? What's the real hardware, how is it positioned, how is it powered, how is it connected..?
Your description lacks a lot of basic info. Did You have a fire in Your pants when You sent Your question? Slow down.

I am trying to add a push button that will decrement the run value by 1, however, if I even lightly tap the push button the serial monitor shows that the RunValue is all over the place. Any advice?

How is the push button wired? Are you using any pullups or pulldowns on the input to prevent a floating pin?

The preferred way to wire a push button is to wire one side the the switch to an input pin set for INPUT_PULLUP pin mode and the other side of the switch to ground. The input will read HIGH when the button is not pressed and LOW when pressed.

Whatever else the issue may be, I don't think this will do what you think it will.

      case 9:
        for (i == 8; i = 0; i++);
        break;

During every delay() in that code the button is not read. The code between your delays runs in less than a millisecond and then the thing goes blind, deaf and dumb until the delay is over.

Want a responsive button? Use millis() to get rid of the delays and debounce the button without blocking the sketch.

Those delays to allow a runner to see something on a watch? So the runner has to keep an eye on a screen so often as every 4 and less seconds while running? Isn't that just a bit stupid? Runners like drivers should look where they are going, not develop semi-obsessive attention-reducing habits.