PIC Microcontroller LED Matrix Multiplexing Tutorial

In this tutorial, you will learn how to build and program an LED matrix display with multiplexing using a PIC microcontroller. Multiplexing is a technique that allows you to control multiple rows and columns of LEDs efficiently, using fewer I/O pins than would otherwise be required. By rapidly switching between rows (or columns) and updating the LEDs at high frequency, our eyes interpret the combined display as being continuously lit. This is a great project for those looking to sharpen their skills in embedded programming and hardware design on PIC microcontrollersIntroduction to PIC: Exploring the Basics of Microcontroller ArchitectureIntroduction to PIC: Exploring the Basics of Microcontroller ArchitectureExplore the core principles of PIC microcontroller architecture, including Harvard design, RISC processing, and efficient memory organization..

Introduction🔗

Imagine a neat grid of LEDs that can display text, patterns, or animations. To bring such a display to life with a PIC, we take advantage of timers, interrupt routines, and digital I/OMastering Digital I/O on PIC MCUs with Practical ExamplesMastering Digital I/O on PIC MCUs with Practical ExamplesLearn hands-on techniques for configuring and using digital I/O pins on PIC microcontrollers to control LEDs, sensors, and more in practical projects.. You will discover how to organize your LED matrix, define a scanning strategy, and structure your code so the display remains stable while the PIC handles other tasks in the background.

Purpose🔗

The primary goal is to:

This hands-on project gives you a foundation to adapt the techniques for a variety of display sizes and styles.

Development Environment🔗

You may use any PIC microcontrollerIntroduction to PIC: Exploring the Basics of Microcontroller ArchitectureIntroduction to PIC: Exploring the Basics of Microcontroller ArchitectureExplore the core principles of PIC microcontroller architecture, including Harvard design, RISC processing, and efficient memory organization. that offers enough I/O pins to drive an LED matrix: for instance, a PIC16F or PIC18F device. Common development setups include:

Components and Requirements🔗

Below is a summary of the key hardware and software components you will need:

ComponentDescription
PIC MicrocontrollerE.g., PIC16F877A or PIC18F45K20, ensuring enough I/O pins for the matrix.
LED Matrix (e.g., 8×8)64 LEDs arranged in rows and columns. Variations (5×7, 16×16, etc.) are possible.
Current-Limiting ResistorsOne resistor per row or column, depending on your wiring configuration (often 220 Ω to 470 Ω).
Transistors (optional, if needed)For larger displays or higher current demands, transistors or MOSFETs can drive the rows or columns.
Power Supply5 V (typical) regulated supply with sufficient current capacity for your LED matrix and PIC.
Breadboard/PCB and WiringFor simple prototypes or more permanent solutions.
MPLAB X IDE and XC8 CompilerDevelopment environment for writing and compiling the project.

Schematics and Theory of Operation🔗

Basic LED Matrix Wiring

An 8×8 LED matrix typically has 8 row lines and 8 column lines:

  • Cathode row configuration: each row line is the common cathode of the LEDs in that row, and each column line is the anode.
  • Anode row configuration: each row line is the common anode, and each column line is the cathode.

Either approach works, but you must adapt your drive method accordingly. For an 8×8, you have 16 lines in total (8 rows + 8 columns). You connect each line to a microcontroller pin (or to a transistor driven by that pin, especially if each row or column might draw significant current).

Multiplexing Concept

When multiplexing, you quickly switch through each row (one at a time), turning corresponding column pins on or off. For instance:

1. Activate Row 1 (and set the desired pattern on columns).

2. Turn off Row 1, activate Row 2 (set the pattern for that row).

3. Turn off Row 2, activate Row 3, … and so on.

By cycling through rows at a sufficiently high frequency (e.g., hundreds of times per second), human vision perceives the entire 8×8 grid as being continuously lit.

Implementation Steps🔗

Pin Mapping

A typical pin mapping example is shown in the table below (you can adapt based on your hardware constraints):

PIC Pin (Example)FunctionLED Matrix Connection
RA0Column 0Column 0 (through resistor)
RA1Column 1Column 1 (through resistor)
RA2Column 2Column 2 (through resistor)
RA3Column 3Column 3 (through resistor)
RA4Column 4Column 4 (through resistor)
RA5Column 5Column 5 (through resistor)
RB0Column 6Column 6 (through resistor)
RB1Column 7Column 7 (through resistor)
RC0Row 0Common row line 0
RC1Row 1Common row line 1
RC2Row 2Common row line 2
RC3Row 3Common row line 3
RC4Row 4Common row line 4
RC5Row 5Common row line 5
RC6Row 6Common row line 6
RC7Row 7Common row line 7
  • (Always consult your PIC datasheet for exact port naming and available pins.)

Code Structure

One typical approach to multiplexing:

1. Define row patterns in a lookup table or array. For each row, store the bit pattern for the columns that should be ON or OFF.

2. Use a timer interruptImplementing Interrupt-Driven Systems for Real-Time ApplicationsImplementing Interrupt-Driven Systems for Real-Time ApplicationsLearn to configure and optimize PIC microcontroller interrupts for real-time performance. Enhance responsiveness and efficiency using best practices. so that every few milliseconds the next row is updated. This ensures the LED matrix is refreshed regularly without manually timing updates in the main loop.

3. Update outputs by:

  • Turning off the previous row.
  • Setting the column outputs for the new row’s pattern.
  • Turning on the new row.

Below is a simplified C-style code outline using pseudo-code:

// Example data array for 8 rows of 8 columns
// Each byte represents column states for a given row
const unsigned char pattern[8] = {
    0b10101010, // Row 0 pattern
    0b01010101, // Row 1 pattern
    0b11110000, // Row 2 pattern
    0b00001111, // Row 3 pattern
    0b11001100, // Row 4 pattern
    0b00110011, // Row 5 pattern
    0b11111111, // Row 6 pattern
    0b00000000  // Row 7 pattern
};
volatile unsigned char currentRow = 0;
void interrupt ISR(void) {
    if (TMR0IF) {           // Timer overflow interrupt flag
        TMR0IF = 0;         // Clear flag
        currentRow++;
        if (currentRow > 7) {
            currentRow = 0;
        }
        updateLEDMatrix(currentRow);
    }
}
void updateLEDMatrix(unsigned char row) {
    // Turn off all rows first
    // (Implementation depends on whether rows are active high or low)
    // Write the column pattern for the current row
    PORTA = pattern[row]; // Example if columns are on port A
    // Activate the selected row
    // e.g., RC0 through RC7 for row selection
    // Only the row pin corresponding to 'row' is activated
}
void main(void) {
    // Configure I/O, enable TMR0 (or any other timer),
    // set up interrupt, etc.
    while (1) {
        // Main loop can do other tasks
    }
}

Timer Configuration

Testing and Debugging🔗

1. Initial Check

Verify that each row and column pin on the PIC is driving the correct physical line on the LED matrix. A single misplaced line can scramble the displayed patterns.

2. Test Single Row

Before implementing full multiplexing, try lighting only Row 0 with a pattern. Ensure LEDs behave as expected when you toggle the column pins.

3. Check InterruptImplementing Interrupt-Driven Systems for Real-Time ApplicationsImplementing Interrupt-Driven Systems for Real-Time ApplicationsLearn to configure and optimize PIC microcontroller interrupts for real-time performance. Enhance responsiveness and efficiency using best practices. Frequency

Use a debugger or temporarily toggle another pin inside the timer interruptImplementing Interrupt-Driven Systems for Real-Time ApplicationsImplementing Interrupt-Driven Systems for Real-Time ApplicationsLearn to configure and optimize PIC microcontroller interrupts for real-time performance. Enhance responsiveness and efficiency using best practices. to verify the refresh rate is correct.

4. Adjust Brightness

If the display seems dim, experiment with shorter row duty time or adjust current-limiting resistors. Too much current can damage the LEDs or the PIC, so balance brightness and safety.

5. Scale Up

If expanding beyond 8×8, consider using shift registers or transistor arrays to handle higher current and free up I/O pins.

Practical Considerations🔗

  • Power Supply: Multiplexing reduces average current on each LED, but ensure your power supply can handle peak current when one row is fully lit.
  • Heat Management: Although each LED is lit only a fraction of the time, repeated scanning can still generate heat in drivers and resistors.
  • Extendibility: Use modular code that easily adapts to bigger matrices (16×16, 32×8, etc.).
  • Software Flexibility: The data array (e.g., “pattern[]”) can store anything from static images to scrolling text, provided your code updates the array contents.

Conclusion🔗

By using a multiplexed approach, a PIC microcontrollerIntroduction to PIC: Exploring the Basics of Microcontroller ArchitectureIntroduction to PIC: Exploring the Basics of Microcontroller ArchitectureExplore the core principles of PIC microcontroller architecture, including Harvard design, RISC processing, and efficient memory organization. can effectively drive an LED matrix while preserving valuable I/O pins for other tasks. The key to flawless multiplexing is a well-timed refresh loop, reliable column/row line control, and careful hardware connections. Once mastered, these principles can be extended to larger, more complex displays or adapted to advanced lighting effects that captivate and inform.

With the foundations covered in this project, you are prepared to customize patterns, text messages, or animations on your LED matrix. Experiment with different frame rates, brightness settings, and patterns to create your own unique and eye-catching applications. Enjoy your new multiplexed PIC-powered LED display!

Author: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

References🔗

Share article