mirror of
https://github.com/esphome/esphome.git
synced 2026-05-31 07:57:40 +08:00
[hub75] HUB75 display component (#11153)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
29270eecb86ffa07b2b1d2a4ca56dd7f84762ddc89c6248dbf3f012eca8780b6
|
c01eec15857a784dd603c0afd194ab3b29a632422fe6f6b0a806ad4d81b5efc0
|
||||||
|
|||||||
@@ -227,6 +227,7 @@ esphome/components/hte501/* @Stock-M
|
|||||||
esphome/components/http_request/ota/* @oarcher
|
esphome/components/http_request/ota/* @oarcher
|
||||||
esphome/components/http_request/update/* @jesserockz
|
esphome/components/http_request/update/* @jesserockz
|
||||||
esphome/components/htu31d/* @betterengineering
|
esphome/components/htu31d/* @betterengineering
|
||||||
|
esphome/components/hub75/* @stuartparmenter
|
||||||
esphome/components/hydreon_rgxx/* @functionpointer
|
esphome/components/hydreon_rgxx/* @functionpointer
|
||||||
esphome/components/hyt271/* @Philippe12
|
esphome/components/hyt271/* @Philippe12
|
||||||
esphome/components/i2c/* @esphome/core
|
esphome/components/i2c/* @esphome/core
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from esphome.cpp_generator import MockObj
|
||||||
|
|
||||||
|
CODEOWNERS = ["@stuartparmenter"]
|
||||||
|
|
||||||
|
# Use fully-qualified namespace to avoid collision with external hub75 library's global ::hub75 namespace
|
||||||
|
hub75_ns = MockObj("::esphome::hub75", "::")
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
"""Board presets for HUB75 displays.
|
||||||
|
|
||||||
|
Each board preset defines standard pin mappings for HUB75 controller boards.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
import importlib
|
||||||
|
import pkgutil
|
||||||
|
from typing import ClassVar
|
||||||
|
|
||||||
|
|
||||||
|
class BoardRegistry:
|
||||||
|
"""Global registry for board configurations."""
|
||||||
|
|
||||||
|
_boards: ClassVar[dict[str, "BoardConfig"]] = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def register(cls, board: "BoardConfig") -> None:
|
||||||
|
"""Register a board configuration."""
|
||||||
|
cls._boards[board.name] = board
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_boards(cls) -> dict[str, "BoardConfig"]:
|
||||||
|
"""Return all registered boards."""
|
||||||
|
return cls._boards
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class BoardConfig:
|
||||||
|
"""Board configuration storing HUB75 pin mappings."""
|
||||||
|
|
||||||
|
name: str
|
||||||
|
r1_pin: int
|
||||||
|
g1_pin: int
|
||||||
|
b1_pin: int
|
||||||
|
r2_pin: int
|
||||||
|
g2_pin: int
|
||||||
|
b2_pin: int
|
||||||
|
a_pin: int
|
||||||
|
b_pin: int
|
||||||
|
c_pin: int
|
||||||
|
d_pin: int
|
||||||
|
e_pin: int | None
|
||||||
|
lat_pin: int
|
||||||
|
oe_pin: int
|
||||||
|
clk_pin: int
|
||||||
|
ignore_strapping_pins: tuple[str, ...] = () # e.g., ("a_pin", "clk_pin")
|
||||||
|
|
||||||
|
# Derived field for pin lookup
|
||||||
|
pins: dict[str, int | None] = field(default_factory=dict, init=False, repr=False)
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
"""Initialize derived fields and register board."""
|
||||||
|
self.name = self.name.lower()
|
||||||
|
self.pins = {
|
||||||
|
"r1": self.r1_pin,
|
||||||
|
"g1": self.g1_pin,
|
||||||
|
"b1": self.b1_pin,
|
||||||
|
"r2": self.r2_pin,
|
||||||
|
"g2": self.g2_pin,
|
||||||
|
"b2": self.b2_pin,
|
||||||
|
"a": self.a_pin,
|
||||||
|
"b": self.b_pin,
|
||||||
|
"c": self.c_pin,
|
||||||
|
"d": self.d_pin,
|
||||||
|
"e": self.e_pin,
|
||||||
|
"lat": self.lat_pin,
|
||||||
|
"oe": self.oe_pin,
|
||||||
|
"clk": self.clk_pin,
|
||||||
|
}
|
||||||
|
BoardRegistry.register(self)
|
||||||
|
|
||||||
|
def get_pin(self, pin_name: str) -> int | None:
|
||||||
|
"""Get pin number for a given pin name."""
|
||||||
|
return self.pins.get(pin_name)
|
||||||
|
|
||||||
|
|
||||||
|
# Dynamically import all board definition modules
|
||||||
|
for module_info in pkgutil.iter_modules(__path__):
|
||||||
|
importlib.import_module(f".{module_info.name}", package=__package__)
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"""Adafruit Matrix Portal board definitions."""
|
||||||
|
|
||||||
|
from . import BoardConfig
|
||||||
|
|
||||||
|
# Adafruit Matrix Portal S3
|
||||||
|
BoardConfig(
|
||||||
|
"adafruit-matrix-portal-s3",
|
||||||
|
r1_pin=42,
|
||||||
|
g1_pin=41,
|
||||||
|
b1_pin=40,
|
||||||
|
r2_pin=38,
|
||||||
|
g2_pin=39,
|
||||||
|
b2_pin=37,
|
||||||
|
a_pin=45,
|
||||||
|
b_pin=36,
|
||||||
|
c_pin=48,
|
||||||
|
d_pin=35,
|
||||||
|
e_pin=21,
|
||||||
|
lat_pin=47,
|
||||||
|
oe_pin=14,
|
||||||
|
clk_pin=2,
|
||||||
|
ignore_strapping_pins=("a_pin",), # GPIO45 is a strapping pin
|
||||||
|
)
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
"""Apollo Automation M1 board definitions."""
|
||||||
|
|
||||||
|
from . import BoardConfig
|
||||||
|
|
||||||
|
# Apollo Automation M1 Rev4
|
||||||
|
BoardConfig(
|
||||||
|
"apollo-automation-m1-rev4",
|
||||||
|
r1_pin=42,
|
||||||
|
g1_pin=41,
|
||||||
|
b1_pin=40,
|
||||||
|
r2_pin=38,
|
||||||
|
g2_pin=39,
|
||||||
|
b2_pin=37,
|
||||||
|
a_pin=45,
|
||||||
|
b_pin=36,
|
||||||
|
c_pin=48,
|
||||||
|
d_pin=35,
|
||||||
|
e_pin=21,
|
||||||
|
lat_pin=47,
|
||||||
|
oe_pin=14,
|
||||||
|
clk_pin=2,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Apollo Automation M1 Rev6
|
||||||
|
BoardConfig(
|
||||||
|
"apollo-automation-m1-rev6",
|
||||||
|
r1_pin=1,
|
||||||
|
g1_pin=5,
|
||||||
|
b1_pin=6,
|
||||||
|
r2_pin=7,
|
||||||
|
g2_pin=13,
|
||||||
|
b2_pin=9,
|
||||||
|
a_pin=16,
|
||||||
|
b_pin=48,
|
||||||
|
c_pin=47,
|
||||||
|
d_pin=21,
|
||||||
|
e_pin=38,
|
||||||
|
lat_pin=8,
|
||||||
|
oe_pin=4,
|
||||||
|
clk_pin=18,
|
||||||
|
)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
"""Huidu board definitions."""
|
||||||
|
|
||||||
|
from . import BoardConfig
|
||||||
|
|
||||||
|
# Huidu HD-WF2
|
||||||
|
BoardConfig(
|
||||||
|
"huidu-hd-wf2",
|
||||||
|
r1_pin=2,
|
||||||
|
g1_pin=6,
|
||||||
|
b1_pin=10,
|
||||||
|
r2_pin=3,
|
||||||
|
g2_pin=7,
|
||||||
|
b2_pin=11,
|
||||||
|
a_pin=39,
|
||||||
|
b_pin=38,
|
||||||
|
c_pin=37,
|
||||||
|
d_pin=36,
|
||||||
|
e_pin=21,
|
||||||
|
lat_pin=33,
|
||||||
|
oe_pin=35,
|
||||||
|
clk_pin=34,
|
||||||
|
)
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
"""ESP32 Trinity board definitions."""
|
||||||
|
|
||||||
|
from . import BoardConfig
|
||||||
|
|
||||||
|
# ESP32 Trinity
|
||||||
|
# https://esp32trinity.com/
|
||||||
|
# Pin assignments from: https://github.com/witnessmenow/ESP32-Trinity/blob/master/FAQ.md
|
||||||
|
BoardConfig(
|
||||||
|
"esp32-trinity",
|
||||||
|
r1_pin=25,
|
||||||
|
g1_pin=26,
|
||||||
|
b1_pin=27,
|
||||||
|
r2_pin=14,
|
||||||
|
g2_pin=12,
|
||||||
|
b2_pin=13,
|
||||||
|
a_pin=23,
|
||||||
|
b_pin=19,
|
||||||
|
c_pin=5,
|
||||||
|
d_pin=17,
|
||||||
|
e_pin=18,
|
||||||
|
lat_pin=4,
|
||||||
|
oe_pin=15,
|
||||||
|
clk_pin=16,
|
||||||
|
)
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,192 @@
|
|||||||
|
#include "hub75_component.h"
|
||||||
|
#include "esphome/core/application.h"
|
||||||
|
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
|
namespace esphome::hub75 {
|
||||||
|
|
||||||
|
static const char *const TAG = "hub75";
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// Constructor
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
HUB75Display::HUB75Display(const Hub75Config &config) : config_(config) {
|
||||||
|
// Initialize runtime state from config
|
||||||
|
this->brightness_ = config.brightness;
|
||||||
|
this->enabled_ = (config.brightness > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// Core Component methods
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
void HUB75Display::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up HUB75Display...");
|
||||||
|
|
||||||
|
// Create driver with pre-configured config
|
||||||
|
driver_ = new Hub75Driver(config_);
|
||||||
|
if (!driver_->begin()) {
|
||||||
|
ESP_LOGE(TAG, "Failed to initialize HUB75 driver!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->enabled_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HUB75Display::dump_config() {
|
||||||
|
LOG_DISPLAY("", "HUB75", this);
|
||||||
|
|
||||||
|
ESP_LOGCONFIG(TAG,
|
||||||
|
" Panel: %dx%d pixels\n"
|
||||||
|
" Layout: %dx%d panels\n"
|
||||||
|
" Virtual Display: %dx%d pixels",
|
||||||
|
config_.panel_width, config_.panel_height, config_.layout_cols, config_.layout_rows,
|
||||||
|
config_.panel_width * config_.layout_cols, config_.panel_height * config_.layout_rows);
|
||||||
|
|
||||||
|
ESP_LOGCONFIG(TAG,
|
||||||
|
" Scan Wiring: %d\n"
|
||||||
|
" Shift Driver: %d",
|
||||||
|
static_cast<int>(config_.scan_wiring), static_cast<int>(config_.shift_driver));
|
||||||
|
|
||||||
|
ESP_LOGCONFIG(TAG,
|
||||||
|
" Pins: R1:%i, G1:%i, B1:%i, R2:%i, G2:%i, B2:%i\n"
|
||||||
|
" Pins: A:%i, B:%i, C:%i, D:%i, E:%i\n"
|
||||||
|
" Pins: LAT:%i, OE:%i, CLK:%i",
|
||||||
|
config_.pins.r1, config_.pins.g1, config_.pins.b1, config_.pins.r2, config_.pins.g2, config_.pins.b2,
|
||||||
|
config_.pins.a, config_.pins.b, config_.pins.c, config_.pins.d, config_.pins.e, config_.pins.lat,
|
||||||
|
config_.pins.oe, config_.pins.clk);
|
||||||
|
|
||||||
|
ESP_LOGCONFIG(TAG,
|
||||||
|
" Clock Speed: %u MHz\n"
|
||||||
|
" Latch Blanking: %i\n"
|
||||||
|
" Clock Phase: %s\n"
|
||||||
|
" Min Refresh Rate: %i Hz\n"
|
||||||
|
" Bit Depth: %i\n"
|
||||||
|
" Double Buffer: %s",
|
||||||
|
static_cast<uint32_t>(config_.output_clock_speed) / 1000000, config_.latch_blanking,
|
||||||
|
TRUEFALSE(config_.clk_phase_inverted), config_.min_refresh_rate, HUB75_BIT_DEPTH,
|
||||||
|
YESNO(config_.double_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// Display/PollingComponent methods
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
void HUB75Display::update() {
|
||||||
|
if (!driver_) [[unlikely]]
|
||||||
|
return;
|
||||||
|
if (!this->enabled_) [[unlikely]]
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->do_update_();
|
||||||
|
|
||||||
|
if (config_.double_buffer) {
|
||||||
|
driver_->flip_buffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HUB75Display::fill(Color color) {
|
||||||
|
if (!driver_) [[unlikely]]
|
||||||
|
return;
|
||||||
|
if (!this->enabled_) [[unlikely]]
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Special case: black (off) - use fast hardware clear
|
||||||
|
if (!color.is_on()) {
|
||||||
|
driver_->clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For non-black colors, fall back to base class (pixel-by-pixel)
|
||||||
|
Display::fill(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HOT HUB75Display::draw_pixel_at(int x, int y, Color color) {
|
||||||
|
if (!driver_) [[unlikely]]
|
||||||
|
return;
|
||||||
|
if (!this->enabled_) [[unlikely]]
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (x >= this->get_width_internal() || x < 0 || y >= this->get_height_internal() || y < 0) [[unlikely]]
|
||||||
|
return;
|
||||||
|
|
||||||
|
driver_->set_pixel(x, y, color.r, color.g, color.b);
|
||||||
|
App.feed_wdt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HOT HUB75Display::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, ColorOrder order,
|
||||||
|
ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) {
|
||||||
|
if (!driver_) [[unlikely]]
|
||||||
|
return;
|
||||||
|
if (!this->enabled_) [[unlikely]]
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Map ESPHome enums to hub75 enums
|
||||||
|
Hub75PixelFormat format;
|
||||||
|
Hub75ColorOrder color_order = Hub75ColorOrder::RGB;
|
||||||
|
int bytes_per_pixel;
|
||||||
|
|
||||||
|
// Determine format based on bitness
|
||||||
|
if (bitness == ColorBitness::COLOR_BITNESS_565) {
|
||||||
|
format = Hub75PixelFormat::RGB565;
|
||||||
|
bytes_per_pixel = 2;
|
||||||
|
} else if (bitness == ColorBitness::COLOR_BITNESS_888) {
|
||||||
|
#ifdef USE_LVGL
|
||||||
|
#if LV_COLOR_DEPTH == 32
|
||||||
|
// 32-bit: 4 bytes per pixel with padding byte (LVGL mode)
|
||||||
|
format = Hub75PixelFormat::RGB888_32;
|
||||||
|
bytes_per_pixel = 4;
|
||||||
|
|
||||||
|
// Map ESPHome ColorOrder to Hub75ColorOrder
|
||||||
|
// ESPHome ColorOrder is typically BGR for little-endian 32-bit
|
||||||
|
color_order = (order == ColorOrder::COLOR_ORDER_RGB) ? Hub75ColorOrder::RGB : Hub75ColorOrder::BGR;
|
||||||
|
#elif LV_COLOR_DEPTH == 24
|
||||||
|
// 24-bit: 3 bytes per pixel, tightly packed
|
||||||
|
format = Hub75PixelFormat::RGB888;
|
||||||
|
bytes_per_pixel = 3;
|
||||||
|
// Note: 24-bit is always RGB order in LVGL
|
||||||
|
#else
|
||||||
|
ESP_LOGE(TAG, "Unsupported LV_COLOR_DEPTH: %d", LV_COLOR_DEPTH);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// Non-LVGL mode: standard 24-bit RGB888
|
||||||
|
format = Hub75PixelFormat::RGB888;
|
||||||
|
bytes_per_pixel = 3;
|
||||||
|
color_order = (order == ColorOrder::COLOR_ORDER_RGB) ? Hub75ColorOrder::RGB : Hub75ColorOrder::BGR;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Unsupported bitness: %d", static_cast<int>(bitness));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if buffer is tightly packed (no stride)
|
||||||
|
const int stride_px = x_offset + w + x_pad;
|
||||||
|
const bool is_packed = (x_offset == 0 && x_pad == 0 && y_offset == 0);
|
||||||
|
|
||||||
|
if (is_packed) {
|
||||||
|
// Tightly packed buffer - single bulk call for best performance
|
||||||
|
driver_->draw_pixels(x_start, y_start, w, h, ptr, format, color_order, big_endian);
|
||||||
|
} else {
|
||||||
|
// Buffer has stride (padding between rows) - draw row by row
|
||||||
|
for (int yy = 0; yy < h; ++yy) {
|
||||||
|
const size_t row_offset = ((y_offset + yy) * stride_px + x_offset) * bytes_per_pixel;
|
||||||
|
const uint8_t *row_ptr = ptr + row_offset;
|
||||||
|
|
||||||
|
driver_->draw_pixels(x_start, y_start + yy, w, 1, row_ptr, format, color_order, big_endian);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HUB75Display::set_brightness(int brightness) {
|
||||||
|
this->brightness_ = brightness;
|
||||||
|
this->enabled_ = (brightness > 0);
|
||||||
|
if (this->driver_ != nullptr) {
|
||||||
|
this->driver_->set_brightness(brightness);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace esphome::hub75
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "esphome/components/display/display_buffer.h"
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "hub75.h" // hub75 library
|
||||||
|
|
||||||
|
namespace esphome::hub75 {
|
||||||
|
|
||||||
|
using esphome::display::ColorBitness;
|
||||||
|
using esphome::display::ColorOrder;
|
||||||
|
|
||||||
|
class HUB75Display : public display::Display {
|
||||||
|
public:
|
||||||
|
// Constructor accepting config
|
||||||
|
explicit HUB75Display(const Hub75Config &config);
|
||||||
|
|
||||||
|
// Core Component methods
|
||||||
|
void setup() override;
|
||||||
|
void dump_config() override;
|
||||||
|
float get_setup_priority() const override { return setup_priority::PROCESSOR; }
|
||||||
|
|
||||||
|
// Display/PollingComponent methods
|
||||||
|
void update() override;
|
||||||
|
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }
|
||||||
|
void fill(Color color) override;
|
||||||
|
void draw_pixel_at(int x, int y, Color color) override;
|
||||||
|
void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order,
|
||||||
|
display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override;
|
||||||
|
|
||||||
|
// Brightness control (runtime mutable)
|
||||||
|
void set_brightness(int brightness);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Display internal methods
|
||||||
|
int get_width_internal() override { return config_.panel_width * config_.layout_cols; }
|
||||||
|
int get_height_internal() override { return config_.panel_height * config_.layout_rows; }
|
||||||
|
|
||||||
|
// Member variables
|
||||||
|
Hub75Driver *driver_{nullptr};
|
||||||
|
Hub75Config config_; // Immutable configuration
|
||||||
|
|
||||||
|
// Runtime state (mutable)
|
||||||
|
int brightness_{128};
|
||||||
|
bool enabled_{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace esphome::hub75
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -152,6 +152,7 @@ lib_deps =
|
|||||||
esphome/ESP32-audioI2S@2.3.0 ; i2s_audio
|
esphome/ESP32-audioI2S@2.3.0 ; i2s_audio
|
||||||
droscy/esp_wireguard@0.4.2 ; wireguard
|
droscy/esp_wireguard@0.4.2 ; wireguard
|
||||||
esphome/esp-audio-libs@2.0.1 ; audio
|
esphome/esp-audio-libs@2.0.1 ; audio
|
||||||
|
esphome/esp-hub75@0.1.6 ; hub75
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${common:arduino.build_flags}
|
${common:arduino.build_flags}
|
||||||
@@ -175,6 +176,7 @@ lib_deps =
|
|||||||
droscy/esp_wireguard@0.4.2 ; wireguard
|
droscy/esp_wireguard@0.4.2 ; wireguard
|
||||||
kahrendt/ESPMicroSpeechFeatures@1.1.0 ; micro_wake_word
|
kahrendt/ESPMicroSpeechFeatures@1.1.0 ; micro_wake_word
|
||||||
esphome/esp-audio-libs@2.0.1 ; audio
|
esphome/esp-audio-libs@2.0.1 ; audio
|
||||||
|
esphome/esp-hub75@0.1.6 ; hub75
|
||||||
build_flags =
|
build_flags =
|
||||||
${common:idf.build_flags}
|
${common:idf.build_flags}
|
||||||
-Wno-nonnull-compare
|
-Wno-nonnull-compare
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
esp32:
|
||||||
|
board: esp32dev
|
||||||
|
framework:
|
||||||
|
type: esp-idf
|
||||||
|
|
||||||
|
display:
|
||||||
|
- platform: hub75
|
||||||
|
id: my_hub75
|
||||||
|
panel_width: 64
|
||||||
|
panel_height: 32
|
||||||
|
double_buffer: true
|
||||||
|
brightness: 128
|
||||||
|
r1_pin: GPIO25
|
||||||
|
g1_pin: GPIO26
|
||||||
|
b1_pin: GPIO27
|
||||||
|
r2_pin: GPIO14
|
||||||
|
g2_pin: GPIO12
|
||||||
|
b2_pin: GPIO13
|
||||||
|
a_pin: GPIO23
|
||||||
|
b_pin: GPIO19
|
||||||
|
c_pin: GPIO5
|
||||||
|
d_pin: GPIO17
|
||||||
|
e_pin: GPIO21
|
||||||
|
lat_pin: GPIO4
|
||||||
|
oe_pin: GPIO15
|
||||||
|
clk_pin: GPIO16
|
||||||
|
pages:
|
||||||
|
- id: page1
|
||||||
|
lambda: |-
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
- id: page2
|
||||||
|
lambda: |-
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
on_page_change:
|
||||||
|
from: page1
|
||||||
|
to: page2
|
||||||
|
then:
|
||||||
|
lambda: |-
|
||||||
|
ESP_LOGD("display", "1 -> 2");
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
esp32:
|
||||||
|
board: esp32-s3-devkitc-1
|
||||||
|
framework:
|
||||||
|
type: esp-idf
|
||||||
|
|
||||||
|
display:
|
||||||
|
- platform: hub75
|
||||||
|
id: hub75_display_board
|
||||||
|
board: adafruit-matrix-portal-s3
|
||||||
|
panel_width: 64
|
||||||
|
panel_height: 32
|
||||||
|
double_buffer: true
|
||||||
|
brightness: 128
|
||||||
|
pages:
|
||||||
|
- id: page1
|
||||||
|
lambda: |-
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
- id: page2
|
||||||
|
lambda: |-
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
on_page_change:
|
||||||
|
from: page1
|
||||||
|
to: page2
|
||||||
|
then:
|
||||||
|
lambda: |-
|
||||||
|
ESP_LOGD("display", "1 -> 2");
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
esp32:
|
||||||
|
board: esp32-s3-devkitc-1
|
||||||
|
framework:
|
||||||
|
type: esp-idf
|
||||||
|
|
||||||
|
display:
|
||||||
|
- platform: hub75
|
||||||
|
id: my_hub75
|
||||||
|
panel_width: 64
|
||||||
|
panel_height: 32
|
||||||
|
double_buffer: true
|
||||||
|
brightness: 128
|
||||||
|
r1_pin: GPIO42
|
||||||
|
g1_pin: GPIO41
|
||||||
|
b1_pin: GPIO40
|
||||||
|
r2_pin: GPIO38
|
||||||
|
g2_pin: GPIO39
|
||||||
|
b2_pin: GPIO37
|
||||||
|
a_pin: GPIO45
|
||||||
|
b_pin: GPIO36
|
||||||
|
c_pin: GPIO48
|
||||||
|
d_pin: GPIO35
|
||||||
|
e_pin: GPIO21
|
||||||
|
lat_pin: GPIO47
|
||||||
|
oe_pin: GPIO14
|
||||||
|
clk_pin: GPIO2
|
||||||
|
pages:
|
||||||
|
- id: page1
|
||||||
|
lambda: |-
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
- id: page2
|
||||||
|
lambda: |-
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
on_page_change:
|
||||||
|
from: page1
|
||||||
|
to: page2
|
||||||
|
then:
|
||||||
|
lambda: |-
|
||||||
|
ESP_LOGD("display", "1 -> 2");
|
||||||
Reference in New Issue
Block a user