This library has functions to easily send commands to a LED matrix, get the response, and definitions for all parameter types.
Supports Windows and Linux. Tested on Windows 11 and Linux Mint.
#include "FWLedMatrixLib/fw_led_matrix.h"
void main(){
// replace "COM3" with the path to your device
// so something like COM<number> on Windows
// and something like /dev/ttyACM0 on Linux
fwlm::LedMatrix led_matrix("COM3");
// set to half brightness
led_matrix.set_brightness(128);
// display the zig zag pattern
led_matrix.display_pattern(fwlm::Pattern::ZIG_ZAG);
}All the functions below are methods of fwlm::LedMatrix
set_brightness(uint8t value)- sets the brightness of the matrix tovalueget_brightness(uint8t *brightness_out)- gets the brightness and store it inbrightness_outdisplay_pattern(fwlm::Pattern pattern)- displays a pre-programmed pattern on the matrixset_sleep(bool sleep)- sets if the matrix is asleep or not tosleepget_sleep(bool *sleep_out)- gets is the matrix is asleep or not and stores it insleep_outset_animate(bool animate)- sets if the matrix is animating (scrolling what's on the matrix) or not toanimateget_animate(bool *animate_out)- gets if the matrix is animating and stores it inanimate_outget_version(fwlm::Version *version_out)- gets the firmware version of the matrix and stores it inversion_out
Every instance of fwlm::LedMatrix has an internal matrix where you can make changes using
fwlm::LedMatrix::blit().
There are two ways of drawing the internal matrix to the actual matrix:
fwlm::LedMatrix::draw_matrix_black_white()will draw the internal matrix to the actual matrix it interprets the values in the internal matrix as booleans (0 = OFF, 1 to 255 = ON)fwlm::LedMatrix::draw_matrix_greyscale()will draw the internal matrix to the actual matrix it interprets the values in the internal matrix as brightness values
the top-left corner is (0, 0), the bottom-right corner is (8, 33)
when using fwlm::LedMatrix::blit() the top left corner of the "image" is used as the anchor
so if you where trying to blit:
01010 | ░█░█░
01010 | ░█░█░
00000 | ░░░░░
10001 | █░░░█
01110 | ░███░
to the internal matrix at (2, 1)
the resulting internal matrix (assuming it was empty before) will look like this
000000000 | ░░░░░░░░░
000101000 | ░░░█░█░░░
000101000 | ░░░█░█░░░
000000000 | ░░░░░░░░░
001000100 | ░░█░░░█░░
000111000 | ░░░███░░░
000000000 | ░░░░░░░░░
000000000 | ░░░░░░░░░
000000000 | ░░░░░░░░░
... + 14 more empty rows ...
000000000 | ░░░░░░░░░
fwlm:LedMatrix::blit() can be used to blit a 2D "image" to the internal matrix
blit takes 3 arguments:
std::vector<std::vector<uint8_t>> datathis is the data to blit in column-major order meaningdatais astd::vectorof columns, each column is astd::vectorof bytes which are the values to blitunsigned int xthe x coordinate of the position to blit to, accepted values: 0 to (8 - the amount of columns), if x is greater than (8 - amount of columns)blitwill throwstd::out_of_rangeunsigned int ythe y coordinate of the position to blit to, accepted values: 0 to (33 - the height of the highest column), if x is greater than (33 - height of highest column)blitwill throwstd::out_of_range
fwlm::LedMatrix::set_pixel() can be used to set a single pixel value on the internal matrix
set_pixel takes 3 arguments
uint8_t valuethe value to write to the pixelunsigned int xthe x coordinate of the pixel to set, accepted values: 0 to 8, if x is greater than 8blitwill throwstd::out_of_rangeunsigned int ythe y coordinate of the pixel to set, accepted values: 0 to 33, if x is greater than 33blitwill throwstd::out_of_range
When playing a game most other commands will stop working correctly.
Unfortunately I can't get Tetris to work so it won't be explained here.
To start a game use fwlm::LedMatrix::game_start(), it's usage depends on what game you're starting.
To start Conway's Game of Life you need to pass two parameters to game_start like so:
led_matrix.game_start(fwlm::GameID::GAME_OF_LIFE, fwlm::GameOfLifeStartParam::<PATTERN_NAME>);Just replace <PATTERN_NAME> with any of the following:
CURRENT_MATRIXPATTERN_1BLINKERTOADBEACONGLIDERBLINKER_TOAD_BEACON
You can start Snake and Pong like so:
led_matrix.game_start(fwlm::GameID::<GAME_NAME>);Just replace <GAME_NAME> with any of the following:
SNAKEPONG
throws std::invalid_agrument if you pass the extra parameter to snake or pong, or if you don't pass the parameter to the game of life
Conway's game of life doesn't have any controls.
Games can be controlled using fwlm::LedMatrix::game_control().
What param to pass into game_control depends on the game that's being played.
fwlm::GameControl::UP- the snake's head will move upfwlm::GameControl::DOWN- the snake's head will move downfwlm::GameControl::LEFT- the snake's head will move leftfwlm::GameControl::RIGHT- the snake's head will move right
fwlm::GameControl::LEFT- Player 1's paddle will move left.fwlm::GameControl::RIGHT- Player 1's paddle will move right.fwlm::GameControl::LEFT2- Player 2's paddle will move left.fwlm::GameControl::RIGHT2- Player 2's paddle will move right.
Any game can be quit in 2 ways:
- using
fwlm::LedMatrix::game_quit() - using
led_matrix.game_control(fwlm::GameControl::QUIT);
almost all functions in this library return an error code where:
0 is success and non-0 (including negatives) is failure.
To get an error message from the code use fwlm::error_to_string(int error).
The error message will be prefixed with the source of the error, the prefix will be:
fwlm:if the source is this librarywindows_getlasterror:if the source is the Windows apilinux_errno:if the source is the linux "api" (functions likeopen,read, andwrite)
Based on this document.
How to communicate with the matrix using fwlm::LedMatrix::send_command().
These commands are defined in the enum fwlm::Command.
If a command appears twice in this table it means it has multiple variants that differ in parameters and/or response
| Command | id | Parameters | Response | Description | Shorthand (Member function of fwlm::LedMatrix) |
|---|---|---|---|---|---|
| BRIGHTNESS | 0x00 | 1 byte | - | Sets the brightness | set_brightness() |
| BRIGHTNESS | 0x00 | - | 1 byte | Gets the brightness | get_brightness() |
| PATTERN | 0x01 | 1 byte* | - | Displays a pre-programmed pattern | display_pattern() |
| BOOTLOADER | 0x02 | - | - | Jumps to the bootloader** | - |
| SLEEP | 0x03 | 1 byte | - | Sets if the matrix is asleep | set_sleep() |
| SLEEP | 0x03 | - | 1 byte | Gets if the matrix is asleep | get_sleep() |
| ANIMATE | 0x04 | 1 byte | - | Sets if the current pattern should scroll | set_animate() |
| ANIMATE | 0x04 | - | 1 byte | Gets if the current pattern is animating | get_animate() |
| PANIC | 0x05 | - | - | Causes the Firmware to crash** | - |
| DRAWBW | 0x06 | 39 bytes | - | Draw a black & white image | blit() + draw_matrix_black_white() |
| STAGE_COL | 0x07 | 35 bytes | - | Sends a column of brightnesses | blit() + draw_matrix_greyscale() |
| COMMIT_COL | 0x08 | - | - | Draw all columns sent by STAGE_COL | blit() + draw_matrix_greyscale() |
| START_GAME | 0x10 | 1 byte*** | - | Start a pre-programmed game on the matrix**** | game_start() |
| GAME_CONTROL | 0x11 | 1 byte | - | Control the currently running game | game_control() / game_quit() (for quitting the game only) |
| GAME_STATUS | 0x12 | - | ??? | Not implemented in the firmware of the matrix at the time of writing | - |
| VERSION | 0x20 | - | 3 bytes | Gets the version info of the matrix | get_version() |
- *: The pattern
PERCENTAGEis special it needs an extra parameter. - **: The LED matrix will stop responding after this.
- ***: The game
GAME_OF_LIFEis special it needs an extra parameter. - ****: The LED matrix will not respond normally to commands until the game is quit.
NOTE: the response is always 32 bytes long even if the table above says it only responds with 1 byte, the rest of the bytes will just be 0x00.
#include "FWLedMatrixLib/fw_led_matrix.h"
void main(){
// replace "COM3" with the path to your device
// so something like COM<number> on Windows
// and something like /dev/ttyACM0 on Linux
fwlm::LedMatrix led_matrix("COM3")
// to tell send_command that you expect a response call it with `with_response = true`
int r = led_matrix.send_command(fwlm::Command::BRIGHTNESS, {}, true);
// get what the last response was, may be empty if the command failed or no commands have been sent
const std::vector<uint8_t> buffer = led_matrix.get_last_response();
// print the response (not necessary)
for (const unsigned char i : buffer) {
printf("%02x ", i);
}
printf("\n");
}