Count numbers from an array with a button press

Hello!
So I am using a 7pin LED to show a series of numbers.
As a smaller part of a larger project I am trying to figure out how to have these numbers count down during a button press but when the button is released the display blinks the current digit.

This is one of my attempts at the coding. As you can see when the button is pressed it is trapped inside of a for loop that proceeds with the counting, but it does not detect the button in this loop.

Hopefully somebody can help or nudge me in the proper direction.

Thank you.

Attached is the code I have.

/*
 *  Switch and LED program
 */

int pinA = 13; 
int pinB = 12;    
int pinC = 11;             
int pinD = 10;
int pinE = 9;
int pinF = 8;
int pinG = 7;
int pinDP = 6;
int switchpin = 5;
int val;

// Fill missing rows
int digits[10][7] = {{0,0,0,0,0,0,1},
                    {1,0,0,1,1,1,1},
                    {0,0,1,0,0,1,0},
                    {0,0,0,0,1,1,0},
                    {1,0,0,1,1,0,0},
                    {0,1,0,0,1,0,0},
                    {0,1,0,0,0,0,0},
                    {0,0,0,1,1,1,1},
                    {0,0,0,0,0,0,0},
                    {0,0,0,1,1,0,0},
                    };

void setup() {
  Serial.begin(9600);
  // Set all pins as output
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  pinMode(pinC, OUTPUT);
  pinMode(pinD, OUTPUT);
  pinMode(pinE, OUTPUT);
  pinMode(pinF, OUTPUT);
  pinMode(pinG, OUTPUT);
  pinMode(pinDP, OUTPUT);
  pinMode(switchpin, INPUT);
  // Set all pins to high to turn off all segments
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, HIGH);
  digitalWrite(pinF, HIGH);
  digitalWrite(pinG, HIGH);
  digitalWrite(pinDP, HIGH);
 }

void loop(){
  int blank[1][7] = {{1,1,1,1,1,1,1}}; //create a blink in the LED
  int i;
  val = digitalRead(switchpin);
  
  if (val== HIGH);{
    
  for (i=0; i<9 ; i++) {  // fill for loop limit
    showDigit(digits[i]);   // fill array index with student number
    delay(1000);             // fill time delay
    showDigit(blank[0]); //blink
    delay(1000);
  }
  if (val == LOW) { //check if button is pressed
    showDigit(digits[i]);   // fill array index with student number
    delay(1000);             // fill time delay
    showDigit(blank[0]); //blink
    delay(1000);
  }

  }
}

// This function uses an array of 7 1's and 0's to turn LEDs ON/OFF
void showDigit(int signals[]) {
  // Set all pins levels & fill missing parts
  digitalWrite(pinA, signals[0]);
  digitalWrite(pinB, signals[1]);
  digitalWrite(pinC, signals[2]);
  digitalWrite(pinD, signals[3]);
  digitalWrite(pinE, signals[4]);
  digitalWrite(pinF, signals[5]);
  digitalWrite(pinG, signals[6]);
}

NumberbuttonTEST.ino (2.12 KB)

 if (val== HIGH);{

An if statement will run conditionally the next statement after it. That can be a single line of code or is can be a block of code between { and }. In your case it is the single empty line of code denoted by the ; there. So this says, if (val == HIGH) then do nothing. The block behind that is run unconditionally and is not under the control of the if statement.

Moral: if statements don't get semicolons.

If you want to check the button inside the for loop, then write a line with digitalWrite to check it in there and an if statement to sue break to end the loop if you want.

Personally, I wouldn't use a for loop at all. The loop function is already looping. So you can just let it increment the variable one time, show it if needed, and loop back around to check the button.

To start with, you could save a lot of memory by switching to an array of bytes for your digits. Not a huge deal now but it's good to get into the habit before you start working on larger programs. You've got an array with 70 int's in it, that's 140 bytes of memory. You could do the same thing with an array of 10 bytes, which is of course 10 bytes of memory.

const byte myByteArray[10] = {  B00111111, //Digit_0
                                B00000110, //Digit_1
                                B01011011, //Digit_2
                                B01001111, //Digit_3
                                B01100110, //Digit_4
                                B01101101, //Digit_5
                                B01111101, //Digit_6
                                B00000111, //Digit_7
                                B01111111, //Digit_8
                                B01101111 }; //Digit_9

The B in front of the group of 1s & 0s denotes that you're writing a binary number. You don't specifically need to write them as binary numbers but it can help you visualize which LED Segments are On/Off. Note: the binary number reads from right to left. Here's what LED segments they'll control:

 .GFEDCBA
B00110011

To work with the invidual bits familiarize yourself with the arduino functions: bitRead(x, n); bitSet(x, n); bitClear(x, n);

For now all you'll need is bitRead(variableToRead, bitToRead); Here's how you would turn on/off the pins for what I'm referring to as Digit_0 in myByteArray above:

Note: My 7 segment LED display needs pins set high to turn things on. If yours is different then just flip all the 1s & 0s I typed for all the values in myByteArray

digitalWrite(pinA, bitRead(myByteArray[0], 0) );
digitalWrite(pinB, bitRead(myByteArray[0], 1) );
digitalWrite(pinC, bitRead(myByteArray[0], 2) );
digitalWrite(pinD, bitRead(myByteArray[0], 3) );
digitalWrite(pinE, bitRead(myByteArray[0], 4) );
digitalWrite(pinF, bitRead(myByteArray[0], 5) );
digitalWrite(pinG, bitRead(myByteArray[0], 6) );
digitalWrite(pinDP, bitRead(myByteArray[0], 7) );

Now next up let's address your switch. Switches do weird things if they aren't pulled up, or pulled down by a resistor. You'll basically get random on/off's that make no sense and will drive you insane. Easiest way to deal with this is use the internal pullup resistors built into your arduino. Set the mode of switchpin to INPUT_PULLUP. What this does is pull your button up to HIGH when it isn't pressed. Now connect one wire of your button to the pin, and another wire from your button to Ground (GND). When you push the button the pin will get pulled LOW.

It might be slightly confusing at first that LOW means it's pushed, and HIGH means it isn't pushed but you'll get used to it. You can also use ! to get the inverse of something if that helps things make more sense.

pinMode(switchpin, INPUT_PULLUP);

val = !digitalRead(switchpin); //If switchpin is LOW (pressed), val = HIGH. If switchpin is HIGH (not pressed), val = LOW

DeltaG already mentioned the problems with your for loop.