Modifying 7-segment display code to allow a second button

Hey, guys! Super-new to Arduino, but I'm learning a lot by Googling, Youtubing and asking big-brains like yourselves all my dumbass questions.

Here's the latest - Looking to modify the below code to do the following things:

  1. Count down from (chosen number between 1-9) to zero, then stop there.
  2. Include a second button that resets the counter to (chosen number).

Wiring diagram attached. Code below.

I know how to physically wire in the second button, but beyond that I'm completely baffled. Not sure how the code does what it does, but eager to learn.

Let me know if you need anything else from me, and I appreciate you in advance!

-JG

const int a = 8;  //For displaying segment "a"
const int b = 9;  //For displaying segment "b"
const int c = 4;  //For displaying segment "c"
const int d = 5;  //For displaying segment "d"
const int e = 6;  //For displaying segment "e"
const int f = 2;  //For displaying segment "f"
const int g = 3;  //For displaying segment "g"

bool bPress = false;
const int buttonPin = 10;

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // put your setup code here, to run once:
  pinMode(a, OUTPUT);  //A
  pinMode(b, OUTPUT);  //B
  pinMode(c, OUTPUT);  //C
  pinMode(d, OUTPUT);  //D
  pinMode(e, OUTPUT);  //E
  pinMode(f, OUTPUT);  //F
  pinMode(g, OUTPUT);  //G

  pinMode( buttonPin , INPUT_PULLUP );
  Serial.begin(9600);
  displayDigit(buttonPushCounter);
}

void loop() {

   buttonState = digitalRead(buttonPin);

   // compare the buttonState to its previous state 
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == LOW) {
      // if the current state is HIGH then the button went from off to on:
      bPress = true;
      buttonPushCounter++;
      if( buttonPushCounter > 9) buttonPushCounter =0 ;
      Serial.println("on");
   
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  if( bPress ){
     turnOff();
     displayDigit(buttonPushCounter);
  }


}



void displayDigit(int digit)
{
 //Conditions for displaying segment a
 if(digit!=1 && digit != 4)
 digitalWrite(a,HIGH);

 //Conditions for displaying segment b
 if(digit != 5 && digit != 6)
 digitalWrite(b,HIGH);

 //Conditions for displaying segment c
 if(digit !=2)
 digitalWrite(c,HIGH);

 //Conditions for displaying segment d
 if(digit != 1 && digit !=4 && digit !=7)
 digitalWrite(d,HIGH);

 //Conditions for displaying segment e
 if(digit == 2 || digit ==6 || digit == 8 || digit==0)
 digitalWrite(e,HIGH);

 //Conditions for displaying segment f
 if(digit != 1 && digit !=2 && digit!=3 && digit !=7)
 digitalWrite(f,HIGH);
 if (digit!=0 && digit!=1 && digit !=7)
 digitalWrite(g,HIGH);

}
void turnOff()
{
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
}

7-segment-counter-button_bb.jpg

hopefully you see how buttonPin is defines the pin used as a button input, how it is read, how the value is tested to determine if the button was pressed and how it is then used.

you need for define a 2nd button pin and similarly read it, debounce it and do something with it. (you could read both inputs, check for change and debounce, check for either one being pressed, ignoring if neither pressed, and separate test for each button being pressed.)

separately, your jpg showing the wiring doesn't show individual resistors for each segment. This means all the current for multiple segments is limited by the one resistor, why a "1" with just 2 segments is brighter than an "8" with all 7 segments.

the code for determining which segments to turn on for each digit is also awkward. another approach would be a array, with an entry for each digit, 0-9 and each entry indicating when each of the 7 segments in on or not. Code would locate the entry and turn on/off each segment.

The bit for the button is well-taken, thank you.

Any advice for making the numbers count DOWN, instead of UP?

Change

buttonPushCounter++;

to

buttonPushCounter--;

but I have to say I could not understand, from the "dumbass" question in your original post, what you want to do exactly. How is the "chosen number" to be chosen?

Good note, Paul, thank you.

Ideally, in the code, there'd be a place where I could input a number between 0 and 9, and that would be the number that shows up on the display when you power the Arduino on.

Does that make sense?

A little more sense, yes. What is this "place" where you enter the number? A rotary switch? A line of code?

That's where I'm hoping one of you guys could help out. :stuck_out_tongue:

I know that this isn't actual code, but maybe this will help you understand the kind of flow I'm looking for:

Button1: pin2
Button2: pin3
Loop
Write "5" to 7-segment display
When Button1 is pressed, decrease the displayed count by 1.
If display count is zero, don't change count when Button1 is pressed.
When Button2 is pressed, reset display count to 5.

Does that help?

Actually, I think I may have done it!!

This code allows me to:

  1. Pick a starting number (under "variables will change")
  2. @PaulRB gave me the basics on how to decrement the number (change ++ to --)
  3. Keep the counter from looping back to the starting number:
    if( buttonPushCounter < 1) buttonPushCounter =0 ;
  4. Reset (reload) the counter to the starting number (I hardwired a pushbutton to the arduino "reset" pin).

This basic counter will allow me to keep track of the shots on a laser gun I plan to build...now I just need to marry this code with a laser diode trigger. :slight_smile:

I appreciate you guys immensely. If you see anything in my code that can be improved or streamlined, please call it out.

const int a = 8;  //For displaying segment "a"
const int b = 9;  //For displaying segment "b"
const int c = 4;  //For displaying segment "c"
const int d = 5;  //For displaying segment "d"
const int e = 6;  //For displaying segment "e"
const int f = 2;  //For displaying segment "f"
const int g = 3;  //For displaying segment "g"

bool bPress = false;
const int buttonPin = 10;

// Variables will change:
int buttonPushCounter = 9;   // counter for the number of button presses
int buttonState = 9;         // current state of the button
int lastButtonState = 9;     // previous state of the button

void setup() {
  // put your setup code here, to run once:
  pinMode(a, OUTPUT);  //A
  pinMode(b, OUTPUT);  //B
  pinMode(c, OUTPUT);  //C
  pinMode(d, OUTPUT);  //D
  pinMode(e, OUTPUT);  //E
  pinMode(f, OUTPUT);  //F
  pinMode(g, OUTPUT);  //G

  pinMode( buttonPin , INPUT_PULLUP );
  Serial.begin(9600);
  displayDigit(buttonPushCounter);
}

void loop() {

   buttonState = digitalRead(buttonPin);

   // compare the buttonState to its previous state 
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == LOW) {
      // if the current state is HIGH then the button went from off to on:
      bPress = true;
      buttonPushCounter--;
      if( buttonPushCounter < 1) buttonPushCounter =0 ;
      Serial.println("on");
   
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  if( bPress ){
     turnOff();
     displayDigit(buttonPushCounter);
  }


}



void displayDigit(int digit)
{
 //Conditions for displaying segment a
 if(digit!=1 && digit != 4)
 digitalWrite(a,HIGH);

 //Conditions for displaying segment b
 if(digit != 5 && digit != 6)
 digitalWrite(b,HIGH);

 //Conditions for displaying segment c
 if(digit !=2)
 digitalWrite(c,HIGH);

 //Conditions for displaying segment d
 if(digit != 1 && digit !=4 && digit !=7)
 digitalWrite(d,HIGH);

 //Conditions for displaying segment e
 if(digit == 2 || digit ==6 || digit == 8 || digit==0)
 digitalWrite(e,HIGH);

 //Conditions for displaying segment f
 if(digit != 1 && digit !=2 && digit!=3 && digit !=7)
 digitalWrite(f,HIGH);
 if (digit!=0 && digit!=1 && digit !=7)
 digitalWrite(g,HIGH);

}
void turnOff()
{
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
}

Too late, but for completeness, here’s the OPs picture.
Karma for using code tags up the top !

7-segment-counter-button_bb.jpg

You can shorten the code like this:

const byte segmentPin[7] = {8, 9, 4, 5, 6, 2, 3};
const byte digitPattern[10] = {
  //gfedcba
  0b0111111, // "0"
  0b0000110, // "1"
  0b1011011, // "2"
  0b1001111, // "3"
  0b1100110, // "4"
  0b1101101, // "5"
  0b1111101, // "6"
  0b0000111, // "7"
  0b1111111, // "8"
  0b1101111  // "9"
};

bool bPress = false;
const int buttonPin = 10;

// Variables will change:
int buttonPushCounter = 9;   // counter for the number of button presses
int buttonState = 9;         // current state of the button
int lastButtonState = 9;     // previous state of the button

void setup() {
  // put your setup code here, to run once:
  for (byte seg = 0; seg < 7, seg++) pinMode(segmentPin[seg], OUTPUT);
  pinMode( buttonPin , INPUT_PULLUP );
  Serial.begin(9600);
  displayDigit(buttonPushCounter);
}

void loop() {

   buttonState = digitalRead(buttonPin);

   // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == LOW) {
      // if the current state is HIGH then the button went from off to on:
      bPress = true;
      buttonPushCounter--;
      if( buttonPushCounter < 1) buttonPushCounter =0 ;
      Serial.println("on");
   
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  if( bPress ){
     displayDigit(buttonPushCounter);
  }
}

void displayDigit(int digit)
{
  for (byte seg = 0; seg < 7, seg++) {
    digitalWrite(segmentPin[seg], bitRead(digitPattern[digit], seg));
  }
}

(Untested, and certainly possible I made an error or two with the digit patterns, you may have to adjust those).