Arduino Uno Q In C - Text On The LED Matrix
Written by Harry Fairhead   
Monday, 26 January 2026
Article Index
Arduino Uno Q In C - Text On The LED Matrix
ArduinoGraphics

The Uno Q has a small LED matrix that could be really useful if it could display text. It can and Harry Fairhead shows you how.  - This is an extract from his book on the Uno Q, due to be published in February. 

Programming The Uno Q In C 
Using Arduino Core & Zephyr

By Harry Fairhead

unoqC360

Available as a softback, hardback and kindle from Amazon in the first week of February

Contents

       Preface

  1. The Uno Q – Before We Begin
  2. Getting Started
  3. Getting Started With GPIO
  4. Simple Output 
  5. Some Electronics
  6. Simple Input
  7. Advanced Input – Interrupts
  8. Pulse Width Modulation
      Extract: 
    Text On The LED Matrix ***NEW!!!
  9. Controlling Motors And Servos
  10. Getting Started With The SPI Bus
  11. Using Analog Sensors
  12. Using The I2C Bus
  13. One-Wire Protocols
  14. Zephyr For Task Management
  15. Zephyr Devices
  16. The Bridge 

In chapter but not in this extract:

  • Pulse Width Modulation
  • Some Basic PWM Facts
  • Arduino Simple DAC
  • Controlling an LED
  • Digital to Analog
  • Zephyr PWM
  • Zephyr Sine Wave
  • Frequency Modulation

The LED Matrix

The 8x13 blue LED matrix is also an example of using PWM to implement gray-level images. The LEDs are connected in a row/column layout in the form of a tree – the first row has one LED pair, the second two, the third three and so on. You can see the basic idea from this portion of the circuit diagram:

LEDMatrix

The GPIO lines used are PF0 to PF11 and they are not part of the Arduino Core which means you have to use Zephyr functions to access them.

There are two LED connected to each pair of lines and which one switches on depends on the polarity of the GPIO lines. If both are at zero or one then both LEDs are off. If we set MATRIX_0 to 1 and MATRIX_1 to 0 then LED1 lights up. To stop all of the other LEDs connected to MATRIX_0 turning on, all the other lines have to be set to high impedance, i.e. input. So to turn LED 1 on we need to set the lines to:

*********01

where * means high impedance or input mode.

To turn just LED 2 on we need to set:

*********10

To turn just LED 3 on we need to set MATRIX_0 to 1 and MATRIX_2 to 0 and, to stop the other LEDs turning on, the other lines have to be set to input:

********0*1

To turn just LED 4 on we need to set:

********1*0 

To turn on each odd numbered LED in the first column one after the other we would use:

*********01
********0*1
*******0**1
******0***1
*****0****1
****0*****1
***0******1
**0*******1
*0********1
0*********1

and for the even numbered LEDs we would use the logical not of the bit patterns.

To turn each odd numbered LED on in the second column we would use:

********01*
*******0*1*
******0**1*
*****0***1*
****0****1*
***0*****1*
**0******1*
*0*******1*
0********1*

This is a very clever way to implement a matrix of LEDs. A standard 8x13 matrix implemented in the straightforward way with one LED at each crossing point of a grid of GPIO lines would need 104 GPIO lines. This approach, with three coding states and two LEDs at each cross point, uses just 11 GPIO lines.

You can drive the LEDs directly, but only if you use Zephyr GPIO functions. For example, matrix1 clears the matrix and turns LED1 on:

static const struct device *port =
                    DEVICE_DT_GET(DT_NODELABEL(gpiof));
void setup() {
  for (int pin = 0; pin < 11; pin++) {
    gpio_pin_configure(port, pin, GPIO_INPUT);
  };
  gpio_pin_configure(port, 0, GPIO_OUTPUT_HIGH);
  gpio_pin_configure(port, 1, GPIO_OUTPUT_LOW);
}
void loop() {
}

You could continue in this manner and develop a function to set the LED at x,y in the matrix, but it is much simpler to use the library provided by Arduino to use the LED matrix which has most of the functions you need to work with the LED display.

To use the library you create an instance of the matrix class:

Arduino_LED_Matrix matrix;

and use its begin method to initialize it:

matrix.begin();

You can stop using it with:

matrix.end();

Rather than giving you a way of setting single pixels, Matrix provides functions which will render a grayscale image stored in a buffer – the grayscale is delivered by using PWM on the activating GPIO line.

To do this you first need to define how many gray levels you are going to work with:

setGrayscaleBits(n);

where n sets 2n gray levels. For example:

setGrayscaleBits(1);

creates a two-level image, i.e. a black and blue image. The display only shows 8 gray levels, i.e. n=3, and the specified gray level range is mapped into this.

To draw the image use:

draw(buf);

where buf is a uint8_t with 104 elements specifying the gray level of each LED. To clear the display use:

clear();

The documentation give the following simple example, matrix2:

#include <Arduino_LED_Matrix.h>
uint8_t logo[104] = {
    0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,1,1,1,0,0,0,1,1,1,0,0,
    0,1,0,0,0,1,0,1,0,0,0,1,0,
    1,0,0,0,0,0,1,0,0,1,0,0,1,
    1,0,1,1,1,0,1,0,1,1,1,0,1,
    1,0,0,0,0,0,1,0,0,1,0,0,1,
    0,1,0,0,0,1,0,1,0,0,0,1,0,
    0,0,1,1,1,0,0,0,1,1,1,0,0
};
Arduino_LED_Matrix matrix;
void setup() {
  matrix.begin();
  matrix.setGrayscaleBits(1);
  matrix.draw(logo);
  matrix.clear()
}
void loop() {
}

The call to GrayscaleBits sets the display to monochrome, i.e. two levels and the buffer defines the bitmap of the Arduino logo using two levels.

For another example, matrix3, consider drawing a gradient fill:

#include <Arduino_LED_Matrix.h>
uint8_t grayScale[104];
Arduino_LED_Matrix matrix;
void setup() {
  for(int i=0;i<104;i++){
    grayScale[i]=i/13;
  }
  matrix.begin();
  matrix.setGrayscaleBits(3);
  matrix.draw(grayScale);
}
void loop() {
}  


Last Updated ( Tuesday, 27 January 2026 )