Home
Min
Unmin
Wisdom
Give-a-try
>>
>>
Eyelet
<<
<<

ERROR

Error fetching content.

Basic LED matrix messaging

If one is about to make MCU display showing some text, there are needs:

  1. Important definitely is to have some characters to show, i.e. some font.
  2. And while display is only 5×5, characters need to be scrolled in some pertinent manner. Thus some logic is needed.
  3. Also one needs to communicate demands to display. Nobody want this building from scratch for its incredeble complexity so using just microbit-v2 seems fine.

Font 🌐

Let go through font. Declaring character as array of rows or columns is on easy side. Simplest case regonizes bipolar state on = 1, off = 0. Code block bellow shows shape resembling accomplished G letter quite well.

let gr = [
      [0, 1, 1, 1, 1],
      [1, 0, 0, 0, 0],
      [1, 0, 1, 1, 1],
      [1, 0, 0, 0, 1],
      [0, 1, 1, 1, 1],
    ];
    
let gc = [
      [0, 1, 1, 1, 0],
      [1, 0, 0, 0, 1],
      [1, 0, 1, 0, 1],
      [1, 0, 1, 0, 1],
      [1, 0, 1, 1, 1],
  ];

Aforementioned row/column prudently turns into array also. Array of numbers. Declaring letter as array of columns makes it much more less readable. Let check with scheme.

Schematic G representation

Scheme shows how column/row array will be ordered when reading declaration from respective starts, for chosen row/columns of known letter G.

Why this can be important? Not really much because user code can easily accomodate traversing to fit its needs. By needs should be understand scrolling direction and input matrix mapping to physical layout of LED array. Of importance is only its homogenicity among font.

Continuing on font, one can easily imagine that maintaining file of characters defined as arrays of arrays in not really managable. For better understanding let bring in idea of 15×15 display. For this purpose character defintion can be flatten to array of numbers where number is something already shown in schema figure.

Taking G middle row in left-right ordering, number is 0b10111 = 0x17.

let gb = [
      0b01111,
      0b10000,
      0b10111,
      0b10001,
      0b01111,
    ];

let gb = [0b01111, 0b10000, 0b10111, 0b10001, 0b01111,];
    
let gx = [0xf, 0x10, 0x17, 0x11, 0xf,];

Now G letter is more conceise. Of course hex representation is visually unreadable in any means.

On Scrolling 🌐

For scrolling we need to know display orientation and its matrix mapping. And scrolling direction.

microbit:v2 LED matrix

Looking at this display, mapping is left-top [0;0], right-bottom [4;4] since lighting LEDs correspond to matrix bellow.

let mtx = [
        [1, 0, 0, 0, 1],
        [0, 1, 0, 1, 0],
        [0, 0, 1, 0, 0],
        [0, 1, 0, 0, 0],
        [1, 0, 0, 0, 0],
    ];

Only direction is lasting. Let go with scrolling from top to bottom.

Show me code, please! 🌐

We matured to some code exhibition. As code dependencies are out of scope for this article, these are only listed and not debated.

//main.rs
▶ details…
#![no_std]
#![no_main]

use cortex_m_rt::entry;
use panic_halt as _;

use microbit::{board::Board, display::blocking::Display, hal::Timer};
#[entry]
fn entry() -> ! {
    let board = Board::take().unwrap();

    let mut timer = Timer::new(board.TIMER0);
    let mut display = Display::new(board.display_pins);

    let mut mtx = [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
    ];

    let gb = [0b01111, 0b10000, 0b10111, 0b10001, 0b01111];

    for gb_rowix in (0..=4).rev() {
        for rowix in (1..=4).rev() {
            let rowix_prev = rowix - 1;
            for colix in 0..5 {
                mtx[rowix][colix] = mtx[rowix_prev][colix];
            }
        }

        let gb_row = gb[gb_rowix];

        let mut mask_shift = 4;
        for colix in 0..5 {
            let mask = 1 << mask_shift;
            mtx[0][colix] = if gb_row & mask == mask { 1 } else { 0 };

            mask_shift -= 1;
        }

        display.show(&mut timer, mtx, 200);
    }

    display.show(&mut timer, mtx, u32::MAX);    

    loop {}
}
// cargo flash --target thumbv7em-none-eabihf --chip nRF52833_xxAA --release
▶ Cargo.toml    
[package]
name = "basic_led_matrix_messaging"
version = "0.0.1-alpha"
edition = "2021"
authors = [" software9119.technology" ]
license = "MIT"

[dependencies]
microbit-v2 = "0.13.0"
cortex-m = "0.7.7"
cortex-m-rt = "0.7.3"
panic-halt = "0.2.0"

Carful reader's eye likely noted some transformation done to G letter before putting into LED matrix:

  1. gb_rowix in (0..=4).rev() – 1st must appear bottom line of G.
  2. rowix in (1..=4).rev() – not really transformation, simple shifting rows from bottommost one. This is reflective to scroll direction.
  3. mask_shift = 4; – since G row is declared left-right, it must be traversed from leftmost bit to rightmost.
G letter top-bottom showcase

Result meets expectation. G letter comes from top to bottom.

For more developed topics on this check with:

  1. mcu_chats_with_you
  2. ug_max documentation on docs.rs