Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Arduino & Microcontrollers

Arduino 7-Segment Multiplexing: Drive 4 Digits on Few Pins

Arduino 7-Segment Multiplexing: Drive 4 Digits on Few Pins

March 11, 2026 /Posted byJayesh Jain / 0

Driving a 4-digit 7-segment display might seem like it needs dozens of pins — after all, each digit has 8 segments (a through g, plus decimal point). But with arduino 7 segment multiplexing, you can drive all four digits using just 11 digital pins by switching between digits so fast that the human eye perceives them all as lit simultaneously. In this tutorial, you’ll learn the theory behind multiplexing, how to wire a common-cathode or common-anode 4-digit display, and how to write clean, interrupt-driven code that doesn’t block your main sketch.

Table of Contents

  • How Multiplexing Works
  • Common-Cathode vs Common-Anode
  • Wiring a 4-Digit Display
  • Digit and Character Patterns
  • Basic Multiplexing Code
  • Interrupt-Driven Multiplexing
  • Controlling Brightness
  • FAQ

How Multiplexing Works

A 4-digit 7-segment display has 4 separate digit enable pins (one per digit) and 8 shared segment pins (a-g + dp). All four digits share the same segment wires. At any given moment, you can only light one digit at a time because all segment pins are wired together.

Multiplexing works by exploiting persistence of vision: if you cycle through all four digits faster than ~50 times per second (50 Hz), the human eye doesn’t perceive the flickering — it sees all four digits lit at once. In practice, you switch digits at 200-1000 Hz (a 1-5 ms dwell time per digit) for a flicker-free display even when viewed through a phone camera.

The sequence is:

  1. Disable all digit pins (turn off all digits)
  2. Set segment pins for digit 0’s character
  3. Enable digit 0
  4. Wait 2-3 ms
  5. Disable digit 0
  6. Set segment pins for digit 1’s character
  7. Enable digit 1
  8. Wait 2-3 ms
  9. … and so on for digits 2 and 3
  10. Repeat from step 1

With 4 digits each shown for 2.5 ms, one full cycle takes 10 ms = 100 Hz refresh rate — smooth and flicker-free.

Recommended: Multifunction Shield For Arduino Uno / Leonardo — includes a 4-digit 7-segment display already wired and ready to go, perfect for learning multiplexing without any wiring setup.

Common-Cathode vs Common-Anode

Before wiring anything, you must know which type of display you have:

Common-Cathode (CC): All cathodes (negative terminals) of the LEDs in each digit are connected together at the digit pin. To enable a digit, you set its pin LOW (connecting cathodes to ground). To light a segment, you set the segment pin HIGH. Most budget displays are common-cathode.

Common-Anode (CA): All anodes (positive terminals) are connected at the digit pin. To enable a digit, you set its pin HIGH. To light a segment, you set the segment pin LOW (active-low logic). This is the opposite logic — easy to mix up!

Check your display’s datasheet or do a quick test: connect a coin cell (3V) between the common pin and a segment pin. If the segment lights, you know the polarity and can determine the type.

The code in this tutorial uses a common-cathode display. If you have common-anode, simply invert all HIGH/LOW states in the digit and segment functions.

Wiring a 4-Digit Display

A typical 4-digit common-cathode 7-segment display has 12 pins: 8 segment pins (a, b, c, d, e, f, g, dp) and 4 digit pins (D1, D2, D3, D4).

Connect as follows to an Arduino Uno:

Display Pin Arduino Pin Notes
Segment a D2 via 220Ω resistor
Segment b D3 via 220Ω resistor
Segment c D4 via 220Ω resistor
Segment d D5 via 220Ω resistor
Segment e D6 via 220Ω resistor
Segment f D7 via 220Ω resistor
Segment g D8 via 220Ω resistor
Segment dp D9 via 220Ω resistor
Digit 1 (leftmost) D10 direct connection
Digit 2 D11 direct connection
Digit 3 D12 direct connection
Digit 4 (rightmost) D13 direct connection

Important: Place a 220Ω current-limiting resistor in series with each segment pin (8 resistors total). Without resistors, you’ll exceed the Arduino’s 40 mA per-pin limit when multiple segments in a single digit are lit simultaneously. The resistors go on the segment pins, not the digit pins — this ensures the current stays safe regardless of how many segments are active.

Recommended: Arduino Uno R3 Beginners Kit — comes with resistors, breadboard, and jumper wires needed for this exact project, saving you from sourcing components separately.

Digit and Character Patterns

Each digit is encoded as a byte where each bit represents one segment: dp, g, f, e, d, c, b, a (MSB to LSB). For a common-cathode display where HIGH = segment on:

// Segment pattern lookup table (common-cathode)
// Bit order: dp, g, f, e, d, c, b, a
// Example: digit '0' lights a,b,c,d,e,f (not g, not dp)
const byte DIGITS[10] = {
  0b00111111, // 0 — a,b,c,d,e,f
  0b00000110, // 1 — b,c
  0b01011011, // 2 — a,b,d,e,g
  0b01001111, // 3 — a,b,c,d,g
  0b01100110, // 4 — b,c,f,g
  0b01101101, // 5 — a,c,d,f,g
  0b01111101, // 6 — a,c,d,e,f,g
  0b00000111, // 7 — a,b,c
  0b01111111, // 8 — all segments
  0b01101111  // 9 — a,b,c,d,f,g
};

// Special characters
const byte SEG_BLANK = 0b00000000; // all off
const byte SEG_DASH  = 0b01000000; // just g (middle bar)
const byte SEG_DP    = 0b10000000; // just decimal point

// OR the DP bit onto any digit to add decimal point:
// DIGITS[3] | SEG_DP → '3.'

Basic Multiplexing Code

Here is a complete sketch that displays a 4-digit number (e.g., a counter) using the multiplexing technique in the main loop:

// 4-digit 7-segment display multiplexing — basic version

const int SEG_PINS[8] = {2, 3, 4, 5, 6, 7, 8, 9}; // a,b,c,d,e,f,g,dp
const int DIGIT_PINS[4] = {10, 11, 12, 13};          // D1,D2,D3,D4

const byte DIGITS[10] = {
  0b00111111, 0b00000110, 0b01011011, 0b01001111,
  0b01100110, 0b01101101, 0b01111101, 0b00000111,
  0b01111111, 0b01101111
};

byte displayBuffer[4] = {0, 0, 0, 0}; // What to show on each digit

void setup() {
  for (int i = 0; i < 8; i++) pinMode(SEG_PINS[i], OUTPUT);
  for (int i = 0; i < 4; i++) {
    pinMode(DIGIT_PINS[i], OUTPUT);
    digitalWrite(DIGIT_PINS[i], HIGH); // HIGH = digit OFF (common-cathode: digit on = LOW)
  }
}

void setSegments(byte pattern) {
  for (int i = 0; i > i) & 1);
  }
}

void displayNumber(int number) {
  // Split number into 4 digits
  displayBuffer[0] = (number / 1000) % 10;
  displayBuffer[1] = (number / 100) % 10;
  displayBuffer[2] = (number / 10) % 10;
  displayBuffer[3] = number % 10;
}

void multiplexDisplay() {
  for (int d = 0; d < 4; d++) {
    // Blank all digits first (ghost prevention)
    for (int i = 0; i = 1000) {
    lastUpdate = millis();
    counter = (counter + 1) % 10000;
    displayNumber(counter);
  }
  
  multiplexDisplay(); // Call frequently — takes ~10ms per full cycle
}

Ghost image prevention: The key line is blanking all digits before switching segments. Without it, you get “ghosting” — the previous digit’s segments briefly appear on the next digit during the transition.

Interrupt-Driven Multiplexing

The basic approach above blocks the main loop for 10 ms every cycle. For any project that needs concurrent tasks (reading sensors, communicating over serial, etc.), you need interrupt-driven multiplexing using a timer interrupt.

#include <MsTimer2.h>  // Install via Library Manager

volatile byte displayBuffer[4] = {0, 0, 0, 0};
volatile byte currentDigit = 0;

const int SEG_PINS[8] = {2, 3, 4, 5, 6, 7, 8, 9};
const int DIGIT_PINS[4] = {10, 11, 12, 13};

const byte DIGITS[10] = {
  0b00111111, 0b00000110, 0b01011011, 0b01001111,
  0b01100110, 0b01101101, 0b01111101, 0b00000111,
  0b01111111, 0b01101111
};

void multiplexISR() {
  // Blank all
  for (int i = 0; i < 4; i++) digitalWrite(DIGIT_PINS[i], HIGH);
  
  // Set segments for current digit
  byte pattern = DIGITS[displayBuffer[currentDigit]];
  for (int i = 0; i > i) & 1);
  }
  
  digitalWrite(DIGIT_PINS[currentDigit], LOW);
  currentDigit = (currentDigit + 1) % 4;
}

void setup() {
  for (int i = 0; i < 8; i++) pinMode(SEG_PINS[i], OUTPUT);
  for (int i = 0; i < 4; i++) {
    pinMode(DIGIT_PINS[i], OUTPUT);
    digitalWrite(DIGIT_PINS[i], HIGH);
  }
  
  MsTimer2::set(3, multiplexISR); // Call every 3ms
  MsTimer2::start();
}

void loop() {
  // Main loop is completely free for other tasks!
  // Update display buffer any time:
  int val = analogRead(A0); // Example: show ADC reading
  displayBuffer[0] = (val / 1000) % 10;
  displayBuffer[1] = (val / 100) % 10;
  displayBuffer[2] = (val / 10) % 10;
  displayBuffer[3] = val % 10;
  delay(100); // Update 10x/sec
}
Recommended: Arduino Frequency Counter Kit with 16×2 LCD Display — a great project that applies similar display-driving techniques to measure and display frequencies, an excellent next step after mastering 7-segment multiplexing.

Controlling Brightness

Brightness control in a multiplexed display is achieved by adjusting the duty cycle — how long each digit stays on within its time slot. Two approaches:

Method 1 — Dwell time adjustment: Shorten the active time and add a blank period. For 50% brightness, dwell for 1.25 ms then blank for 1.25 ms before moving to the next digit. Total cycle time stays the same, but each digit is on for half as long.

Method 2 — Current-limiting resistor change: Replace the fixed 220Ω resistors with a potentiometer or use a PWM-driven transistor on each digit pin. This changes the current through the LEDs, changing their brightness. A transistor (2N2222 or similar) between the digit pin and ground allows the Arduino pin to switch high currents cleanly.

For professional builds, use a dedicated driver IC like the MAX7219 or TM1637. These handle multiplexing, brightness, and scanning entirely in hardware over a simple SPI or 2-wire interface, freeing your Arduino from all display duties and requiring only 2 wires instead of 11.

Recommended: Arduino Mega 2560 R3 Board — with 54 digital pins, the Mega can drive multiple 7-segment displays without multiplexing at all, or drive multiple multiplexed groups simultaneously for large scoreboard or industrial display projects.

FAQ

Why is my 7-segment display showing ghost images on wrong digits?

This is the most common multiplexing problem. The cause is switching the segment pins while a digit is still enabled, briefly showing the new pattern on the old digit. Fix: always disable ALL digit pins first, then set the new segment pattern, then enable only the correct digit pin. The blank period also prevents ghost images.

How fast should I multiplex? Is faster always better?

Faster multiplexing means each digit is on for less time, which reduces effective brightness. Too slow (below 50 Hz total refresh) causes visible flickering. The sweet spot is 200-500 Hz total refresh rate, which means 50-125 ms per digit with 4 digits. For timer-based multiplexing, set your interrupt interval to 2-3 ms per digit.

Do I need current-limiting resistors on every segment pin?

Yes, always. Each segment is an LED and needs a current-limiting resistor. If you skip them, you may damage either the display LEDs or the Arduino’s output pins. Use 220Ω for 5V operation (gives approximately 10-15 mA per segment, typical for indicator brightness). For brighter displays, 100Ω is common but check your Arduino’s total current budget.

Can I use the same multiplexing technique for larger displays (6 or 8 digits)?

Yes — simply add more digit pins and extend the displayBuffer array. However, with 8 digits each shown for 2.5 ms, your refresh rate drops to 50 Hz (8 × 2.5 ms = 20 ms cycle = 50 Hz), which is still acceptable but just at the edge of flicker visibility. For 8+ digits, use a driver IC (MAX7219 can handle up to 8 digits with automatic multiplexing).

What’s the maximum current an Arduino pin can supply for driving segment displays?

Each Arduino Uno digital output pin can source or sink a maximum of 40 mA, and the total current across all I/O pins should not exceed 200 mA. With multiplexing, only one digit is active at a time, and that digit can have up to 7 segments lit simultaneously — that’s up to 7 × 15 mA = 105 mA. Use transistors on the digit pins to handle this current safely, with the Arduino pin driving the transistor base only.

Take your display skills further. Once you’ve mastered multiplexing, you’re ready for shift registers (74HC595), driver ICs (MAX7219), and full alphanumeric matrix displays. Browse our complete collection of Arduino modules and display components at Zbotic to find everything you need for your next display project.

Tags: 7 segment display, Arduino, display, Electronics, LED, multiplexing, tutorial
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Arduino String vs char Array: ...
blog arduino string vs char array memory efficient coding tips 594742
blog arduino soil npk sensor measure fertilizer levels in soil 594752
Arduino Soil NPK Sensor: Measu...

Related posts

Svg%3E
Read more

Arduino Batch Programming: Flash Multiple Boards Quickly

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Based Radar System with Ultrasonic Sensor

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Automatic Plant Monitor: Sunlight, Moisture, Temperature

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Lie Detector: GSR Sensor Polygraph Project

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Metal Detector: Build a Treasure Finder

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now