Problem using SevSegShift library with ESP32 and 74HC595

I'm trying to build a digital clock using ESP32. I cannot use the TM1637 display module because it's too small. So I'm using a generic common anode 4 digit 7 segment display. I used the Arduino SevSeg library on ESP32 and it worked perfectly. However, it consumed a lot of GPIO pins. Hence I used two 74HC595 registers and connected them exactly as described in the SevSegShift library (a fork of SevSeg library but with shift registers), like this: Circuit diagram

Unfortunately, when I run the code, I get wrong output. No matter what number or characters I try to display, only the "b" segment of the corresponding digits are turned on, all other segments of all digits are turned off. For ex, if I try to display "1111", only the "b" segment of all digits are turned on, rest all segments of all digits are turned off. As a result only upper half of "1111" is displayed on the 7 segment display, like this:

Here's the code:

#include <Arduino.h>
#include <SevSegShift.h>

#define SHIFT_PIN_DS   5 /* Data input PIN */
#define SHIFT_PIN_STCP 19 /* Shift Register Storage PIN */
#define SHIFT_PIN_SHCP 18 /* Shift Register Shift PIN */

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




void setup() {
  // put your setup code here, to run once:

  byte numDigits = 4;
  byte digitPins[] = {8+2, 8+5, 8+6, 2}; // 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;
  byte hardwareConfig = COMMON_ANODE; 
  bool updateWithDelays = false;
  bool leadingZeros = false;
  bool disableDecPoint = false;

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

}

void loop() {
  // put your main code here, to run repeatedly:
  sevseg.setNumber(1111, 0);
  sevseg.refreshDisplay();
  delay(1);
}

What am I doing wrong? Is the circuit layout given above correct? More importantly, does the SevSegShift library work with ESP32?

Try resistorsOnSegments = true

That worked but now I've another problem. Only the 2nd digit is turning on. Digits 1, 3 & 4 are turned off.

What happens when you run the example sketches from the library? I compared your sketch with one of them, and it looks like you're "winging" some things... (like why is there a delay function in loop()? ). Also why do you repeatedly set the output value every time through loop()? It may not be as harmless as you think, as it happens at a high frequency. In the "counter" example sketch, it is updated only every 100ms.

That's just a dummy value I used for testing. Running example sketches give same problem as well.

Then you probably have a wiring error. Please post detailed images of all your wiring. It would be helpful also if you would translate the Fritzing supplied by the library authors, into a real schematic, and post it too.

It's better to test with example sketches because you can generally be certain that they work.

No, it will lead to the failure of the shift registers, either sooner or later, because it exceeds one of the absolute maximum ratings for the chip. A single pin on 74hc595 can only source or sink 35mA. In this circuit, the 74hc595 pins connected to the digit common pins will be sourcing or sinking over 100mA, 3x higher than they are rated for. You would need to increase the 220R resistors by 3x to avoid overloading the chips. This would make the display less bright. I don't know if that would be a problem for you.

Also, there are no 0.1uF bypass caps for the shift registers.

A much better idea than using 74hc595 chips for this would be to use a max7219 chip. This would make your circuit and code much simpler. Only one resistor and two caps would be required. The display would be much brighter and you could adjust the brightness in your code if you wanted to. Your choice would also be easier because you would be able to use delay() without the display flickering. The max7219 chip performs the multiplexing so that the Arduino does not have to.

It is a schematic. Not a very well drawn one, but at least it is not a "breadboard view" wiring diagram of the type that often gets posted when using Fritzing. That's what forum members hate!

But in fact, they will not actually do that. :face_with_raised_eyebrow:

OK, you know this, I know this. When the datasheet refers to a "limiting value", this is not necessarily (jsut) the "safe" value, but just as much a genuine limit, something the chip simply will not exceed.

But if you are driving a LED with a driver to both anode and cathode, the LED will drop nearly 2 V (red) and each of the drivers will drop a voltage as per table 6 which if extrapolated, means that the currents will not necessarily be exceeded even with no resistors!

However, while I have been researching this in detail, you (@PaulRB) have pointed out the sensible idea. Using the "SevSeg" and "shift" libraries is just for toying around, not in any way for a serious project.

If you really want to build a digital clock, use a proper LED driver, the MAX7219.

Easiest way (albeit slow :grin:), get one or more (more, of course, buy half a dozen!) of the matrix module kits from Aliexpress and use the convenient PCB with the MAX7219 mounted; ignore the matrix display and the socket pins for it, connect your display.

The MAX7219 is not the ideal choice for use with 3.3V processors because of the need for logic level translation. Both the HT16K33 and TM1637 are specified for operation at 3.3V, so the connections can be safely be made directly to the processor I/O pins.

It is not, however, a schematic of the system that the OP has, with a different processor at least.

True!

I recently built an ESP32 clock using similar display modules, and for the same reason, size. I used an HT16K33 backpack because it makes it extremely easy to make the connections to the module, there is no futzing around with IC's or proto boards.

Well, actually there is one proto board to physically support the backpack PCB and display modules (it uses 3). But there is no active wiring there except for jumpers and bypass caps.

I'm a CSE student, so my knowledge in electronics is limited. However I did research quite a bit for the display. I wanted to use either MAX7219 or HT16K33 for my project. Unfortunately, MAX7219 isn't readily available and HT16K33 is way too expensive in my region. So I had to settle for a generic 4 digit 7 segment display with shift registers.

I've a weird question. The TM1637 is available at cheap price but it's digits are too small (0.36 inch). Can I take out those digits and replace them with 0.56 inch digits?

(Picks up module from desk in front of me ...)

Yes, you certainly could, but you will need a good solder sucker and some patience to dislodge the twelve pins.

Actually, some very careful work with a bandsaw or hacksaw as there is no other component on the face of the module, and you can pick out the remnant pins individually as you de-solder them. :grin:

Note the need to remove incorrectly specified capacitors - unless the later manufacture has corrected this - as in this discussion.

Yes, I did that also, replaced the modules by snipping the leads and desoldering them. Then the new leads had to run around the board edge instead of right in. I even managed to wire the colon pins to an unused drive pin on the TM1637. But the project is not for the faint of heart.

Thank you for the quick responses! This community is awesome.

As a newbie, I've a few novice questions:

  1. Does the TM1637 work with 1 inch 7 segment digits?
  2. As @PaulRB pointed out, MAX7219 performs multiplexing. Does TM1637 also perform multiplexing? If not, how much load does multiplexing put on the MCU?
  1. It is not the size of the digits that matters, it is the forward voltage (Vf) of the segments. Post a link to the specs of the digits you want to use and details of how the circuit will be powered.

  2. Yes, MAX7219, TM1637 and HT16K33 perform the multiplexing of the display. When the Arduino multiplexes the display, for example when using shift registers, cpu load is not very high, provided the code is well written. The difficulty with the Arduino multiplexing is that you must write your code in such a way that it allows the multiplexing to run smoothly with the rest of the code, and this is not easy for a beginner. If it does not work smoothly, the display will flicker or not light all digits with the same brightness.

Hi, @amith108
Welcome to the forum.

Can you please post a circuit diagram, not a Fritzy image but a proper connecting wires schematic?
Please include All power supplies, component names and pin labels.

Some images of your project would also be helpful.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

@PaulRB looks like replacing the digits of TM1637 is the way to go. I'll simply take out the tiny digits, solder male pins to the board and connect the larger display via dupont wires.

Thanks for all the support!