A chain on an ESP32-S3
The whole build in one place: an ESP32-S3 on USB, a 12 V adapter, and modules joined by eight jumper wires each. Which wire goes where, why the logic rail is 3V3 and never 5V, and how big an adapter a chain needs at 140 mA a module.
Two supplies, one ground
An ESP32-S3 cannot light these digits and is not asked to. The S3 runs from its USB cable. The segments run from a 12 V adapter. The two meet at the first module's IN edge: the adapter on the two-pin header, the S3 on the six-pin one. Both headers have a GND pin, and the board joins them, so wiring both is all it takes to give the two supplies a common ground.
Change the number of modules and watch the labels on the orange wires. The current goes in at module 1 and gets smaller at every join, because each join only feeds the modules after it.
Six wires from the S3
| ESP32-S3 | Module 1, IN edge |
|---|---|
| 3V3 | 3V3/5V |
| GND | GND (six-pin header) |
| GPIO11 | DATAIN (SER) |
| GPIO10 | LATCH (RCLK) |
| GPIO12 | CLOCK (SRCLK) |
| GPIO13 | PWM |
On the ESP32-S3 Gold board the four GPIOs sit side by side on one header: 9, 10, 11, 12, 13, 14, then 5V and GND. Take GND from there and 3V3 from the other end of the same row. Mind the 5V pin next to that GND. It is the wire that looks right and is wrong.
None of the four is a strapping pin, a USB pin or a PSRAM pin. Any other free GPIO works just as well, and the sketch has one line per pin. These four have one more thing going for them: they are the pins the Arduino core calls SS, MOSI, SCK and MISO on an S3, so the wiring stays put if you later drive the chain from the SPI peripheral.
3V3, not 5V
The module's logic pin is printed 3V3/5V, and both work on the chip's own terms. The catch is that the shift register measures a high against its own supply. On 5 V, TI's datasheet wants at least 3.15 V before it counts an input as high, and that is its 4.5 V figure; at 5 V the threshold is higher still. An S3 pin never goes above 3.3 V. Wired that way, a chain usually works on the desk and then misses a clock edge for no visible reason.
On 3V3 the S3's highs sit well above what the chip needs, and nothing is lost. The 74HC595 is rated from 2 V, and the segments do not run from this rail at all.
Eight wires at every join
Every further module takes eight jumpers from the OUT edge of the module before it to its own IN edge: the two power pins and the six signal pins, row for row. Seven of them keep their name across the join. The eighth is the data: (QH) DATAOUT on one side, DATAIN on the other, because that wire comes out of the first shift register and goes into the next.
Which jumper to use follows from the headers. The IN edge has male pins and the OUT edge has female sockets (soldering the headers has the details), so a join is eight male-to-female jumpers. From a dev board's pins to module 1's pins they are female-to-female.
Nothing beyond module 1 goes back to the S3. The chain is one set of six wires from your board, however long it gets.
How big an adapter
One module showing "8." at full brightness draws 140 mA from the 12 V. That is our own measurement, and it is the worst case, with all eight segments lit. A chain draws that much per module, so four modules need 560 mA.
Buy an adapter with room to spare: a quarter more than the chain's figure is our rule, not a datasheet's. A 12 V 1 A adapter covers up to five modules on that rule. All of the current enters through module 1's 12V pin and leaves through its GND, which makes the first pair of jumpers the ones to check if something gets warm.
The sketch
It counts from 0 to the largest number the chain can show. Two things in it are
specific to the S3. The pins are the GPIO numbers from the table. And PWM is
driven with analogWrite() at the end of setup(), after the registers have
been cleared, so the digits never flash whatever the registers held at power-up.
The code
Set NUM_DIGITS to the number of modules in the chain. The four GPIOs are the ones in the table above; if you move a wire, change its line here.
// Count on a chain of 4" seven-segment modules from an ESP32-S3.
//
// Two supplies. The ESP32-S3 runs from USB, the segments from a 12 V adapter.
// Wiring, at the first module's IN edge (reading the back, IN is on the left):
// 12 V adapter + -> 12V two-pin header
// 12 V adapter - -> GND two-pin header
// ESP32-S3 3V3 -> 3V3/5V six-pin header (3V3, never 5V)
// ESP32-S3 GND -> GND six-pin header
// ESP32-S3 GPIO11 -> DATAIN (SER)
// ESP32-S3 GPIO10 -> LATCH (RCLK)
// ESP32-S3 GPIO12 -> CLOCK (SRCLK)
// ESP32-S3 GPIO13 -> PWM leave the PWM pad OPEN on every module
//
// Each further module: eight jumpers from the OUT edge of the one before to
// its IN edge, pin for pin. (QH) DATAOUT goes to DATAIN; the other seven go
// to the pin of the same name. Nothing else goes back to the ESP32-S3.
//
// Arduino IDE: Tools > Board > esp32 > ESP32S3 Dev Module, then Tools > Port
// and pick the port the board appears on. ESP32 core 3.x. No libraries.
#define NUM_DIGITS 2 // how many modules are in the chain
#define SER 11 // DATAIN (SER)
#define LAT 10 // LATCH (RCLK)
#define CLK 12 // CLOCK (SRCLK)
#define PWM 13 // PWM
#define BRIGHT 255 // 0 is dark, 255 is full
#define STEP_MS 200 // how long each number stays on screen
// One byte per digit. Bit 0 is segment A, bit 6 is G, bit 7 is the point.
const uint8_t d[] = {
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
};
// buf[0] is the leftmost digit. It goes out first, so it travels furthest
// down the chain and ends up in the module at the far end.
void updateDisplay(const uint8_t *buf) {
digitalWrite(LAT, LOW);
for (int i = 0; i < NUM_DIGITS; i++)
shiftOut(SER, CLK, MSBFIRST, buf[i]);
digitalWrite(LAT, HIGH);
}
void setup() {
pinMode(SER, OUTPUT);
pinMode(LAT, OUTPUT);
pinMode(CLK, OUTPUT);
uint8_t blank[NUM_DIGITS];
for (int i = 0; i < NUM_DIGITS; i++) blank[i] = 0x00;
updateDisplay(blank); // a register powers up holding anything
analogWrite(PWM, BRIGHT); // only now let the 12 V reach the digits
}
void loop() {
uint8_t b[NUM_DIGITS];
unsigned long limit = 1;
for (int i = 0; i < NUM_DIGITS; i++) limit *= 10;
limit -= 1; // 9, 99, 999 …
for (unsigned long n = 0; n <= limit; n++) {
unsigned long t = n;
for (int i = NUM_DIGITS - 1; i >= 0; i--) {
b[i] = d[t % 10]; // the rightmost digit of what is left
t /= 10; // drop it
}
updateDisplay(b);
delay(STEP_MS);
}
}No library. shiftOut() and analogWrite() are in the ESP32 Arduino core. PWM is driven with analogWrite() only, 255 for full brightness: on core 3.x a digitalWrite() to a pin that analogWrite() has already claimed does nothing.
When it does not work
Check PWM first. The pad ships open, so the digits get no 12 V until GPIO13 drives PWM, and the sketch only does that at the end of setup(). If it is still dark, measure 12 V at the first module's 12V pin with the black probe on the S3's GND. A reading there and none at the second module means the 12 V jumper between them is the fault.
Because it worked on the desk, not by the datasheet. On 5 V the 74HC595 wants more than 3.15 V before an input counts as high, and an S3 pin gives 3.3 V at best. That margin is gone with a longer wire, a warmer room or a different module. On 3V3 the same chip is comfortably inside its rating.
The data jumper of that join is the suspect: (QH) DATAOUT on the first module's OUT edge to DATAIN on the second's IN edge. Then CLOCK and LATCH of the same join, which the second module needs as much as the first. Power off and check each of the eight with a continuity test.
The module wired to the S3 shows the ones digit; the far end shows the leftmost. That is the chain working. Move the modules on the desk, not the wires: the S3 goes on the right-hand end of the row.
This page keeps the S3 on its own USB supply on purpose: two supplies and one ground, and nothing to get wrong. The S3's GND and the adapter's minus meet on the module, on the two GND pins of the IN edge, which are the same copper.
The same counting sketch on an Uno, line by line, and the one number worth changing while you test the wiring.
Count from 00 to 99 →Edit this page — content/books/seg4/chain-on-an-esp32-s3.mdx
Questions about this product
See what other owners have asked, and read their solutions.
4″ 7-Segment LED Display with 74HC595
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.