目标

制作一个ESP8266串口和MQTT相互透传的小WIFI,可用手机修改其连接的路由器,由此该模块可以任意加载到各种串口传输的单片机上,完成硬件到云端的传输。

1 实物图

2 MQTT网页测试客户端

链接:https://pan.baidu.com/s/1th4U0_nC3FOnvusPokYSGQ
提取码:j7fm

3 ESP8266硬件程序烧录代码

//----------------------------------------------------------------------------------------//
//-----------------------------------程序功能-----------------------------------------//
/*
总功能: 制作一个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 <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <math.h>
#include <EEPROM.h>
WiFiClient espClient;
PubSubClient client(espClient); //----------------------------------------------------------------------------------------//
//-----------------------------------配置信息开始-----------------------------------------//
//----------------------------------------------------------------------------------------//
// 产品唯一ID 微信分配
#define PRODUCT_ID "gh_e93c1b3098b9_cc8c4f4cd693972f" // 默认连接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(999999999),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);
} /**************************************************************************/ void serial_mqtt_sendmsg(){ //-------------------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, 100) ;
client.publish(MQTT_PUB_TOPIC,charBuf);
comdata = "";
}
//-------------------End----------------------// } //初始化函数
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){
// 初始化连接
reconnect();//确保连上服务器,否则一直等待。
// 订阅话题等待
client.loop();//MUC接收数据的主循环函数。
// 将串口数据发送给服务器
serial_mqtt_sendmsg(); }
else
{
Serial.println("wifi fail!");
setup_wifi() ;
} }

  

ESP8266串口和MQTT服务器消息互传(版本一) 单纯透传+保存WIFI账号信息的更多相关文章

  1. APP消息推送:通知和透传

    目前市场上的消息推送方式有两种:通知和透传.什么是透传?透传即是透明传送,即传送网络无论传输业务如何,只负责将需要传送的业务传送到目的节点,同时保证传输的质量即可,而不对传输的业务进行处理.透传消息, ...

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

    //----------------------------------------------------------------------------------------// //----- ...

  3. 4G DTU为什么要具有透传的功能

    4G DTU为什么要透传 透传的目的就是为了在数据传输的过程中不对数据做任何出来,实现发送方和接收方的数据完全一样,长度和内容完全没有变化.它主要是使用在智能设备之间的远程串口数据传输,是一种和传输方 ...

  4. 手把手教你开发BLE数据透传应用程序

    如何开发BLE数据透传应用程序?什么是BLE service和characteristic?如何开发自己的service和characteristic?如何区分ATT和GATT?有没有什么工具可以对B ...

  5. ESP8266局域网 路由器下作服务器模式串口透传 arduino uno示例 模板参考2

    ESP8266服务器模式串口透传编译需要下载8266的库文件后才可以正常 准备工作 下载一个Arduino IDE,下载8266的库文件ESP8266服务器模式串口透传编译 功能说明 1.直接使用路由 ...

  6. ESP8266局域网智能家居 路由器下作服务器模式串口透传 无线通信控制 arduino uno示例 模板参考

    准备工作 下载一个Arduino IDE, 下载8266的库文件 ESP8266服务器模式串口透传编译 功能说明 1.直接使用路由器中转数据 2.手机放热点模式直接传输数据 两者有访问IP地址的差别, ...

  7. 18-ESP8266 SDK开发基础入门篇--TCP 服务器 RTOS版,串口透传,TCP客户端控制LED

    https://www.cnblogs.com/yangfengwu/p/11112015.html 先规定一下协议 aa 55 02 01 F1 4C 控制LED点亮  F1 4C为CRC高位和低位 ...

  8. (一)基于阿里云的MQTT远程控制(Android 连接MQTT服务器,ESP8266连接MQTT服务器实现远程通信控制----简单的连接通信)

    如果不了解MQTT的可以看这篇文章  http://www.cnblogs.com/yangfengwu/p/7764667.html http://www.cnblogs.com/yangfengw ...

  9. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于Wi-Fi模块(ESP8266)AT指令TCP透传方式,MQTT通信控制升级(加入数据校验)

    前言 这节演示下,上两节写的利用MQTT来控制STM32控制的程序 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说明) 一,下载BootLoader程序(请自行下载) 首先BootLo ...

随机推荐

  1. es6 语法 (iterator和for...of循环)

    Iterator遍历器 遍历器(Iterator)就是这样一种机制.它是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据 ...

  2. jQuery 简单案例

    案例一:全选.反选.取消实例 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  3. Python基础知识点

    自学记录: 1.字符串 python中单引号和双引号使用完全相同. 使用三引号('''或""")可以指定一个多行字符串. 转义符 '\' 反斜杠可以用来转义,使用r可以让 ...

  4. Android项目实战(四十二):启动页优化,去除短暂白屏或黑屏

    大家会发现一个空项目,从手机桌面打开app是秒启动.但是对于自己开发的项目,有时会发现打开app的时候,会有短暂的1秒--2秒的白屏或者黑屏,然后才进入到程序界面. 个人理解为我们自己实现的Appli ...

  5. 章节二、1-java概述-数据类型

    一.数据类型 1.基本数据类型 a.数值型 1.整数:byte(1个字节=8位) min:-128 max:127 default:0 .short(2个字节=16位) min:-32768 max: ...

  6. Windows桌面或服务器环境下嵌入JavaScript支持(JSRT)

    很多人比较关注Google的JS V8 JavaScript引擎,确实Google最近很高调.但这个库在Windows下使用确实有点难度,即使在Linux嵌入,也需要下载gyp,编译安装,然后再下载v ...

  7. 2018-05-27-computer-using-hints-电脑使用帮助[持续更新]

    layout: post title: 2018-05-27-computer-using-hints-电脑使用帮助 key: 20180527 tags: ubuntu cuda cudnn ten ...

  8. mysql执行语句提示Table 'performance_schema.session_variables' doesn't exist

    用管理员身份cmd进入mysql安装目录bin里,执行 mysql_upgrade -u root -p 如果杀毒软件拦截,添加为信任区

  9. [20181007]12cR2 Using SQL Patch.txt

    [20181007]12cR2 Using SQL Patch.txt --//12cR2 已经把sql打补丁集成进入dbms_sqldiag,不是11g的 DBMS_SQLDIAG_INTERNAL ...

  10. ASP.NET MVC概述及第一个MVC程序

    一.ASP.NET 概述        1. .NET Framework 与 ASP.NET                .NET Framework包含两个重要组件:.NET Framework ...