I am working on a project to use an LED matrix to display a MQTT received text.
I got it working on a 8x32 matrix using the code available on ESPHome.
I am not trying to finalize the project on my actual hardware which uses 2 x 16x16 matrix displays side by side to create a 16x32.
I cannot figure out the pixel mapping for the life of me. Anyone has done this before or any guidance on how to go about it in ESPHome?
This is the configuration I have attached the displays as:
As I am debugging, I know that both sides work… Just can’t read what’s displayed as it is not mapped correctly.
Any help or guidance?
EDIT:
This is the code I am working with. With it now I can see the text go across the top, seamlessly over both units. But the text is mirrored.
#Name of the project and other subsitutions
substitutions:
project: Gallery Door LED Controller
id: gallery-door-led-controller
xscrollpadding: "4" # in pix
#Include the board used
<<: !include common/mqtt_credentials.yaml
#Include the board used
<<: !include common/esphome/esp32.yaml
#include common Wifi-OTA-API, etc
<<: !include common/common_for_mqtt.yaml
#include logger
<<: !include common/logger.yaml
binary_sensor:
#Include the status
- !include common/binary_sensors/status.yaml
switch:
#Include restart button
- !include common/switches/restart.yaml
sensor:
#Include wifi signal sensor
- !include common/sensors/wifi_signal.yaml
- !include common/sensors/uptime.yaml
text_sensor:
- platform: mqtt_subscribe
id: gallery_door_led_controller_text_topic
internal: true
topic: gallery_door/led_controller/text
on_value:
then:
- if:
condition:
lambda: return true;
then:
lambda: id(gallery_door_led_controller_text).publish_state(x);
- platform: template
id: gallery_door_led_controller_text
internal: true
font:
- file: "fonts/arial.ttf"
id: text_font_tiny
size: 10
- file: "fonts/materialdesignicons-webfont.ttf"
id: icon_font_10
size: 10
glyphs: [
# Wifi
'', # mdi-wifi-strength-outline
'', # mdi-wifi-strength-1
'', # mdi-wifi-strength-2
'', # mdi-wifi-strength-3
'', # mdi-wifi-strength-4
]
color:
- id: my_red
red: 100%
green: 0%
blue: 0%
- id: my_green
red: 0%
green: 100%
blue: 0%
- id: my_blue
red: 0%
green: 0%
blue: 100%
- id: my_yellow
red: 100%
green: 100%
blue: 0%
- id: my_black
red: 0%
green: 0%
blue: 0%
# Configure WS2812
light:
- platform: fastled_clockless
chipset: WS2812b
id: gallery_door_led_controller_led_matrix
pin: GPIO5
num_leds: 512
rgb_order: GRB
name: $project LED Matrix
default_transition_length: 0s
color_correct: [50%, 50%, 50%]
restore_mode: ALWAYS_ON
effects:
- addressable_rainbow:
- addressable_color_wipe:
- flicker:
- strobe:
- random:
- addressable_scan:
- addressable_twinkle:
- addressable_random_twinkle:
- addressable_fireworks:
- addressable_flicker:
- addressable_rainbow:
name: Rainbow Effect With Custom Values
speed: 10
width: 50
display:
- platform: addressable_light
id: gallery_door_led_controller_display_matrix
addressable_light_id: gallery_door_led_controller_led_matrix
width: 32
height: 16
pixel_mapper: |-
int iMatrixOffset = y >= 16 ? 512 : 0;
if (x % 2 == 0) {
return (x * 16) + (y % 16) + iMatrixOffset;
}
return (x * 16) + iMatrixOffset + (14 - (y % 16));
rotation: 180°
update_interval: 200ms
pages:
- id: page1
lambda: |-
if (id(mqtt_client)->is_connected()) {
// do something if MQTT is connected
static uint16_t xpos = 0;
int x_start, y_start;
int width, height;
it.get_text_bounds(0, 16, "MQTT Connected", id(text_font_tiny),
TextAlign::TOP_LEFT, &x_start, &y_start, &width, &height);
it.print(-(xpos % (width + $xscrollpadding)), -2,
id(text_font_tiny), Color(id(my_blue)),
TextAlign::TOP_LEFT, "MQTT Connected");
xpos++;
}
- id: page2
lambda: |-
it.print(0, 0, id(icon_font_10), Color(id(my_blue)), TextAlign::TOP_LEFT, "");
- id: page3
lambda: |-
// Draw the same rectangle, but this time filled.
//it.filled_rectangle(0, 0, it.get_width(), it.get_height());
it.fill(my_red);
- id: page4
lambda: |-
// Draw the same rectangle, but this time filled.
//it.filled_rectangle(0, 0, it.get_width(), it.get_height());
it.fill(my_black);
- id: page5
lambda: |-
static uint16_t xpos = 0;
const char * text = id(gallery_door_led_controller_text_topic).state.c_str();
int x_start, y_start;
int width, height;
it.get_text_bounds(0, 0, text, id(text_font_tiny),
TextAlign::TOP_LEFT, &x_start, &y_start, &width, &height);
it.print(-(xpos % (width + $xscrollpadding)), -2,
id(text_font_tiny), Color(id(my_green)),
TextAlign::TOP_LEFT, text);
xpos++;
interval:
- interval: 2s
then:
if:
condition:
lambda: |-
return id(gallery_door_led_controller_text).state == "STOP";
then:
- display.page.show: !lambda |-
static int pagenum = 0;
static display::DisplayPage* pages[] = {id(page2), id(page3)};
auto page = pages[pagenum++];
if (pagenum >= 2)
pagenum = 0;
return page;
- component.update: gallery_door_led_controller_display_matrix
- interval: 2s
then:
if:
condition:
lambda: |-
return id(gallery_door_led_controller_text).state == "START";
then:
- display.page.show: !lambda |-
static int pagenum = 0;
static display::DisplayPage* pages[] = {id(page5), id(page3)};
auto page = pages[pagenum++];
if (pagenum >= 2)
pagenum = 0;
return page;
- component.update: gallery_door_led_controller_display_matrix
