You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Preferences.h在ESP8266中持久化MQTT配置?

问题

我正在为电池驱动的ESP8266编写代码,实现传感器数据读取并发布到MQTT总线,希望移除硬编码的凭据。WiFiManager.h库默认支持通过ConfigPortal网页界面修改WiFi凭据,我想在此基础上添加可修改并持久化保存的MQTT自定义字段。

我的实现思路伪代码如下:

#include <Preferences.h>

// Declare vars 
char mqtt_server[40];
char mqtt_port[6];
char mqtt_user[20];
char mqtt_pass[20];

// Read data from persistant memory or else return default
mqtt_server = preferences.getChar("mqtt_server", "default mqtt server");
mqtt_port = preferences.getChar("mqtt_port", "default mqtt port");
mqtt_user = preferences.getChar("mqtt_user", "default mqtt user");
mqtt_pass = preferences.getChar("mqtt_pass", "default mqtt pass");

// Connect to mqtt broker using the vars as just defined

// Pushing a button starts a ConfigPortal webinterface to change these vars
// Write new data to persistant memory
// get the new data from the webform (called "Mqtt_server.
preferences.begin("mqtt_config", false);
preferences.putChar("mqtt_server", new_mqtt_server);
preferences.putChar("mqtt_port", new_mqtt_port);
preferences.putChar("mqtt_user", new_mqtt_user);
preferences.putChar("mqtt_pass", new_mqtt_pass);
preferences.end();

目前我遇到两个问题:

  1. 如何将完整数据写入mqtt_server变量?当前仅能获取第一个字符;
  2. 为何getChar仅允许整数作为默认返回值,而无法设置默认文本?

解决方案

问题1:仅获取第一个字符的修复

你误用了Preferences库的API:getChar()和putChar()是专门用来操作单个字符(char类型,本质是8位整数)的,完全不适合处理字符串。要读写字符串,必须使用getString()和putString()方法。

正确的持久化读写代码示例:

#include <Preferences.h>

Preferences preferences;

// 声明字符串缓冲区
char mqtt_server[40];
char mqtt_port[6];
char mqtt_user[20];
char mqtt_pass[20];

void setup() {
  // 初始化Preferences,命名空间为"mqtt_config",只读模式
  preferences.begin("mqtt_config", false);
  
  // 从持久化存储读取字符串,参数依次为:键名、存储缓冲区、缓冲区大小、默认值
  preferences.getString("mqtt_server", mqtt_server, sizeof(mqtt_server), "default.mqtt.server");
  preferences.getString("mqtt_port", mqtt_port, sizeof(mqtt_port), "1883");
  preferences.getString("mqtt_user", mqtt_user, sizeof(mqtt_user), "");
  preferences.getString("mqtt_pass", mqtt_pass, sizeof(mqtt_pass), "");
  
  preferences.end();

  // 此处可使用读取到的参数连接MQTT broker
}

// 保存新的MQTT配置到持久化存储
void saveMqttConfig(const char* newServer, const char* newPort, const char* newUser, const char* newPass) {
  preferences.begin("mqtt_config", true); // 切换为写入模式
  
  preferences.putString("mqtt_server", newServer);
  preferences.putString("mqtt_port", newPort);
  preferences.putString("mqtt_user", newUser);
  preferences.putString("mqtt_pass", newPass);
  
  preferences.end();
}

问题2:getChar不支持文本默认值的原因

getChar()的设计目标就是读取单个字符数据,它的返回值是char类型(本质是整数),因此只能接受整数作为默认值,从根本上就不具备处理字符串的能力。处理字符串必须用getString(),这个方法支持传入字符串默认值,还能指定缓冲区大小避免溢出。


补充:结合WiFiManager添加MQTT配置项

要在WiFiManager的ConfigPortal中显示MQTT配置输入框,需要用WiFiManagerParameter定义字段,示例代码片段:

#include <WiFiManager.h>

WiFiManager wm;

// 定义MQTT配置参数,关联到之前的缓冲区
WiFiManagerParameter mqtt_server_param("mqtt_server", "MQTT Server", mqtt_server, 40);
WiFiManagerParameter mqtt_port_param("mqtt_port", "MQTT Port", mqtt_port, 6);
WiFiManagerParameter mqtt_user_param("mqtt_user", "MQTT User", mqtt_user, 20);
WiFiManagerParameter mqtt_pass_param("mqtt_pass", "MQTT Password", mqtt_pass, 20);

void setup() {
  // 先读取已保存的MQTT配置(前面的代码)
  
  // 将参数添加到WiFiManager
  wm.addParameter(&mqtt_server_param);
  wm.addParameter(&mqtt_port_param);
  wm.addParameter(&mqtt_user_param);
  wm.addParameter(&mqtt_pass_param);
  
  // 触发按钮时启动配置门户(示例)
  // if(buttonPressed()) {
  //   if(wm.startConfigPortal("ESP8266-Config")) {
  //     // 获取新配置并保存
  //     strncpy(mqtt_server, mqtt_server_param.getValue(), sizeof(mqtt_server));
  //     strncpy(mqtt_port, mqtt_port_param.getValue(), sizeof(mqtt_port));
  //     strncpy(mqtt_user, mqtt_user_param.getValue(), sizeof(mqtt_user));
  //     strncpy(mqtt_pass, mqtt_pass_param.getValue(), sizeof(mqtt_pass));
  //     saveMqttConfig(mqtt_server, mqtt_port, mqtt_user, mqtt_pass);
  //   }
  // }
}

内容的提问来源于stack exchange,提问作者Szjoin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:10:16