屏幕

micropython

https://micropython.org/download/ESP32_GENERIC/

模拟器 https://wokwi.com/

模拟配置文件diagram.json

LCD1602

i2c通信协议

scl=22 , sda=21

from machine import I2C, Pin
import time

# LCD 常量定义
LCD_ADDRESS = 0x27  # I2C 地址(可能是 0x3F,具体根据你的屏幕)
LCD_WIDTH = 16      # 每行字符数
LCD_CHR = 1         # 发送数据
LCD_CMD = 0         # 发送命令

# LCD 命令
LCD_LINE_1 = 0x80   # 第一行起始地址
LCD_LINE_2 = 0xC0   # 第二行起始地址
LCD_BACKLIGHT = 0x08  # 背光开
ENABLE = 0b00000100  # Enable bit

# 初始化 I2C  分配引脚
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)

def lcd_write(byte, mode):
    """发送命令或数据到 LCD"""
    bits_high = mode | (byte & 0xF0) | LCD_BACKLIGHT
    bits_low = mode | ((byte << 4) & 0xF0) | LCD_BACKLIGHT
    i2c.writeto(LCD_ADDRESS, bytearray([bits_high, bits_high | ENABLE, bits_high & ~ENABLE]))
    i2c.writeto(LCD_ADDRESS, bytearray([bits_low, bits_low | ENABLE, bits_low & ~ENABLE]))
    time.sleep_us(50)

def lcd_init():
    """初始化 LCD 屏幕"""
    lcd_write(0x33, LCD_CMD)  # 初始化
    lcd_write(0x32, LCD_CMD)  # 设置为 4 位模式
    lcd_write(0x06, LCD_CMD)  # 光标移动方向
    lcd_write(0x0C, LCD_CMD)  # 打开显示,不显示光标
    lcd_write(0x28, LCD_CMD)  # 2 行模式
    lcd_write(0x01, LCD_CMD)  # 清屏
    time.sleep(0.1)

def lcd_clear():
    """清除 LCD 屏幕"""
    lcd_write(0x01, LCD_CMD)
    time.sleep(0.1)

def lcd_message(message, line):
    """在指定行显示消息"""
    if line == 1:
        lcd_write(LCD_LINE_1, LCD_CMD)
    elif line == 2:
        lcd_write(LCD_LINE_2, LCD_CMD)

    for char in message:
        lcd_write(ord(char), LCD_CHR)

# 初始化 LCD 并显示消息
lcd_init()
lcd_clear()

lcd_message("hello", 1)  # 第一行显示 "hello"
lcd_message("world", 2)  # 第二行显示 "world"

MAX7219

spi通信协议

sck=18,mosi(DIN)=19,cs=2

使用https://github.com/mcauser/micropython-max7219/blob/master/max7219.py库

4块屏幕8*32

名称功能
MOSI主输出-从输入
MISO主输入-从输出
SCLK同步时钟线
CS片选线

代码点亮

from machine import Pin, SPI
import max7219
from time import sleep

# 初始化 SPI 接口
spi = SPI(1, baudrate=10000000, polarity=0, phase=0, sck=Pin(18), mosi=Pin(19))

# 初始化 MAX7219
cs = Pin(5, Pin.OUT)  # CS 引脚
num_matrices = 3       # 点阵模块数量(24 列 / 8 列 = 3 模块)
display = max7219.Matrix8x8(spi, cs, num_matrices)

# 清屏并设置亮度
display.brightness(1)  # 设置亮度(0-15)
display.fill(0)        # 清屏
display.show()

# 显示文字
text = "hello 1234567890  "  # 循环滚动的文字
while True:
    for i in range(len(text) * 8):  # 每个字符占 8 列
        display.fill(0)
        display.text(text, -i, 0, 1)  # 滚动文字
        display.show()
        sleep(0.1)  # 滚动速度调整(单位:秒)

esphome点亮

# SPI 总线配置
spi:
  clk_pin: GPIO18
  mosi_pin: GPIO19

# 配置 Max7219 LED 屏幕

display:
  - platform: max7219digit
    id: max7219_display
    cs_pin: GPIO5
    num_chips: 4
    intensity: 8
    lambda: |-
      it.print(0, 0, id(my_font), "HELLO! World");


time:
  - platform: homeassistant
    id: homeassistant_time

font:
  - file: "fonts/arial.ttf"
    id: my_font
    size: 8

switch:
  - platform: template
    name: "Display Power"
    id: display_power
    turn_on_action:
      - logger.log: "Display is ON"
      - lambda: |-
          id(max7219_display).turn_on_off(true);
    turn_off_action:
      - logger.log: "Display is OFF"
      - lambda: |-
          id(max7219_display).turn_on_off(false);

number:
  - platform: template
    name: "Display Brightness"
    id: display_brightness
    min_value: 0
    max_value: 15
    step: 1
    restore_value: true
    initial_value: 8
    set_action:
      - lambda: |-
          id(max7219_display).set_intensity((int)x);

加了实体后有问题

自定义文本

固件绑定传感器数值+lambda动态函数显示

# SPI 总线配置
spi:
  clk_pin: GPIO18
  mosi_pin: GPIO19

# 配置 Max7219 LED 屏幕

display:
  - platform: max7219digit
    cs_pin: GPIO5
    num_chips: 4
    intensity: 2
    id: max7219_display
    update_interval: 1s  # 每秒更新一次显示
    lambda: |-
      // 获取文本传感器的值
      const char* text = id(display_text).state.c_str();
      // 在屏幕上显示文本
      it.print(0, 0, id(my_font), text);
# 添加文本传感器
text_sensor:
  - platform: homeassistant
    name: "Display Text"
    id: display_text
    entity_id: input_text.max7219_display_text  # 绑定到 Home Assistant 的 input_text 实体


font:
  - file: "fonts/calibril.ttf"
    id: my_font
    size: 8

修改hass系统 configuration.yaml 文件添加一个文本传感器,设置后重启生效

input_text:
  max7219_display_text:
    name: " max7219 Display Text"
    initial: "Hello Input"
    max: 16  # 最大字符数(根据屏幕宽度调整)

HUB75

HUB75 RGB LED 模块 16针

屏幕实际像素为 高64像素宽128像素 屏幕物理宽高 16*32cm

编号孔位孔位编号
R112G1
B134GND
R256G2
B278GND/E
A910B
C1112D
CLK1314LAT
OE1516GND

以下是你的 HUB75 RGB 屏幕引脚说明,以及每个引脚的功能解释:

pcb对应引脚

引脚引脚
GPIO13--OE,GND--GND,
GPIO19--CLK,GPIO5--LAT,
GPIO14--C,GPIO18--D,
GPIO26--A,GPIO12--B,
GPIO25--B2,GPIO23--E,
GPIO33--R2,GPIO15--G2,
GPIO2--B1,GND--GND,
GPIO4--R1,GPIO32--G1,

三色交替显示

from machine import Pin
import time

# 引脚定义
OE = Pin(13, Pin.OUT)  # 输出使能
CLK = Pin(19, Pin.OUT)  # 时钟信号
LAT = Pin(5, Pin.OUT)  # 数据锁存
A = Pin(26, Pin.OUT)  # 行选择 A
B = Pin(12, Pin.OUT)  # 行选择 B
C = Pin(14, Pin.OUT)  # 行选择 C
D = Pin(18, Pin.OUT)  # 行选择 D
E = Pin(23, Pin.OUT)  # 行选择 E
R1 = Pin(4, Pin.OUT)  # 上半部分红色
G1 = Pin(32, Pin.OUT)  # 上半部分绿色
B1 = Pin(2, Pin.OUT)  # 上半部分蓝色
R2 = Pin(33, Pin.OUT)  # 下半部分红色
G2 = Pin(15, Pin.OUT)  # 下半部分绿色
B2 = Pin(25, Pin.OUT)  # 下半部分蓝色

# 屏幕参数
MATRIX_WIDTH = 1 # 屏幕宽度
MATRIX_HEIGHT = 32  # 屏幕高度

# 初始化引脚
def init_pins():
    OE.value(1)  # 禁止显示(高电平关闭屏幕)
    LAT.value(0)  # 初始化锁存
    CLK.value(0)  # 初始化时钟
    A.value(0)
    B.value(0)
    C.value(0)
    D.value(0)
    E.value(0)
    R1.value(0)
    G1.value(0)
    B1.value(0)
    R2.value(0)
    G2.value(0)
    B2.value(0)

# 设置行选择
def set_row(row):
    A.value(row & 0x01)
    B.value((row >> 1) & 0x01)
    C.value((row >> 2) & 0x01)
    D.value((row >> 3) & 0x01)
    E.value((row >> 4) & 0x01)

# 刷新一行
def refresh_row(row, color):
    set_row(row)  # 设置当前行
    for col in range(MATRIX_WIDTH):  # 屏幕宽度为 128
        # 设置颜色
        R1.value(color[0])
        G1.value(color[1])
        B1.value(color[2])
        R2.value(color[0])
        G2.value(color[1])
        B2.value(color[2])

        # 时钟信号
        CLK.value(1)
        CLK.value(0)

    # 锁存数据
    LAT.value(1)
    LAT.value(0)

# 刷新整个屏幕
def refresh_screen(color):
    for row in range(MATRIX_HEIGHT):  # 每次刷新 64 行
        refresh_row(row, color)

# 主循环
def main():
    init_pins()
    colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1)]  # 红绿蓝
    while True:
        for color in colors:
            start_time = time.ticks_ms()  # 当前时间
            while time.ticks_diff(time.ticks_ms(), start_time) < 1000:  # 持续刷新 1 秒
                OE.value(0)  # 打开屏幕显示
                refresh_screen(color)
                OE.value(1)  # 短暂关闭屏幕,避免刷新时闪烁
                time.sleep_us(50)  # 微小延迟

# 运行主程序
main()



3个像素显示红绿蓝

from machine import Pin
import time

# 引脚定义
pin_config = {
    'a': Pin(26, Pin.OUT),
    'b': Pin(12, Pin.OUT),
    'c': Pin(14, Pin.OUT),
    'd': Pin(18, Pin.OUT),
    'e': Pin(23, Pin.OUT),
    'r1': Pin(4, Pin.OUT),
    'g1': Pin(32, Pin.OUT),
    'b1': Pin(2, Pin.OUT),
    'r2': Pin(33, Pin.OUT),
    'g2': Pin(15, Pin.OUT),
    'b2': Pin(25, Pin.OUT),
    'clk': Pin(19, Pin.OUT),
    'oe': Pin(13, Pin.OUT),
    'lat': Pin(5, Pin.OUT),
}

# 屏幕参数
MATRIX_WIDTH = 128  # 屏幕宽度
MATRIX_HEIGHT = 64  # 屏幕高度

# 初始化引脚
def init_pins():
    for pin in pin_config.values():
        pin.value(0)
    pin_config['oe'].value(1)  # 禁止显示

# 设置行选择
def set_row(row):
    pin_config['a'].value(row & 0x01)
    pin_config['b'].value((row >> 1) & 0x01)
    pin_config['c'].value((row >> 2) & 0x01)
    pin_config['d'].value((row >> 3) & 0x01)
    pin_config['e'].value((row >> 4) & 0x01)

# 刷新一行
def refresh_row(row, color):
    set_row(row)  # 设置当前行
    for col in range(MATRIX_WIDTH):  # 屏幕宽度为 128
        if col < 3:  # 只点亮前3个像素
            pin_config['r1'].value(color[0])
            pin_config['g1'].value(color[1])
            pin_config['b1'].value(color[2])
            pin_config['r2'].value(color[0])
            pin_config['g2'].value(color[1])
            pin_config['b2'].value(color[2])
        else:
            pin_config['r1'].value(0)
            pin_config['g1'].value(0)
            pin_config['b1'].value(0)
            pin_config['r2'].value(0)
            pin_config['g2'].value(0)
            pin_config['b2'].value(0)

        # 时钟信号
        pin_config['clk'].value(1)
        pin_config['clk'].value(0)

    # 锁存数据
    pin_config['lat'].value(1)
    pin_config['lat'].value(0)

# 刷新整个屏幕
def refresh_screen(color):
    for row in range(MATRIX_HEIGHT):  # 每次刷新 64 行
        refresh_row(row, color)
        time.sleep_us(50)  # 微小延迟

# 主循环
def main():
    init_pins()
    colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1)]  # 红绿蓝
    while True:
        for color in colors:
            start_time = time.ticks_ms()
            while time.ticks_diff(time.ticks_ms(), start_time) < 1000:  # 持续刷新 1 秒
                pin_config['oe'].value(0)  # 打开屏幕显示
                refresh_screen(color)
                pin_config['oe'].value(1)  # 短暂关闭屏幕,避免刷新时闪烁
                time.sleep_us(50)  # 微小延迟

# 运行主程序
main()

通过esphome

esphome:
  name: hubleddisplay
  friendly_name: hubleddisplay

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "AsB5u4X88wIgcajQ3g04HAs3Y+yedVEWWiNn9TJ9GDg="

web_server:
  port: 80
  
wifi:
  ssid: "sb"
  password: "100200300"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Myesphom99"
    password: "a123456789"

captive_portal:

external_components:
  - source: github://TillFleisch/ESPHome-HUB75-MatrixDisplayWrapper@main

font:
  - file: "gfonts://Roboto"
    id: roboto
    size: 10

display:
  - platform: hub75_matrix_display
    id: matrix
    width: 128
    height: 64
    R1_pin: 4
    G1_pin: 32
    B1_pin: 2
    R2_pin: 33
    G2_pin: 15
    B2_pin: 25
    A_pin: 26
    B_pin: 12
    C_pin: 14
    D_pin: 18
    E_pin: 23
    LAT_pin: 5
    OE_pin: 13
    CLK_pin: 19
    lambda: |- 
      it.print(0, 0, id(roboto), "Hello World!");


switch:
  - platform: hub75_matrix_display
    matrix_id: matrix
    name: "Power"
    id: power

number:
  - platform: hub75_matrix_display
    matrix_id: matrix
    name: "Brightness"

多行显示+日期+中文

esphome:
  name: hubleddisplay
  friendly_name: hubleddisplay
 
esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "AsB5u4X88wIgcajQ3g04HAs3Y+yedVEWWiNn9TJ9GDg="

web_server:
  port: 80
  
wifi:
  ssid: "sb"
  password: "100200300"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Myesphom99"
    password: "a123456789"

captive_portal:

external_components:
  - source: github://TillFleisch/ESPHome-HUB75-MatrixDisplayWrapper@main
 
# 定义多种字体
font:
  - file: "gfonts://Courier New"       # 用于日期显示的等宽字体
    id: courier_new
    size: 12
  - file: "fonts/unifont-16.0.02.otf"
    id: sans_cjk
    size: 16
    glyphs: !include all_chars.txt
 
display:
  - platform: hub75_matrix_display
    id: matrix
    width: 128
    height: 64
    R1_pin: 4
    G1_pin: 32
    B1_pin: 2
    R2_pin: 33
    G2_pin: 15
    B2_pin: 25
    A_pin: 26
    B_pin: 12
    C_pin: 14
    D_pin: 18
    E_pin: 23
    LAT_pin: 5
    OE_pin: 13
    CLK_pin: 19
    lambda: |-
      // 第一行:显示日期,使用 Courier New 字体,红色
      it.printf(0, 0, id(courier_new), Color(255, 0, 0), "%04d-%02d-%02d %02d:%02d:%02d",
                id(homeassistant_time).now().year, 
                id(homeassistant_time).now().month, 
                id(homeassistant_time).now().day_of_month,
                id(homeassistant_time).now().hour,
                id(homeassistant_time).now().minute,
                id(homeassistant_time).now().second);
      // 第二行:显示中文,使用点阵字体,绿色
      //it.printf(0, 12, FONT_chinese, Color(255, 255, 255), "你好");
      it.printf(0, 12, id(sans_cjk), Color(255, 255, 255), "你好 我很好 谢谢你 我指定你是谁");
      // 第三行:
      it.print(0, 40, id(sans_cjk), Color(0, 0, 255), "Hello好World!");

switch:
  - platform: hub75_matrix_display
    matrix_id: matrix
    name: "Power"
    id: power

number:
  - platform: hub75_matrix_display
    matrix_id: matrix
    name: "Brightness"

# 时间组件,用于获取当前日期
time:
  - platform: homeassistant
    id: homeassistant_time

    glyphs: ["你", "好"]  # 只编译这两个汉字

打包简易字体思源黑体

pyftsubset D:\Users\NotoSansSC-Regular.ttf  --text-file=D:\Users\chars.txt --output-file=D:\Users\subset_font.ttf   
  

提取字体文字

用TTFont读取字体内的所有文字生成all_chars.txt

from fontTools.ttLib import TTFont

矩阵屏

固件

  • Tasmota

    mqtt: 前缀 tasmota/discovery

  • ESPHome

屏幕驱动

  • MAX7219 (单色,性价比 8*8点阵) SPI 协议

  • WS2812B (彩色 灯带)

  • hub75 (拼接屏)

# Configure the HUB75 display  没试过
display:
  - platform: hub75
    width: 32             # 屏幕宽度,通常为 64 或 32
    height: 16            # 屏幕高度,通常为 32 或 16
    rgb_order: RGB        # RGB 排列方式 (默认是 RGB,可根据屏幕情况调整为 RBG、GRB 等)
    chain_length: 1       # 串联的屏幕数量
    gpio_pins:            # 定义连接到 ESP32 的 GPIO 引脚
      r1: 25
      g1: 26
      b1: 27
      r2: 14
      g2: 12
      b2: 13
      a: 23
      b: 19
      c: 18
      d: 5
      lat: 4
      oe: 15
      clk: 22
    update_interval: 16ms # 屏幕刷新频率,调整此值可以优化显示效果

hub75库

第三方库

external_components:
  - source:
      type: local
      path: custom_components/hub75

联网


def do_connect():
    import network
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    if not wifi.isconnected():
        print('connecting to network...')
        wifi.connect('sb', '100200300')
        while not wifi.isconnected():
            pass
    print('network config:', wifi.ifconfig())

安装扩展

import mip
mip.install('hub75')