controlling a seven segment display to display a number when a switch is pressed

Hi.

I am hopefuly someone here can help me.

I am building a simple (haha) circuit to display a number when a switch is pressed.

I've set up the seven segment display, using the 74HC595 serial to parallel converter included in the Elegoo super started kit. (data sheet here http://www.ti.com/lit/ds/symlink/sn74hc595.pdf)

The example code gives a number countdown from 9 to 0.

I need to set it up so that it displays a pre-determined number when a switch is pressed. There will be four switches, each with a separate number.

Obviously the wiring is all correct to connect the 7 segment display to the Uno, via the SPC, it's just the coding that has me stumped.

I'm a total noob at C++. My programming experience expired around 1998, with BASIC.

Can anyone help? Has anyone done a similar thing?

Any help would be hugely appreciated.

Sounds quite straightforward to me. Feel free to post your best attempt.

Do start with the examples - particularly on how to read a button, understand that part, then make a button press display a number. Start by counting button presses or so, that'd be a fairly easy integration of the button example with your existing countdown example.

Thanks WV.

I’ve been trying to teach myself Python to run RPi stuff. This C++ syntax is totally throwing me.

All I’ve got so far is the very simple number countdown. I know what I need to ask the board to do, just no idea how to phrase it in C++.

Full disclosure.

This is for a work project.

I'm learning RPi and Python (for my own enjoyment)

New boss been here three days) found this out and therefore thinks I'm an expert in all things computer, so has handed me this task.

I know it's my problem, not yours, but I don't have time to learn the required coding skills in C++. We are opening a new escape room on monday and everything needs to be up and running by then.

I know it's incredibly cheeky, and I promise a donation to a charity of consensus choice for any assistance in making this work.

I WILL learn C++ and Arduino, because I can see it being an absolutely essential skill, but I just don't have the time to learn it between now and monday.

Post that code :slight_smile:

And if you know how to count down, you know how to display all numbers, don't you? So can't be to hard to display a certain number...

And yeah, C/C++ has a pretty strict syntax compared to Python. But I would not say it's a hard syntax, you only have to follow is strictly. If you can, I think other languages are easier.

Coming from Python myself (via Basic and Turbo Pascal). I found C++ isn't that hard, really, the hardest part is dealing with the variables which you have to declare. Check out a few tutorials, there are lots of them online. And as said before: do go through the examples as provided in the Arduino IDE, try to understand what it's doing. Make a change, see what happens. You'll learn quick enough. As soon as you know a few computer languages, it becomes "yet another one".

Thanks Septillion.

I can barely

print ('Hello World')

in Python so far.

WV, If only I had the time. I could do it, given a few days to play and learn, but I just don't have the time.

The code I have thus far (this is Elegoo code, not my own) goes something like this.

//www.elegoo.com
//2016.12.12

// define the LED digit patterns, from 0 - 9
// 1 = LED on, 0 = LED off, in this order:
//                74HC595 pin     Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7 
//                Mapping to      a,b,c,d,e,f,g of Seven-Segment LED
byte seven_seg_digits[10] = { B11111100,  // = 0
                              B01100000,  // = 1
                              B11011010,  // = 2
                              B11110010,  // = 3
                              B01100110,  // = 4
                              B10110110,  // = 5
                              B10111110,  // = 6
                              B11100000,  // = 7
                              B11111110,  // = 8
                              B11100110   // = 9
                             };
 
// connect to the ST_CP of 74HC595 (pin 3,latch pin)
int latchPin = 3;
// connect to the SH_CP of 74HC595 (pin 4, clock pin)
int clockPin = 4;
// connect to the DS of 74HC595 (pin 2)
int dataPin = 2;
 
void setup() {
  // Set latchPin, clockPin, dataPin as output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}
 
// display a number on the digital segment display
void sevenSegWrite(byte digit) {
  // set the latchPin to low potential, before sending data
  digitalWrite(latchPin, LOW);
     
  // the original data (bit pattern)
  shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[digit]);  
 
  // set the latchPin to high potential, after sending data
  digitalWrite(latchPin, HIGH);
}
 
void loop() {       
  // count from 9 to 0
  for (byte digit = 10; digit > 0; --digit) {
    delay(1000);
    sevenSegWrite(digit - 1); 
  }
   
  // suspend 4 seconds
  delay(3000);
}

Now some of this makes sense, of a sort, but I've played and can't work out how to force it to display a digit of my choosing.

Also I've not worked out how to register a button push (let alone four different buttons). Nor have I worked out how to take the latter and make it output the former. Obviousy three different problems.

The line where a digit gets written:

    sevenSegWrite(digit - 1);

The value of digit goes from 10 to 1, so you're writing a value 9 to 0. Just put the number you want to display there.

So you're going to get four sets like this in loop():

if (digitalRead(button) == LOW) { // Assume this is button 1, wired the normal way, internal pull-up enabled.
  sevenSegWrite(1);
}

And for the push button part, connect it between a pin and GND and use Bounce2 to do al the "heavy lifting" for you :slight_smile:

No need to worry about bounce in this application. You don't count the number of presses, you just react to the button being pressed.

Yeah, bounce and state change are not big issues as it seems. But still, like the clean look of it :stuck_out_tongue:

Thankyou so much! I realise it's super cheeky coming in and asking you to solve my problems for me, but it's hugely appreciated!

Do I need to define the switched pins and number them?

What do you mean by "switched pins"?

OK, so had a play and have got as far as this, which the IDE seems to think is ok. All I get out is all seven segments flickering in and out, apparently at random and independent of any switch input.

I meant the pins that have the switches attached, but I think I worked it out correctly?

// define the LED digit patterns, from 0 - 9
// 1 = LED on, 0 = LED off, in this order:
//                74HC595 pin     Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7 
//                Mapping to      a,b,c,d,e,f,g of Seven-Segment LED
byte seven_seg_digits[10] = { B11111100,  // = 0
                              B01100000,  // = 1
                              B11011010,  // = 2
                              B11110010,  // = 3
                              B01100110,  // = 4
                              B10110110,  // = 5
                              B10111110,  // = 6
                              B11100000,  // = 7
                              B11111110,  // = 8
                              B11100110   // = 9
                             };
 
// connect to the ST_CP of 74HC595 (pin 3,latch pin)
int latchPin = 3;
// connect to the SH_CP of 74HC595 (pin 4, clock pin)
int clockPin = 4;
// connect to the DS of 74HC595 (pin 2)
int dataPin = 2;
// set switch 1 to pin 7, 2 to 8, 3 to 9 and 4 to 10 
int switch1pin = 7;
int switch2pin = 8;
int switch3pin = 9;
int switch4pin = 10;
 
void setup() {
  // Set latchPin, clockPin, dataPin as output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(switch1pin, INPUT);
  pinMode(switch2pin, INPUT);
  pinMode(switch3pin, INPUT);
  pinMode(switch4pin, INPUT);
}
 
// display a number on the digital segment display
void sevenSegWrite(byte digit) {
  // set the latchPin to low potential, before sending data
  digitalWrite(latchPin, LOW);
     
  // the original data (bit pattern)
  shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[digit]);  
 
  // set the latchPin to high potential, after sending data
  digitalWrite(latchPin, HIGH);
}
 
void loop() {       
  // write digits on button press
   if (digitalRead(switch1pin) == LOW) { // Assume this is button 1, wired the normal way, internal pull-up enabled.
  sevenSegWrite(1);
   }
   if (digitalRead(switch2pin) == LOW) { // Assume this is button 2, wired the normal way, internal pull-up enabled.
  sevenSegWrite(2);
   }
   if (digitalRead(switch3pin) == LOW) { // Assume this is button 3, wired the normal way, internal pull-up enabled.
  sevenSegWrite(3);
   }
   if (digitalRead(switch4pin) == LOW) { // Assume this is button 4, wired the normal way, internal pull-up enabled.
  sevenSegWrite(4);
}
}

How do you have your buttons wired? Any pull-up resistors? I notice you didn't enable the built-in ones (by using INPUT_PULLUP instead of INPUT). Your symptoms may very well be due to floating (unconnected) pins.

You are, of course, entirely correct.

One final conundrum.

The display continues to display the last number until a new one is selected. I've attempted to clear the display using a second if statement after the first, but I can't get it to turn off all the LED's.

Is there a simple way to do this?

I was thinking maybe to add a line to the truth table at the beginning with everything set to 0, maybe call it A or something, then addan if statement saying

if (digitalRead(switch1pin) == HIGH) { 
  sevenSegWrite(A);
   }

Would that work?

I tried it. It appears to!

Final code reads

// define the LED digit patterns, from 0 - 9
// 1 = LED on, 0 = LED off, in this order:
//                74HC595 pin     Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7 
//                Mapping to      a,b,c,d,e,f,g of Seven-Segment LED
byte seven_seg_digits[11] = { B11111100,  // = 0
                              B01100000,  // = 1
                              B11011010,  // = 2
                              B11110010,  // = 3
                              B01100110,  // = 4
                              B10110110,  // = 5
                              B10111110,  // = 6
                              B11100000,  // = 7
                              B11111110,  // = 8
                              B11100110,  // = 9
                              B00000000   // = 10
                             };
 
// connect to the ST_CP of 74HC595 (pin 3,latch pin)
int latchPin = 3;
// connect to the SH_CP of 74HC595 (pin 4, clock pin)
int clockPin = 4;
// connect to the DS of 74HC595 (pin 2)
int dataPin = 2;
// set switch 1 to pin 7, 2 to 8, 3 to 9 and 4 to 10 
int switch1pin = 7;
int switch2pin = 8;
int switch3pin = 9;
int switch4pin = 10;
 
void setup() {
  // Set latchPin, clockPin, dataPin as output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(switch1pin, INPUT_PULLUP);
  pinMode(switch2pin, INPUT_PULLUP);
  pinMode(switch3pin, INPUT_PULLUP);
  pinMode(switch4pin, INPUT_PULLUP);
}
 
// display a number on the digital segment display
void sevenSegWrite(byte digit) {
  // set the latchPin to low potential, before sending data
  digitalWrite(latchPin, LOW);
     
  // the original data (bit pattern)
  shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[digit]);  
 
  // set the latchPin to high potential, after sending data
  digitalWrite(latchPin, HIGH);
}
 
void loop() {       
  // write digits on button press
   if (digitalRead(switch1pin) == LOW) { // Button 1 closed, wired the normal way, internal pull-up enabled.
  sevenSegWrite(1);
   }
   if (digitalRead(switch1pin) == HIGH) { // Button 1 open, wired the normal way, internal pull-up enabled.
  sevenSegWrite(10);
   }
   if (digitalRead(switch2pin) == LOW) { // Assume this is button 2, wired the normal way, internal pull-up enabled.
  sevenSegWrite(2);
   }
   if (digitalRead(switch2pin) == HIGH) { // Button 2 open, wired the normal way, internal pull-up enabled.
  sevenSegWrite(10);
   }
   if (digitalRead(switch3pin) == LOW) { // Assume this is button 3, wired the normal way, internal pull-up enabled.
  sevenSegWrite(3);
   }
   if (digitalRead(switch3pin) == HIGH) { // Button 3 open, wired the normal way, internal pull-up enabled.
  sevenSegWrite(10);
   }
   if (digitalRead(switch4pin) == LOW) { // Assume this is button 4, wired the normal way, internal pull-up enabled.
  sevenSegWrite(4);
   }
   if (digitalRead(switch1pin) == HIGH) { // Button 4 open, wired the normal way, internal pull-up enabled.
  sevenSegWrite(10);
   }
}

Out of interest, what's the maximum power output capacity for the Uno? Will it happily run 7 3V 30mA LED's?

Once again, thankyou for your help. I hope I have shown that I've learnt a load from it. :slight_smile:

It won't work properly this way. Every time you're running loop() while you have a button pressed you're writing the number once, and you're writing nothing three times. So the LEDs are 1/4 of the time on. As it loops so fast, it seems it's on all the time to your eyes.

Use if..else statements here.

if (button1 == LOW) sevenSegWrite(1);
else if (button2 == LOW) sevenSegWrite(2);
...
else sevenSegWrite(10);

This is what you seem to be looking for. If you have multiple buttons pressed at the same time, the first the code sees is the number displayed.