mqtt与硬件交互_微信硬件平台(十) 1 ESP8266通过mqtt交互消息

该程序展示了如何使用ESP8266通过MQTT协议与服务器进行通信,包括配置WiFi连接、MQTT服务器连接、订阅与发布消息。设备在上电后自动连接预设或通过智能配置的WiFi,并尝试连接MQTT服务器。当收到服务器消息或串口输入时,设备将响应并发送数据。此外,还提供了按键控制LED状态的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//----------------------------------------------------------------------------------------//

//-----------------------------------程序功能-----------------------------------------//

/*

总功能: 制作一个MQTT服务器和ESP8266串口互相传输消息的模块

如何使用:

1修改每个芯片的信息

1-1 修改每一个产品的ID

1-2 修改对应MQTT服务器配置信息

1-3 修改默认登陆WIFI的消息

2使用步骤

2-1 连接WIFI

上电前5S内

如果检测到超过2S的按键长按,进入配网模式,LED慢闪。配网成功后,自动记录WIFI的账号和密码。

如果没有检测到超过2S的按键动作,5s后自动进入连接WIFi模式,,LED快闪,连接上次记录的WIFI。

2-2 连接MQTT服务器

连接不成功,5S后重连。

连接成功,等待服务器发送过来消息,或者将自己的串口收到的消息发送给MQTT服务器

2-3 按键功能预留

按下按键,led亮

离开按键,led灭

*/

//----------------------------------------------------------------------------------------//

#include

#include

#include

#include

WiFiClient espClient;

PubSubClient client(espClient);

//----------------------------------------------------------------------------------------//

//-----------------------------------配置信息开始-----------------------------------------//

//----------------------------------------------------------------------------------------//

// 产品唯一ID 微信分配

#define PRODUCT_ID "bowuguan_jiance"

// 默认连接WIFI账号密码

#define DEFAULT_STASSID "dongdong"//默认连接的路由器的名字 HUAWEI-H3VBKZ

#define DEFAULT_STAPSW "dongdong"//默认连接的路由器的名字 13991320168

//通信服务器消息

#define MQTT_SEVER "www.dongvdong.top"

#define MQTT_PORT 1883

#define MQTT_USER "dongdong"

#define MQTT_PASS "dongdong"

#define MQTT_ID PRODUCT_ID // 使用产品ID充当服务器识别ID

#define MQTT_PUB_TOPIC PRODUCT_ID"/s" // 发布话题 产品ID+/s

#define MQTT_REC_TOPIC PRODUCT_ID"/r" // 接受话题 产品ID+/r

// led状态反转

bool ledState=0;

// 配网

#define Smart_KEY D2 //配网按键

#define Smart_LED D4 //配网LED指示灯

//led控制按键中断

#define Use_LED D4 //控制LED

#define Use_KEY D2 //控制LED的按键

//-----------------------------------配置信息结束-----------------------------------------//

#define MAGIC_NUMBER 0xAA

struct config_type

{

char stassid[32];

char stapsw[64];

uint8_t magic;

};

config_type config;

char sendmsg[100];// 发送话题

/***************************(1.1)按键LED函数()*****************************/

// LED管脚口初始化

void LED_begin(){

pinMode(Use_LED,OUTPUT);

digitalWrite(Use_LED, LOW);

pinMode(Use_KEY, INPUT);

detachInterrupt(Use_KEY);

attachInterrupt(Use_KEY, highInterrupt, RISING);

}

// 高电平触发

void highInterrupt(){

digitalWrite(Use_LED, LOW);

detachInterrupt(Use_KEY);

attachInterrupt(Use_KEY, lowInterrupt,FALLING);

}

// 低电平触发

void lowInterrupt(){

digitalWrite(Use_LED, HIGH);

detachInterrupt(Use_KEY);

attachInterrupt(Use_KEY, highInterrupt, RISING);

}

/**************************************************************/

/*************************(2) WIFI连接设置 *************************************/

/* 1连接WIFI 自动连WIFI接入网络*/

void setup_wifi() {

WiFi.begin(config.stassid, config.stapsw);

while (WiFi.status() != WL_CONNECTED) {

ESP.wdtFeed();

delay(200);

ledState = !ledState;

digitalWrite(Smart_LED, ledState);

Serial.print("...");

}

Serial.println("\r\n--------------WIFi CONNECT!-------------\r\n");

Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());

Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());

}

/**************************************************************************/

/*************************(3) 服务器连接设置 *************************************/

/* 2连接服务器 等待,直到连接上服务器*/

void reconnect() {//等待,直到连接上服务器

while (!client.connected()) {//如果没有连接上

Serial.println("Connect lost!");//连接失败

if (client.connect(MQTT_ID+random(99999),MQTT_USER,MQTT_PASS)) {//接入时的用户名,尽量取一个很不常用的用户名

client.subscribe(MQTT_REC_TOPIC);//接收外来的数据时的intopic

client.publish(MQTT_PUB_TOPIC,"hello world ");

Serial.println("Connect sever succes!");//连接

} else {

Serial.println("failed, rc=");//连接失败

Serial.print(client.state());//重新连接

Serial.println(" try again in 5 seconds");//延时5秒后重新连接

delay(5000);

}

}

}

void callback(char* topic, byte* payload, unsigned int length) {//用于接收数据

char recmsg[length+1];

for (int i = length-1; i >=0; i--) {

recmsg[i]=(char)payload[i];

}

recmsg[length]='\0';

Serial.println(recmsg);

// String str(recmsg); // char 转换String

}

/**************************************************************************/

/*************************(4) smartConfig配置 *************************************/

void smartConfig()

{

Serial.println("Start smartConfig module");

pinMode(Smart_LED, OUTPUT);

digitalWrite(Smart_LED, 0);

WiFi.mode(WIFI_STA);

Serial.println("\r\nWait for Smartconfig");

WiFi.stopSmartConfig();

WiFi.beginSmartConfig();

while (1)

{

Serial.print(".");

digitalWrite(Smart_LED, 0);

delay(500);

digitalWrite(Smart_LED, 1);

delay(500);

if (WiFi.smartConfigDone())

{

Serial.println("SmartConfig Success");

strcpy(config.stassid, WiFi.SSID().c_str());

strcpy(config.stapsw, WiFi.psk().c_str());

Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());

Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());

saveConfig();

break;

}

}

}

/**************************************************************************/

/*******************************5 保存信息**************************************/

/*

* 保存参数到EEPROM

*/

void saveConfig()

{

Serial.println("Save config!");

Serial.print("stassid:");

Serial.println(config.stassid);

Serial.print("stapsw:");

Serial.println(config.stapsw);

EEPROM.begin(1024);

uint8_t *p = (uint8_t*)(&config);

for (int i = 0; i < sizeof(config); i++)

{

EEPROM.write(i, *(p + i));

}

EEPROM.commit();

}

/*

* 从EEPROM加载参数

*/

void loadConfig()

{

EEPROM.begin(1024);

uint8_t *p = (uint8_t*)(&config);

for (int i = 0; i < sizeof(config); i++)

{

*(p + i) = EEPROM.read(i);

}

EEPROM.commit();

//出厂自带

if (config.magic != MAGIC_NUMBER)

{

strcpy(config.stassid, DEFAULT_STASSID);

strcpy(config.stapsw, DEFAULT_STAPSW);

config.magic = MAGIC_NUMBER;

saveConfig();

Serial.println("Restore config!");

}

Serial.println(" ");

Serial.println("-----Read config-----");

Serial.print("stassid:");

Serial.println(config.stassid);

Serial.print("stapsw:");

Serial.println(config.stapsw);

Serial.println("-------------------");

}

void waitKey()

{

pinMode (Smart_LED, OUTPUT);

pinMode (Smart_KEY, INPUT);

digitalWrite(Smart_LED, 0);

Serial.println(" press key 2s: smartconfig mode! \r\n press key <2s: connect wifi!");

char keyCnt = 0;

unsigned long preTick = millis();

unsigned long preTick2 = millis();

int num = 0;

while (1)

{

ESP.wdtFeed();

if (millis() - preTick < 10 ) continue;//等待10ms

preTick = millis();

num++;

if (num % 20 == 0) //50*10=500ms=0.5s 反转一次

{

ledState = !ledState;

digitalWrite(Smart_LED, ledState);

// delay(1);

Serial.print(".");

}

if (keyCnt >= 200 && digitalRead(Smart_KEY) == 1)

{ //按2S 进入一键配置

keyCnt = 0;

Serial.println("\r\n try to begin smartConfig! \r\n");

smartConfig();// 手机灵活设置WIFI

break;

}

// 不按按键,自动连接上传WIFI

if (millis() - preTick2 > 5 * 1000) {

Serial.println("\r\n try to connect wifi! \r\n");

setup_wifi();

break;

}

if (digitalRead(Smart_KEY) == 1){ keyCnt++;}

else{keyCnt = 0;}

}

digitalWrite(Smart_LED, 0);

pinMode (Smart_KEY, OUTPUT);

}

/**************************************************************************/

String serial_read(){

//-------------------Begin----------------------//

//功能: 通过串口给MQTT服务器发送数据

if(Serial.available()>0){

delay(100);

String comdata = Serial.readString();

Serial.print("Serial.readString:");

//从串口缓存区中读取的整个字符串,直至检测到终止字符。

// char terminator = ',';

// String comdata =Serial.readStringUntil(terminator);

// Serial.print("Serial.readStringUntil: ");

Serial.println(comdata);

while(Serial.read()>= 0){}

/// char charBuf[100];

/// comdata.toCharArray(charBuf, sizechar) ;

// client.publish(MQTT_PUB_TOPIC,charBuf);

// comdata = "";

return comdata;

}

else return "fail";

//-------------------End----------------------//

}

bool serial_mqtt_sendmsg(String comdata){

if(comdata=="fail")return 0;

int sise_s=500;

char charBuf[sise_s];

comdata.toCharArray(charBuf, sise_s) ;

client.publish(MQTT_PUB_TOPIC,charBuf);

comdata = "";

return 1;

}

//初始化函数

void setup() {//初始化程序,只运行一遍

Serial.begin(9600);//设置串口波特率(与烧写用波特率不是一个概念)

loadConfig();// 读取信息

waitKey();

delay(5000);

client.setServer(MQTT_SEVER, MQTT_PORT);//端口号

client.setCallback(callback); //用于接收服务器接收的数据

LED_begin();//设置LED模式

}

// 循环主函数

void loop() {//主循环

if(WiFi.status() == WL_CONNECTED){

// 初始化连接

if (!client.connected()) {

reconnect();//确保连上服务器,否则一直等待。

}

// 订阅话题等待

client.loop();//MUC接收数据的主循环函数。

// 从串口读数据

String serial_string=serial_read();

// 将串口数据发送给服务器

serial_mqtt_sendmsg(serial_string);

serial_string="";

}

else

{

Serial.println("wifi fail!");

setup_wifi() ; // wifi

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值