豆爸 发表于 2025-9-23 14:23:43

FireBeetle 2 ESP32-C5基于ESPNOW的无线通信

本帖最后由 豆爸 于 2025-10-3 08:26 编辑

一、简介
本项目基于 ESP32 开发板,通过 ESP-NOW 无线通信协议构建了一套 “摇杆指令发送 - 接收 - 显示” 系统。发送端利用 ADC 模块采集摇杆的 X、Y 轴模拟信号,转化为 “上 / 下 / 左 / 右 / 停止”5 种控制指令;接收端通过 ESP-NOW 接收指令后,在 LCD 屏幕上实时显示指令内容,同时在串口输出 sender MAC 地址与指令信息,实现了低延迟、近距离的无线指令交互。该系统展示了低功耗无线通信技术在物联网设备控制中的应用,适用于遥控小车、智能家居控制等多种场景。
二、硬件
1、硬件清单

硬件名称数量功能说明链接
FireBeetle 2 ESP32-C5 开发板1系统核心控制板,支持 ESP-NOW 通信-
Gravity: JoyStick 摇杆1输入设备,提供 X/Y 轴模拟控制信号https://www.dfrobot.com.cn/goods-117.html
Gravity: I2C OLED-2864 显示屏1显示设备,支持 I2C 通信的 OLED 屏幕https://www.dfrobot.com.cn/goods-1374.html
ESP32编程掌机(ST7735 LCD 显示屏)1显示设备,160×128 分辨率 ST7735 驱动 LCD-
Type-C&Micro二合一USB线1用于程序下载与供电https://www.dfrobot.com.cn/goods-2843.html

2、硬件简介

(1)FireBeetle 2 ESP32-C5 开发板



FireBeetle 2 ESP32-C5 是一款搭载乐鑫 ESP32-C5 模组的低功耗 IoT 开发板,面向智能家居和广泛物联网场景,集高性能计算、多协议支持与智能电源管理于一体,为各种部署需求提供高可靠性、高灵活性与长续航的解决方案。
当前试用赠送的Firebeetle 2 ESP32-C5开发板板载ESP32-C5模组为ECO1 版本,ECO1版本的ESP32-C5模组是基于 ESP32-C5 revision v0.1 版本芯片。

(2)Gravity: JoyStick 摇杆



DFRobot的JoyStick摇杆采用原装优质金属PS2摇杆电位器制作,具有(X,Y)2轴模拟输出,(Z)1路按钮数字输出。

(3)Gravity: I2C OLED-2864 显示屏



Gravity OLED-2864 显示屏是一款无需背景光源,自发光式的显示模块。模块采用蓝色背景,显示尺寸控制在0.96英寸,采用OLED专用驱动芯片SSD1306控制。模块采用Gravity I2C通用接口。

(4)ESP32编程掌机



ESP32编程掌机搭载了EESP32-D0WD MCU,并配备1.8寸ST7735 LCD屏幕、6个按键、蜂鸣器、光感器、电机驱动、锂电池,同时支持外接传感器扩展。

[*]按键:上=2,下=13,左=27,右=35,A =34,B= 12
[*]LCD屏幕:SPl=2,sck=18,mosi=23,cs=5,dc=4,res=19,bl=None
[*]SD卡:SPl=2,sck=18,mosi=23,miso=19,cs=22
[*]蜂鸣器:14,光照:36,热敏电阻:39,
[*]I2C:SCL=15,SDA=21
[*]端口1:33,端口2:32,端口3:26,端口4:25,端口5:UART,端口6:I2C

(5)Type-C&Micro二合一USB线



Type-C&Micro二合一USB线 ,采用扁平线不易打结,加上硅胶扎带方便收纳,同时两个接口都可以上传程序,一根线解决多种板子使用问题。

三、软件

1、开发环境:Thonny IDE
Thonny是一款专为Python初学者设计的集成开发环境(IDE),提供简洁直观的界面和易用特性,支持代码即时语法高亮显示、内置教程及逐步指导等功能,帮助用户专注于编程学习。



下载地址:https://github.com/thonny/thonny/releases/download/v4.1.7/thonny-4.1.7.exe

2、固件
(1)FireBeetle 2 ESP32-C5ESP32 MicroPython 固件

(2)游戏掌机MicroPython 固件
ESP32_GENERIC-SPIRAM-20250911-v1.26.1.bin
3、依赖库
(1)显示驱动库:st7735_buf.py(ST7735 LCD 屏幕底层驱动)
(2)显示工具库:easydisplay.py(简化 LCD 文本显示的封装库)
(3)系统内置库:network(网络配置)、espnow(ESP-NOW 通信)、machine(硬件引脚控制)、ubinascii(MAC 地址格式转换)三、制作过程1、硬件接线
(1)发送端接线(Gravity: JoyStick 摇杆、 FireBeetle 2 ESP32-C5)

VCC3.3V摇杆电源(不可接 5V,避免烧毁电位器)
GNDGND接地
X 轴(VRx)GPIO2X 轴模拟信号输入(接 ADC 引脚)
Y 轴(VRy)GPIO3Y 轴模拟信号输入(接 ADC 引脚)
SW(按键)不接线本项目暂不使用摇杆按键功能

(2)接收端(ESP32 、ST7735 LCD)

ST7735 LCD ESP32功能说明
VCC3.3V屏幕电源
GNDGND接地
SCK(时钟)GPIO18SPI 通信时钟线
SDA(数据)GPIO23SPI 通信数据线(MOSI)
CS(片选)GPIO5屏幕片选信号(低电平有效)
DC(数据 / 命令)GPIO4区分 SPI 传输的是命令还是数据
RES(复位)GPIO19屏幕复位信号(低电平复位)
BL(背光)不接线本项目暂不控制背光亮度

2、烧录固件
(1)Firebeetle 2 ESP32-C5
打开ESP系列芯片烧录工具,按下面步骤进行操作:

[*]选择正确的芯片类型,以Firebeetle 2 ESP32-C5 ver ECO1,选择esp32c5。
[*]选择“使用内置MicroPython固件”。
[*]点击“开始烧录”按钮。
[*]“确认”对话框中,点击“是”按钮,进入烧录程序。
[*]当出现“固件烧录完成”,即完成了固件烧录,如下图所示。

https://mc.dfrobot.com.cn/data/attachment/forum/202509/23/145756mzpg4vzpqopgnzzn.png
(2)ESP32编程掌机
打开ESP系列芯片烧录工具,按下面步骤进行操作:

[*]选择正确的芯片类型,这里选择esp32。
[*]选择“使用外置MicroPython固件”。
[*]点击“浏览”按钮,选择固件文件,这里选择ESP32_GENERIC-SPIRAM-20250911-v1.26.1.bin。
[*]输入正确的地址,这里使用0x1000。
[*]点击“开始烧录”按钮。
[*]“确认”对话框中,点击“是”按钮,进入烧录程序。
[*]当出现“固件烧录完成”,即完成了固件烧录。





3、依赖库上传
打开Thonny,选择“运行”->“配置解释器”,然后按下图所示进行设置。


选择菜单“视图”->“文件”,打开文件视图。在文件视图中找到要上传的库文件,右键弹出菜单选择“上传到/”,分别将ssd1306.pys上传到 FireBeetle 2 ESP32-C5,将t7735_buf.py和easydisplay.py上传到ESP32编程掌机。


4、编写程序
新建文件,复制 “发送端代码”,修改peer_mac为接收端的实际 MAC 地址,保存为main.py并上传到发送端 FireBeetle 2 ESP32-C5。新建文件,复制 “接收端代码”,保存为main.py并上传到ESP32编程掌机。
(1)发送端代码(main.py)
import network
import espnow
import time
import machine
import ubinascii
from machine import I2C, Pin
from ssd1306 import SSD1306_I2C

# ----------------------------
# 常量定义 - 集中管理配置参数
# ----------------------------
# ADC引脚配置 (连接摇杆)
ADC_X_PIN = 3
ADC_Y_PIN = 2

# 摇杆校准参数 (根据实际硬件调整)
JOYSTICK_CALIB = {
    'x_min': 1978,
    'x_center': 3634,
    'x_max': 4095,
    'y_min': 1974,
    'y_center': 3600,
    'y_max': 4095,
    'threshold': 50# 死区阈值
}

# OLED屏幕配置
OLED_WIDTH = 128
OLED_HEIGHT = 64
OLED_I2C_SCL = 10
OLED_I2C_SDA = 9

# ESP-NOW配置
TARGET_MAC = b'\xac\x67\xb2\x44\xba\x8c'# 目标设备MAC地址
LOOP_DELAY = 0.1# 主循环延迟(秒)

# 方向指令常量
DIRECTIONS = {
    'stop': 'Stop',
    'forward': 'Forward',
    'backward': 'Backward',
    'left': 'Left',
    'right': 'Right'
}

# ----------------------------
# 硬件初始化函数
# ----------------------------
def init_adc():
    """初始化ADC引脚用于读取摇杆值"""
    adc_x = machine.ADC(machine.Pin(ADC_X_PIN))
    adc_y = machine.ADC(machine.Pin(ADC_Y_PIN))
    # 设置衰减以支持0-3.3V范围
    adc_x.atten(machine.ADC.ATTN_11DB)
    adc_y.atten(machine.ADC.ATTN_11DB)
    return adc_x, adc_y

def init_oled():
    """初始化OLED屏幕"""
    i2c = I2C(0, scl=Pin(OLED_I2C_SCL), sda=Pin(OLED_I2C_SDA), freq=400000)
    oled = SSD1306_I2C(OLED_WIDTH, OLED_HEIGHT, i2c)
    oled.fill(0)# 清屏
    return oled

def init_espnow():
    """初始化ESP-NOW通信"""
    # 初始化WiFi为STA模式
    sta = network.WLAN(network.STA_IF)
    sta.active(True)
   
    # 显示本机MAC地址
    mac_bytes = sta.config('mac')
    mac_str = ubinascii.hexlify(mac_bytes, ':').decode()
    print(f"本机MAC地址: {mac_str}")
    sta.disconnect()# 不需要连接到AP
   
    # 初始化ESP-NOW
    esp_now = espnow.ESPNow()
    esp_now.active(True)
   
    # 添加目标设备
    esp_now.add_peer(TARGET_MAC)
    target_mac_str = ubinascii.hexlify(TARGET_MAC, ':').decode()
    print(f"已添加目标设备MAC: {target_mac_str}")
   
    return esp_now

# ----------------------------
# 功能函数
# ----------------------------
def read_joystick_values(adc_x, adc_y):
    """读取摇杆原始ADC值"""
    return adc_x.read(), adc_y.read()

def calculate_direction(x, y):
    """根据摇杆位置计算方向指令"""
    x_deviation = x - JOYSTICK_CALIB['x_center']
    y_deviation = y - JOYSTICK_CALIB['y_center']
   
    # 判断是否在死区内(停止状态)
    if abs(x_deviation) < JOYSTICK_CALIB['threshold'] and \
       abs(y_deviation) < JOYSTICK_CALIB['threshold']:
      return DIRECTIONS['stop']
   
    # 判断X/Y方向优先级
    if abs(x_deviation) > abs(y_deviation):
      return DIRECTIONS['right'] if x_deviation > 0 else DIRECTIONS['left']
    else:
      return DIRECTIONS['forward'] if y_deviation > 0 else DIRECTIONS['backward']

def calculate_analog_values(x, y):
    """
    计算摇杆的模拟量值(-127~+127)
    返回: (x_analog, y_analog)
    """
    x_deviation = x - JOYSTICK_CALIB['x_center']
    y_deviation = y - JOYSTICK_CALIB['y_center']
   
    # 如果在死区内,返回0
    if abs(x_deviation) < JOYSTICK_CALIB['threshold'] and \
       abs(y_deviation) < JOYSTICK_CALIB['threshold']:
      return 0, 0
   
    # 计算X轴模拟量
    if x_deviation > 0:
      # 右方向:从中心到最大值映射到0~127
      x_range = JOYSTICK_CALIB['x_max'] - JOYSTICK_CALIB['x_center']
      x_analog = int((x_deviation / x_range) * 127)
    else:
      # 左方向:从最小值到中心映射到-127~0
      x_range = JOYSTICK_CALIB['x_center'] - JOYSTICK_CALIB['x_min']
      x_analog = int((x_deviation / x_range) * 127)
   
    # 计算Y轴模拟量
    if y_deviation > 0:
      # 前方向:从中心到最大值映射到0~127
      y_range = JOYSTICK_CALIB['y_max'] - JOYSTICK_CALIB['y_center']
      y_analog = int((y_deviation / y_range) * 127)
    else:
      # 后方向:从最小值到中心映射到-127~0
      y_range = JOYSTICK_CALIB['y_center'] - JOYSTICK_CALIB['y_min']
      y_analog = int((y_deviation / y_range) * 127)
   
    # 限制在-127~127范围内
    x_analog = max(-127, min(127, x_analog))
    y_analog = max(-127, min(127, y_analog))
   
    return x_analog, y_analog

def send_analog_values(esp_now, x_analog, y_analog):
    """
    发送模拟量值到目标设备
    格式: "ANALOG:X:Y" 例如: "ANALOG:100:-50"
    """
    analog_msg = f"ANALOG:{x_analog}:{y_analog}"
    return esp_now.send(TARGET_MAC, analog_msg, True)

def get_centered_position(text, font_width=8, font_height=8):
    """计算文字在OLED屏幕上的居中位置"""
    text_width = len(text) * font_width
    x = (OLED_WIDTH - text_width) // 2
    y = (OLED_HEIGHT - font_height) // 2 + 8# 垂直居中偏上一点
    return x, y

# ----------------------------
# 主程序
# ----------------------------
def main():
    # 初始化硬件
    adc_x, adc_y = init_adc()
    #oled = init_oled()
    esp_now = init_espnow()
   
    # 显示目标设备信息
    target_mac_str = ubinascii.hexlify(TARGET_MAC, ':').decode()
    target_mac_str_no_colon = ubinascii.hexlify(TARGET_MAC).decode()
    oled.text(f"To:{target_mac_str_no_colon}", 0, 0)
    oled.show()
   
    last_direction = None
    last_x_analog = 0
    last_y_analog = 0
    analog_mode = False# 模拟量模式开关
   
    print("控制器启动,开始监控摇杆...")
   
    try:
      while True:
            # 读取并计算方向
            x, y = read_joystick_values(adc_x, adc_y)
            current_direction = calculate_direction(x, y)
            x_analog, y_analog = calculate_analog_values(x, y)         

            # 模拟量模式
            if x_analog != last_x_analog or y_analog != last_y_analog:
                send_result = send_analog_values(esp_now, x_analog, y_analog)
                if send_result:
                  print(f"发送模拟量: X={x_analog:4d}, Y={y_analog:4d}")
                else:
                  print(f"发送失败: X={x_analog:4d}, Y={y_analog:4d}")
               
                # 更新OLED显示
                oled.fill_rect(0, 16, OLED_WIDTH, OLED_HEIGHT-16, 0)
                oled.text("Analog Mode", 0, 16)
                oled.text(f"X:{x_analog:4d}", 0, 32)
                oled.text(f"Y:{y_analog:4d}", 0, 48)
                oled.show()
               
                last_x_analog = x_analog
                last_y_analog = y_analog

            
            time.sleep(LOOP_DELAY)
            
    except KeyboardInterrupt:
      print("程序被用户终止")
    finally:
      # 清理资源
      oled.fill(0)
      oled.text("Stopped", 40, 32)
      oled.show()
      esp_now.send(TARGET_MAC, DIRECTIONS['stop'], True)
      print("已发送停止指令,程序退出")

if __name__ == "__main__":
    main()


(2)接收端代码(main.py)
# 导入必要库:网络、ESP-NOW通信、硬件控制及LCD驱动
import network
import espnow
import time
from time import sleep_ms
from machine import SPI, Pin
from driver import st7735_buf# ST7735 LCD底层驱动
from driver import drivers         # 电机、光线传感器、温度传感器驱动
from lib.easydisplay import EasyDisplay# 简化LCD显示操作
import ubinascii

# ----------------------------------
# 1. 定义“计算居中坐标”的函数
# ----------------------------------
def get_center_pos(text, font_width=8, font_height=8):
    """
    计算文字居中时的起始坐标 (x, y)
    text: 要显示的文字(如 "forward")
    font_width: 字体宽度(默认 8 像素)
    font_height: 字体高度(默认 8 像素)
    """
    # 计算文字总宽度(字符数 × 字体宽度)
    text_total_width = len(text) * font_width
    # X 轴:屏幕水平中心 - 文字总宽度的一半
    x = (160 - text_total_width) // 2
    # Y 轴:屏幕垂直中心 - 字体高度的一半
    y = (128 - font_height) // 2 + 8
    return x, y

# 初始化
spi = SPI(2, baudrate=20000000, polarity=0, phase=0, sck=Pin(18), mosi=Pin(23))
dp = st7735_buf.ST7735(width=160, height=128, spi=spi, cs=5, dc=4, res=19, rotate=1, bl=None,invert=False, rgb=True)
ed = EasyDisplay(display=dp, font="/font/text_lite_16px_2312.v3.bmf", show=True, color=0xFFFF, clear=True,color_type="RGB565")
hd = drivers.HardwareDrivers()       # 创建硬件驱动实例

# 初始化ESP-NOW通信
# 初始化sta
sta = network.WLAN(network.STA_IF)
sta.active(True)
# 获取MAC地址(以字节形式)
mac_bytes = sta.config('mac')

# 将字节转换为人类可读的十六进制字符串
mac_str = ubinascii.hexlify(mac_bytes, ':').decode()

print(f"MAC地址: {mac_str}")
sta.disconnect()

ed.text(mac_str, 10, 10)

e = espnow.ESPNow()
e.active(True)# 启用ESP-NOW

def receive_messages():
    """接收ESP-NOW消息,处理后在LCD和串口显示"""
    while True:
      try:
            host, msg = e.recv(0)# 非阻塞接收消息
            
            if msg:
                # 解码消息
                command = msg.decode('utf-8').strip() if isinstance(msg, bytes) else str(msg).strip()
                # 格式化发送端MAC
                sender_mac = ':'.join(['%02x' % b for b in host])
                print(f"来自 {sender_mac} 的指令: {command}")
                              
                # LCD显示指令
                # ed.fill(0x0000)# 清屏(黑色)
                dir_x, dir_y = get_center_pos(command)
                ed.text(command, dir_x, dir_y)

                # 首先判断是方向指令还是模拟量指令
                if command.startswith("ANALOG:"):
                  # 模拟量指令 - 解析X和Y值
                  try:
                        parts = command.split(":")
                        x_analog = int(parts)
                        y_analog = int(parts)
                        
                        # 死区处理 - 如果摇杆接近中心位置,则停止
                        if abs(x_analog) < 10 and abs(y_analog) < 10:
                            hd.motor_stop("ALL")
                            print("车辆停止")
                           
                        else:
                            # 基础速度计算(基于Y轴)
                            base_speed = abs(y_analog) * 2# 转换为0-255范围
                           
                            # 转向系数(基于X轴)
                            turn_factor = x_analog / 127.0# -1.0 到 +1.0
                           
                            if y_analog > 10:# 前进
                              # 差速转向:一个轮子快,一个轮子慢
                              left_speed = int(base_speed * (1 - turn_factor))
                              right_speed = int(base_speed * (1 + turn_factor))
                              
                              # 限制速度在0-255范围内
                              left_speed = max(0, min(255, left_speed))
                              right_speed = max(0, min(255, right_speed))
                              
                              hd.motor_run(1, "CW", right_speed)# 右轮
                              hd.motor_run(2, "CW", left_speed)   # 左轮
                              print(f"前进 - 左轮: {left_speed}, 右轮: {right_speed}")
                              
                            elif y_analog < -10:# 后退
                              # 差速转向:一个轮子快,一个轮子慢
                              left_speed = int(base_speed * (1 + turn_factor))
                              right_speed = int(base_speed * (1 - turn_factor))
                              
                              # 限制速度在0-255范围内
                              left_speed = max(0, min(255, left_speed))
                              right_speed = max(0, min(255, right_speed))
                              
                              hd.motor_run(1, "CCW", right_speed)# 右轮
                              hd.motor_run(2, "CCW", left_speed)   # 左轮
                              print(f"后退 - 左轮: {left_speed}, 右轮: {right_speed}")
                              
                            else:# 原地转向(只有X轴输入)
                              turn_speed = abs(x_analog) * 2
                              if x_analog > 10:# 原地右转
                                    hd.motor_run(1, "CCW", min(turn_speed, 255))
                                    hd.motor_run(2, "CW", min(turn_speed, 255))
                                    print(f"原地右转 - 速度: {turn_speed}")
                              elif x_analog < -10:# 原地左转
                                    hd.motor_run(1, "CW", min(turn_speed, 255))
                                    hd.motor_run(2, "CCW", min(turn_speed, 255))
                                    print(f"原地左转 - 速度: {turn_speed}")
                                    
                  except (ValueError, IndexError):
                        print(f"模拟量指令解析错误: {command}")
                        
                else:
                  # 方向指令 - 原有的逻辑保持不变
                  if command == "Forward":
                        hd.motor_run(1, "CW", 255)
                        hd.motor_run(2, "CW", 255)
                        print("车辆前进")
                  elif command == "Backward":
                        hd.motor_run(1, "CCW", 255)
                        hd.motor_run(2, "CCW", 255)
                        print("车辆后退")
                  elif command == "Left":
                        hd.motor_run(1, "CW", 255)
                        hd.motor_run(2, "CCW", 255)
                        print("车辆左转")
                  elif command == "Right":
                        hd.motor_run(1, "CCW", 255)
                        hd.motor_run(2, "CW", 255)
                        print("车辆右转")
                  elif command == "Stop":
                        hd.motor_stop("ALL")
                        print("车辆停止")

            sleep_ms(10)
      except Exception as ex:
            print(f"接收错误: {ex}")
            sleep_ms(100)

def main():
    """主函数:初始化系统并启动消息接收"""
    try:
      # ed.fill(0x0000)
      receive_messages()# 启动接收循环
    except KeyboardInterrupt:
      print("程序被中断")
    except Exception as ex:
      print(f"错误: {ex}")
    finally:
      # 清理资源
      e.active(False)
      sta.active(False)
      ed.fill(0x0000)
      ed.text("已停止", 50, 60)

if __name__ == "__main__":
    main()




5、系统调试

(1)分别给发送端、接收端上电,打开 Thonny 的 “串口监视器”(波特率默认 115200)。

(2)发送端串口会打印自身 MAC 地址和 “准备发送指令” 提示;接收端会打印自身 MAC 地址和 “等待指令” 提示,LCD 屏幕显示 “ESPNow 接收端”“状态:运行中”。


(3)FireBeetle 2 ESP32-C5(发送端)拨动摇杆,发送ESPNOW指令,OLED屏幕显示“Forward/Backward/Left/Right”,串口打印 “发送指令:Forward/Backward/Left/Right/Stop”。


(4)ESP32掌机(接收端)串口打印 “来自 [发送端 MAC] 的指令:Forward/Backward/Left/Right/Stop”,且 LCD 屏幕实时显示“Forward/Backward/Left/Right/Stop”。





四、技术原理
1、ESP-NOW 通信
ESP-NOW 是一种由乐鑫公司定义的无连接 Wi-Fi 通信协议。在 ESP-NOW 中,应用程序数据被封装在各个供应商的动作帧中,然后在无连接的情况下,从一个 Wi-Fi 设备传输到另一个 Wi-Fi 设备。其特点是低延迟(毫秒级)、低功耗、无需 IP 地址,适合物联网设备间的短数据传输(如指令、传感器数据)。
(1)配对逻辑:发送端需先将接收端的 MAC 地址添加为 “peer(对等设备)”,才能向其发送数据;接收端无需主动添加,可被动接收已配对设备的消息。
(2)数据传输:本项目中发送端通过e.send(peer_mac, dir, True)发送指令(True表示等待接收端确认),接收端通过e.recv(0)非阻塞接收消息(0表示不等待,立即返回)。
2、ADC 摇杆信号采集
ESP32 的 ADC 模块(模拟 - 数字转换器)可将摇杆的模拟电压信号(0~3.3V)转换为 0~4095 的数字值(12 位精度)。
(1)信号校准:通过X_CENTER, Y_CENTER = 3634, 3600设置摇杆 “中立位置” 的基准值(需根据实际摇杆校准,避免漂移)。
(2)阈值过滤:通过THRESHOLD = 50设置 “死区阈值”,当摇杆偏移量小于 50 时,判定为 “stop”,避免轻微晃动导致误触发。
(3)方向判断:比较 X 轴(xd)和 Y 轴(yd)的偏移量绝对值,绝对值大的轴为 “有效方向”,再根据正负判断具体方向(如 xd>0 则为 “right”)。
3、LCD 屏幕显示
通过EasyDisplay封装库简化 ST7735 屏幕控制。
(1)初始化:先通过st7735_buf.ST7735配置 SPI 引脚、屏幕分辨率、旋转方向等底层参数,再通过EasyDisplay设置字体、默认颜色、清屏模式。
(2)文本显示:调用ed.text(内容, x坐标, y坐标)在指定位置显示文本,ed.fill(0x0000)实现清屏(0x0000 为 RGB565 格式的黑色)。
附件:程序、固件、工具

木子哦 发表于 2025-9-24 09:29:13

先占个坑
页: [1]
查看完整版本: FireBeetle 2 ESP32-C5基于ESPNOW的无线通信