目标

制作一个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. java.net.ProtocolException:unexpected end of stream

    原因:php 给android 写接口出现java.net.ProtocolException:unexpected end of stream,查找android方面原因时发现数据超长 ,发现htm ...

  2. 实现响应式——CSS变量

    CSS 变量是 CSS 引入的一个新特性,目前绝大多数浏览器已经支持了,它可以帮助我们用更少的代码写出同样多的样式,大大提高了工作效率,本篇文章将教你如何使用 CSS 变量(css variable) ...

  3. js截图及绕过服务器图片保存至本地(html2canvas)

    今天要分享的是用html2canvas根据自己的需求生成截图,并且修复html2canvas截图模糊,以及绕过服务器图片保存至本地. 只需要短短的几行代码,就能根据所需的dom截图,是不是很方便,但是 ...

  4. 洛谷P3247 [HNOI2016]最小公倍数(分块 带撤销加权并查集)

    题意 题目链接 给出一张带权无向图,每次询问\((u, v)\)之间是否存在一条路径满足\(max(a) = A, max(b) = B\) Sol 这题居然是分块..想不到想不到..做这题的心路历程 ...

  5. MySQL服务无法启动 3534

    1.环境变量配置完成 2.配置文件编辑完成 3.启动服务(启动不成功,错误信息“MySQL服务无法启动 请键入 NET HELPMSG 3534 以便获得更多的帮助”) 错误原因:mysql安装目录下 ...

  6. docker swarm 集群进入某节点容器失败的原因及解决方法

    今日在自己的docker swarm 测试环境中,想进入某个节点的容器去查看下,结果进入容器失败,并且报了如下错误信息: [root@worker1 ~]# docker exec -it 9a6f6 ...

  7. Tomcat_记一次tomcatwar包应用简单部署过程

    记一次tomcat war包应用简单部署过程 by:授客 QQ:1033553122 1.  实践环境 Linux apache-tomcat-7.0.73 2.  实践步骤 # 解压tomcat压缩 ...

  8. 使用fiddler抓包手机请求数据

    1.启动Fiddler,打开菜单栏中的 Tools > Fiddler Options,打开“Fiddler Options”对话框. 2.在Fiddler Options”对话框切换到“Con ...

  9. windows server 2008 r2安装windows media player

    1.打开“服务器管理器”: 2.依次单击“功能” →  “添加功能”: 3.勾选“桌面体验”和“优质Windows音频视频体验”: 4.单击“安装”按钮:安装完毕,根据提示重新启动计算机即可.

  10. coTurn测试程序之turnutils_stunclient.exe

    测试使用方法,作为STUN客户端,仅用于测试STUN服务是否正常运行. 使用coTurn服务启动STUN/TURN服务后,执行以下命令即可: turnutils_stunclient -p 61.18 ...