Six digit Seven segment display countdown timer

Hi everyone, I'm totally new to any kind of forum posting. If there's anything not up to regulation, please let me know! I'm trying to learn but it's not always the easiest.

After using an Arduino board for my engineering class, I wanted to tackle my own project. Namely, a countdown timer with six seven segment displays that shows the remaining months, days, and hours set by the user via push-buttons. The actual countdown would then be controlled by an RTC module (I read somewhere that the Arduino's internal timer is not accurate for extended time periods). I assumed this would be a relatively simple project but wow was I wrong. All of my work so far has been through online simulators like TinkerCAD and Wowki. I wanted to have some kind of baseline before buying components. I assume a project like this would not require a board bigger than an UNO correct? (Please let me know if this is wrong)

After testing it out with only two seven segment displays, I ran into a couple of issues. I very quickly realized I needed a SIPO shift register in order to limit the amount of pins used. I started off by using the very common 74HC595. I quickly realized from other forums that this IC has a max current of 35mA. From a quick Google browse, I discovered that each segment of the displays uses about 15mA at half of max capacity. So even if every one of the 6 displays had it's own shift register, the current drawn by the displays would be way past the max of the 35mA limit.

I looked into multiplexing in order to half the current drawn. For the project I could buy 3 pairs of 2 displays which are already multiplexed. However, this obviously still exceeds the max current per shift register. I looked into shift registers which can handle a higher current load (like the TPIC6B595) but if I'm reading the datasheet correctly, they can only sink current. This, however, was an issue for the multiplexed displays since the shift registers required both the ability to source and sink current.

TLDR; All in all, from my limited knowledge and testing, it seems like I can't multiplex and have the shift registers working properly. The goal is to have 3 independent multiplexed pairs of two 7 segment displays seeing as this halves my current usage. However, I can't seem to figure it out.

My two questions are this: 1.) what is the best way to go about using six of these displays? 2.) Will a project like this need an external power source?

Below are two test circuits I built to try and understand. These circuits simply allow the user to enter up to 60 seconds and then proceeds to count down after the start button is pressed.

1.) 2 separate non-multiplexed displays (draws too much current for the 74HC595 and could be multiplexed to reduce current I think)

const int COUNT_BUTTON_PIN = 13;
const int START_BUTTON_PIN = 12;
const int DS_pin = 4;
const int latch_pin = 3;
const int clock_pin = 2;
const long TIME_PRESSED_BUTTON = 500; // indicates the delay needed to increase count

long lastTimeChecked = 0;
int total_count = 0;
int first_disp = 0;
int second_disp = 0;

int dat_arr[10] = {B10000001, B11001111, B10010010, B10000110, 
                  B11001100, B10100100, B10100000, B10001111,
                  B10000000, B10000100}; // binary for 0-9

void setup() {
  pinMode(DS_pin,  OUTPUT);
  pinMode(latch_pin, OUTPUT);
  pinMode(clock_pin, OUTPUT);
  pinMode(COUNT_BUTTON_PIN, INPUT);
  pinMode(START_BUTTON_PIN, INPUT);
}


void  loop() { 
  count_increase();
  if (digitalRead(START_BUTTON_PIN) == HIGH){
    start_timer(total_count);
    total_count = 0;
  }
}

void start_timer(int seconds){
  
  // separate input into first and second digit
  first_disp = seconds/10;
  second_disp = seconds%10;
  
  // countdown timer loop
  while (not((first_disp == 0) && (second_disp == 0))){
    display_digits(first_disp, second_disp);
    delay(1000);
    if (second_disp == 0){
      first_disp--;
      second_disp = 9;
    }
    else{
      second_disp--;
    }
  }
  display_digits(first_disp, second_disp);
}

void display_digits(int first, int second){
  // writes to displays
  digitalWrite(latch_pin,LOW);
  shiftOut(DS_pin,  clock_pin, LSBFIRST, dat_arr[second]);
  shiftOut(DS_pin,  clock_pin, LSBFIRST, dat_arr[first]);
  digitalWrite(latch_pin, HIGH);

}

void count_increase(){
  // Handles increasing of count through push button
  while (digitalRead(COUNT_BUTTON_PIN) == HIGH){
    if (millis() - lastTimeChecked > TIME_PRESSED_BUTTON){
      lastTimeChecked = millis();
      if (total_count >= 60){
        total_count = 0;
      }
      else{
        total_count++;
      }
      first_disp = total_count/10;
      second_disp = total_count%10;
      display_digits(first_disp, second_disp);
    }
  }
  lastTimeChecked = 0;
}

2.) 1 2 digit multiplexed display (still draws too much current for the 74HC595 but can't be swapped for a TPIC6B595 because it needs to both source and sink (right?). The library used, SevSegShift, also doesn't seem to allow multiple separate displays. Is this correct?)

#include "SevSegShift.h"

#define SHIFT_PIN_DS  8
#define SHIFT_PIN_STCP 7
#define SHIFT_PIN_SHCP 6
#define TIME_PRESSED_BUTTON 200
#define COUNT_BUTTON_PIN 13
#define START_BUTTON_PIN 12

long lastTimeChecked = 0;
long timer = 0;
int total_count = 0;
bool timer_finished = false;

SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP); // Instantiate a seven segment controller object

void setup() {
  byte numDigits = 2;
  byte digitPins[] = {8+2, 8+5}; // of ShiftRegister(s) | 8+x (2nd Register)
  byte segmentPins[] = {8+3, 8+7, 4, 6, 7, 8+4, 3,  5}; // of Shiftregister(s) | 8+x (2nd Register)
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = true; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = true; // Use 'true' if your decimal point doesn't exist or isn't connected

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
  updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(90);
}

void loop() {
  count_increase();
  if (digitalRead(START_BUTTON_PIN) == HIGH){
    start_timer();
    timer_finished = false;
  }
  sevseg.refreshDisplay();
}

void start_timer(){
  // countdown timer loop
  sevseg.setNumber(total_count, 0);
  timer = millis();
  while (not(timer_finished)){
    if (millis() - timer >= 1000){
      timer = millis();
      if (total_count == 0){
        timer_finished = true;
      }
      else{
        total_count--;
        sevseg.setNumber(total_count, 0);
      }
    }
    sevseg.refreshDisplay();
  }
}

void count_increase(){
  while (digitalRead(COUNT_BUTTON_PIN) == HIGH){
    if (millis() - lastTimeChecked >= TIME_PRESSED_BUTTON){
      lastTimeChecked = millis();
      if (total_count >= 60){
        total_count = 0;
      }
      else{
        total_count++;
      }
    }
  sevseg.setNumber(total_count, 0);
  sevseg.refreshDisplay();
  }
  lastTimeChecked = 0;
}

I realize buttons have bounce but I didn't feel the need to include this as it is a relatively simple fix from what I've seen.

All in all, I know it's a lot but I wanted to be sure to include everything that could possibly be needed. If there's anything missing, please let me know and I'll update it as soon as possible! If there's anything about the project, regardless of the two questions, that could use tweaking, I would love to hear it! I'm learning as I go.

Thank you so much for your time!

I'm sure there are a bunch of very wise answers on the way, but before they get here: how about a Darlington transistor array after the shift reg?

any MCU can handle Sev Seg. board outline is unimportant. no board is a generator, so external power source is a must.
595 IC have Latch pin, you can connect Sin to one arduino pin and each Latch to its own. or you can connect serial output of 595 to input of next 595.

there are some modules with TM1637 or MAX7912 with 6 digits.

wich sevseg display do you mean? 4Inch devices need definitely more than 15mA

dependent on your skills you may try to build own DIY sevseg display of needed dimension and fill segments with regular LED or LED strips.

You may go with MAX7219 driven/Library support 6/8-digit display unit.


image

I had seen this solution proposed in a different thread. I looked into it and just can't wrap my head around transistors. I searched online for an example usage but I couldn't find a good one.

I'm assuming Darlington arrays can source and sink current? And could you refer me to a good example usage or provide one please? I've tried understanding them but it's just so complicated.

Thank you for you time!

I'm a little confused by the first part of the reply. In the circuit I provided, one shift register is connected through it's data, clock, and latch pin, as well as ground and 5v. The second shift register is connected via the same clock, latch, ground, and 5v as the first but it's data pin is being cascaded. This configuration still suffers from the fact that the 7-seg displays draw too much current for the 595 to handle.

This might be a total noobie question, but how would one go about using one adapter to both feed the Arduino and the circuit? I realize there's a Vin pin on the Arduino but people caution against using it.

As to answer the second part of your reply, I would like to keep the 7-seg displays either entirely separate or in 3 pairs. Each pair of displays would have a header (months, days, hours) engraved above them in the MDF material. Hopefully this beautiful sketch below helps explain why:

Thank you for your time!

I didn't realize such big displays existed. From a quick Google search, the largest I found was a 25x19x8 mm. A bigger display is obviously more enticing (if I can find them).

I had seen someone on YouTube build his own seven segment display with the NeoPixel strips. However, this is a bit overkill as I'm hoping to keep the overall project size to a 30x15x15cm box. I don't think I have the skill to make my own using LEDs.

Thank you for the suggestions!

Seeing as this is the second person suggesting this, I came to realize I didn't specify how I wanted to lay out the displays. My apologies for this!

Here's the response to a 6/8 digit seven segment display driven by a MAX7219 IC.

Thank you for the suggestion!

I don't know what you will do, but this 4-digit , without the need for any resistors and plenty of jumper cables may help you do what you want, because if you are only going to use 4 pins. No potentiometer is required, I included it in the example to understand how the values change.

I only have a rough understanding, so this is probably inaccurate, or a huge simplification.

Depending on the type of transistor, it would either source or sink current, but not both. This isn't an issue though; you can multiplex your pins so all the sources use one shift reg, and all the sinks use another same shift reg.

The very abridged explanation:

Transistors come in two types

Transistor Diagram

  • NPN
    • Good low-side switch
    • Load flows from Collector (C) to Emitter (E)
    • Load current is regulated by current flowing into Base (B)
    • Load current is roughly 100x the Base current
  • PNP
    • Good high-side switch
    • Load flows from Emitter (E) to Collector (C)
    • Load current is regulated by current flowing out of Base (B), from Emitter (E)
    • Load current is roughly 100x the Base current

In either case, you must restrict the current flow into / out of Base. V=IR can be used to figure out the right resistor to limit current appropriately, or there are probably calculators you can search up.

If the goal is ON / OFF, the current into / out of Base just needs to be high enough to more than allow your load.

A Darlington pair is a fancy term for two transistors, connected together, so that a tiny Base current can switch a large load current. Rather than 100x amplification, you're getting (something like) 100x100 = 10,000x amplification.

Given your current needs, single stage transistors may be enough, you may not need anything like Darlington pairs. Of course this is only if you choose to do it the hard way, for the learning opportunity. If the main focus is getting the product done, any of the other solutions suggested will be easier.


Have a play around with transistors on falstad.com. I've found it to be an invaluable tool.

1 Like

this is 1 inch display.
I contributed to one thread here where a user wanted to light 4x 4-inch pieces.
we don't know what display you have and how much current it need due to this we can't for sure say what you need to securely drive them. definitely transistors can help in any case.

here 1 inch display, its current not exceed 30mA pro segment, 595 can drive red, green, amber of it.
https://www.lc-led.com/products/lcs-10012tur11.html

BTW, take a look on dual displays
like this https://www.dghongke.com/product/big-size-dual-digit-red-1-inch-7-segment-led-display-common-cathode-seven-segment-1-houkem-10021-asr

not only shift register are useful, but 7-segment decoder 4511 or 74(x)47 too
зображення
зображення

If you set the timer to count down from one month, then how many days should it take? 30 days? Or 31? Or 28? Or 29?
Have you thought this through?

that is why he will use RTC, to know current month and then calculate days
probably:
зображення

I'm a little confused by this statement. How would you go about doing this? From what I understand, the shift registers either only sink/source current if the 7-seg displays are not multiplexed or do both if they are multiplexed. So how would you separate the pins to have one shift register sink and another source?

So if I understand correctly and grossly simplify transistors, they basically allow us to control relatively high currents through low control currents? Let's say for instance I have an NPN with a 1A current flow from collector to emitter. I could then "toggle" this flow on or off through a 20mA (a.k.a. an Arduino pin) current through the base?

If the above explanation is correct, wouldn't that mean I need a total of 52 (7 segments x 6 displays) transistors? If so, is there a better way to go about this?

That's a really handy explanation, thank you! I'm definitely interested in learning about all these components as they seem useful but I don't want to end up having to solder a million pieces :sweat_smile:. However, if this ends up to be the most cost-effective or a way which I understand, it's a very good option.

This is such a cool site! I'm surprised I've not seen it before. Thank you!

EDIT: While playing around on the falstad.com website, I discovered the existence of MOSFETs. From a quick Google search, I gathered they're like transistors but use voltage instead of current. So if my previous assumption of "allow us to control relatively high currents through low control currents" is true, wouldn't a MOSFET be handier since it uses voltage as its logical "switch"? Let me know if this assumption is incorrect!

Thank you for pointing this out!

I discovered on the datasheet of the DS3231 RTC module that it keeps tracks of months with less than 31 days. As @kolaha pointed out in their comment, I'm planning on using this to keep track of the amount of days.

Now knowing that displays larger than 1 inch exist, I'm hoping to get my hands on some 2 or 3 inch displays for this project.

My bad! Hopefully the above specification should help!

This might be a very ignorant question, but even if each segment does not exceed 30mA per segment, powering all segments simultaneously would result in 210mA (30mA x 7) which is way past the 595's max rating of 70mA. Am I not understanding something about the 595?

I've looked into these as they are multiplexed from the start without the hassle of having to figure it out yourself. However, these still suffer from the 595 max current problem right?

This is what I initially had started with but they can't be cascaded from what I understand. Meaning each display would need its own 4 pins. This is obviously not ideal when I'm planning on having six displays.

how much outputs have 595?

why you think 595 can light simultan only 2 segments? where do you read this?

Yes exactly! Although 1A might be a stretch for lot of tiny cheap models: you'd have to check in a model's datasheet.

It's a bit of a cheat, but what you can do is "strobe" them.

Imagine you have 6 digits, you wire all the A segments together, all the B segments together, etc.

You now have 7 wires. Those wires go into one shift register.

Imagine that you now set the shift register to sink current for the B and C segments. If you pick one of these digits, and provide power to the common pin, you would see segments B and C, showing the numeral one.

If you powered all of these digits, at the same time, they would all show the numeral one.

Now imagine a second shift register. The common power input of each digit is connected to a different pin of this shift reg. By setting this second shift register, you can control which digit lights up.

You can use the first shift reg to decide which segments to sink current from. You can use the second shift reg to decide which digit you want to illuminate.

You can only show one digit at a time. The trick is, if you do this fast enough, the human eye can't really tell.

It keeps the Arduino busy, because it has to constantly alter the two shift registers, scrolling between digits, to keep the illusion going.

This is all a trick to save hardware. If you instead chose to keep the digits steady, you might need, for each digit, one shift reg, and 7 transistors. So, yes, assuming no strobing, that would mean 42 transistors..

Nobody can be bothered with that, and that's why there are various packages that aim to make the job easier. My knowledge here is sparse, but:

  • At the basic end you get something like that "Darlington transistor array": the 8 transistors *8 pairs all in one block. You'd need one of them per shift reg.

  • Somewhere in the middle, you'll get some kind of "LED driver" package, which probably works as a shift reg + transistor combo.

  • At the fancy end, you'll get one of those pre-built display modules. All of the shift-reg / transistor stuff taken care of, and it'll even let control it with something convenient like SPI or I2C.

MOSFETs are very handy things!

What we have so far been calling a "transistor", is really a BJT: bipolar junction transistor, named for the internal design.

MOSFETs are actually just a different kind of transistor: Metal Oxide Semiconductor Field Effect Transformers.

So if my previous assumption of "allow us to control relatively high currents through low control currents" is true, wouldn't a MOSFET be handier since it uses voltage as its logical "switch"?

MOSFETs are really great for a lot things.

The truth is that it is really very easy to use a BJT as a switch. It is also very easy to use a MOSFET as a switch.

The current used to switch a BJT is not enough to be an issue, so in this case, I'm not sure if there is any real advantage to using MOSFETs.

I always have a sense that I shouldn't use a MOSFET when a BJT will do: they're just that bit less expensive, but there's no reason it couldn't be done.

If you do end up using some sort of LED driver IC, you won't have to worry about it, because all the transistors are hidden away inside the mystery box.

Just having a

As @kolaha was saying, the CD4511 (or CD4543B, if you're using common anode LEDs) does sound like an attractive option.

The manufactures seems to think that it has plenty of power to drive LEDs directly, but it sounds like this is really only 5ma..

The reason you won't need pins for each display, is that the CD4511 has a "latch". Like I was talking about above, you can wire all the inputs together, and then just push the latch pin on one of the chips. The others won't change. So that's four pins to select a numeral, then 6 pins (1 shift register?) to select the digit.

We'd call this sort of thing multiplexing (I think?)