Pico LED Matrix Shield – LED Control

Published by frenoy on

The shield contains a total of 24 LEDs connected in a matrix consisting of 8 rows and 3 columns. The LEDs are controlled using 3 data lines that are connected to two shift registers (74HC595). If you are new to the world of shift-registers, then we highly recommend that you read through this post on the circuit theory before continuing. This post will walk you through the demo program for the shield that you can use to create your own patterns.

Mounting The Shield On A Pico:

You will need to solder the appropriate header pins for the Pico as well as the shield. We prefer using the following combination:

You then need to mount the shield in the correct orientation as shown below:

Please make sure you correctly line up the 5V, GND pins of the Pico and shield or else you may damage the shield. Use the Pico pin-out card to confirm if necessary.


The shield was designed to be used with a Pico as mentioned above, but there’s no reason why it can’t be used with a breadboard or any other Arduino board. If you decide to wire it manually, then please follow the instructions below:

We need 3 communication lines for the shield as follows:

  • DS: Connect this to D2 on the microcontroller board
  • ST: Connect this to D3 on the microcontroller board
  • SH: Connect this to D4 on the microcontroller board

We also need 5V and GND which can be obtained from the microcontroller.

When first powered ON, all the LEDs on the shield will light up. This is normal.

Interfacing Requirements:

In order to communicate with the shift registers, we need to pull the latch pin LOW, send the byte values corresponding to the row signals (let’s call this the row-byte), we then need to send the byte values corresponding to the column signals (column-byte) and we finally need to pull the latch pin HIGH again to signal the end of communication.

The exact value of the row-byte and column-byte depends on which LEDs you want to turn ON. You can, of course, compute these yourself, but we’ve decided to include a few example functions which will help you to quickly create what you’re looking for – whether you want to control individual LEDs, or multiple LEDs. So let’s take a look at these next.

Controlling Single LEDs:

Controlling individual LEDs is extremely simple and we’ve created a singleLED() function so that you don’t have to compute the row and column byte values manually.

Simply pass the integer value of the LED that you would like to turn ON and it will automatically do that for you.


singleLED(1) will turn ON the first LED and switch OFF all the others. singleLED(13) will turn ON LED 13 only.

You can download and run the following sketch to help you understand better.

The following GIF illustrates how the LEDs light up:

Controlling Multiple LEDs:

Once you know how to control single LEDs, it’s not that difficult to extend this understanding to control multiple LEDs at the same time. We’ve gone ahead and created a multipleLED function and have defined a few pre-processor directives (a.k.a. #define) to simply this for you.

The multipleLED(COLx, ROWx) function takes two arguments: column byte and row byte which are directly passed on to the shift registers. You can compute these yourself but it’s much easier to use the pre-processor directives (ROW1, ROW2,…,ROW8, COL1, COL2, COL3).


multipleLED(COL1, ROW1) will turn ON the LED that’s connected to both column 1 and row 1 which is none other than LED1. Similarly, multipleLED(COL3, ROW4 & ROW5) will turn ON LEDs 20 & 21.

Please keep in mind that only a single COLx value must be sent with each function call. If LEDs across multiple columns need to be turned ON at the same time then you will need multiple function calls as follows:

multipleLED(COL1, ROW1 & ROW2 & ROW7 & ROW8);

multipleLED(COL2, ROW3 & ROW4 & ROW5 & ROW6);

multipleLED(COL3, ROW4 & ROW5);

The function call above turns ON the following LEDs:

  • LED1, LED2, LED7, LED8 – from column 1
  • LED11, LED12, LED13, LED14 – from column 2
  • LED20, LED21 – from column 3

Keep in mind that the microcontroller is multiplexing between the columns, which means that the first function call only turns ON the LEDs in column 1, the second only turns ON the LEDs in column 2 and the third only turns ON the LEDs in column 3. The microcontroller rapidly switches between these three columns and our eyes perceive all the LEDs as being turned ON simultaneously.

All the LEDs in a particular column can be turned OFF using ROW0 while all the LEDs in a particular column can be turned ON using ROW9.

multipleLED(COL3, ROW9) will turn ON all the LEDs in column 3, so that’s LEDs 17…24 while multipleLED(COL3, ROW0) will turn OFF the above-mentioned LEDs.

You can download and run the following sketch to help you understand better.

The following GIF illustrates how the LEDs light up:

One major drawback here is that the microcontroller needs to constantly refresh the columns within 20ms or else there will be noticeable flicker. You can carry out other tasks but you need to ensure that you refresh the LEDs every 20ms to avoid the flicker.

You can create interesting patterns using the functions above, but if you want a more organized approach to handling patterns then we could recommend using something like a state machine which keeps tracks of the current pattern being displayed and switches to the next using the switch-case statement.

Categories: Piksey Pico