3. MQTT 消息接收计数器

MQTT 消息接收计数器 学习卡片

任务目标

本案例实现一个LVGL图表控件,通过MQTT订阅主题接收传感器数值,并将数据实时绘制为曲线。完成本案例后,你将得到一个可在嵌入式设备或模拟器上运行的独立演示程序,能够动态更新曲线数据。

环境依赖

  • LVGL v8.x(已初始化,显示器与触摸驱动可用)
  • MQTT客户端库(如paho.mqtt.embedded-c或ESP-MQTT),需提供连接、订阅、回调接口
  • 开发板具备网络连接能力(如ESP32、STM32+W5500)

核心实现

以下代码创建了一个包含60个数据点的折线图,通过MQTT回调函数接收sensor/temp主题的数值,将新数据移入图表并刷新显示。代码中mqtt_client_connect()和mqtt_subscribe()为MQTT库的接入函数,实际使用时需根据所选库进行适配。

#include "lvgl.h"
#include "mqtt_client.h"  // 根据实际MQTT库调整头文件

#define DATA_POINTS 60
#define CHART_RANGE 100  // Y轴范围0-100

static lv_obj_t *chart;
static lv_chart_series_t *series_temp;

// MQTT消息回调:解析温度值并更新曲线
static void mqtt_data_callback(const char *topic, const uint8_t *payload, uint32_t len)
{
    if (strcmp(topic, "sensor/temp") != 0) return;

    // 将payload转为整数(假设数据格式为纯数字字符串)
    char buf[16];
    uint32_t copy_len = len < 15 ? len : 15;
    memcpy(buf, payload, copy_len);
    buf[copy_len] = '\0';
    int temp = atoi(buf);

    // 将新值加入图表,自动移除最旧数据点
    lv_chart_set_next_value(chart, series_temp, temp);
    lv_chart_refresh(chart);  // 触发重绘
}

void chart_mqtt_demo_create(void)
{
    // 创建图表控件
    chart = lv_chart_create(lv_scr_act());
    lv_obj_set_size(chart, 400, 200);
    lv_obj_center(chart);

    // 配置Y轴范围与数据点数
    lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, CHART_RANGE);
    lv_chart_set_point_count(chart, DATA_POINTS);

    // 不显示数据点标记,仅连线
    lv_obj_set_style_size(chart, 0, LV_PART_INDICATOR);

    // 添加数据系列
    series_temp = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_BLUE),
                                      LV_CHART_AXIS_PRIMARY_Y);

    // 初始化数据为0
    lv_chart_set_all_value(chart, series_temp, 0);

    // 连接MQTT并订阅主题(需根据实际MQTT库实现)
    mqtt_client_connect("192.168.1.100", 1883);
    mqtt_subscribe("sensor/temp", mqtt_data_callback);
}

运行与验证

  1. 将上述代码集成到你的LVGL项目中,确保chart_mqtt_demo_create()在UI初始化后被调用。
  2. 配置MQTT服务器地址与端口,确保设备能访问该服务器。
  3. 使用MQTT客户端工具(如MQTT.fx)向sensor/temp主题发布0~100之间的整数值。
  4. 观察屏幕上的图表:每次发布新值,曲线应向右移动并显示最新数据点。

通过条件:连续发布10个以上不同数值,图表曲线能实时更新且无卡顿或崩溃,旧数据点被正确移出显示区域。

关键说明

  • 本示例假设MQTT消息为纯数字字符串,若实际为JSON或二进制格式,需在回调中增加相应解析逻辑。
  • 图表Y轴范围固定为0~100,若传感器数据超出此范围,需调整CHART_RANGE或改为动态范围。
  • LVGL图表默认在数据点达到point_count后自动左移,无需手动管理环形缓冲。