目标

制作一个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. 二、Laravel手动下载安装及初始化配置(此处以Laravel5.2为例)

    1.下载安装Laravel5.2的几种方法 —— 一键安装包下载: —— http://www.golaravel.com/download/ —— github下载 —— https://githu ...

  2. canvas-8clip.html

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 二进制安装 kubernetes 1.12(五) - 运行测试实例

    检查集群状态 # 在 master 上 kubectl get node kubectl get cs 注册登录阿里云容器仓库 因国内无法获得 google 的 pause-amd64 镜像,我这里使 ...

  4. angular 时间戳转换(星期过滤器)

    {{(value.time+'000' | date:'yyyy-MM-dd HH:mm:ss') : '/'}} .filter('getWeek', function() { return fun ...

  5. BZOJ3028: 食物(生成函数)

    题意 链接 Sol 生成函数入门题. 对每个物品分别列一下,化到最后是\(\frac{x}{(1-x)^4}\) 根据广义二项式定理,最后答案是\(C_{(N - 1) + 4 - 1}^{4-1} ...

  6. 「Android」消息驱动Looper和Handler类分析

    Android系统中的消息驱动工作原理: 1.有一个消息队列,可以往这个消息队列中投递消息; 2.有一个消息循环,不断的从消息队列中取得消息,然后处理. 工作流程: 1.事件源将待处理的消息加入到消息 ...

  7. 搭建的flask项目,若修改项目中的文件,项目没有reload,除非重启主机,解决方法如下

    1.博主本人前面有发过一篇博文如何搭建flask项目,可以去查看. 解决办法:加入一句 touch-reload=项目目录在uwsgi.ini 2.测试没问题

  8. XSS攻击介绍

    一.概念 XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞, ...

  9. js获取地址栏中的数据

    window.location.href:设置或获取整个 URL 为字符串window.location.pathname:设置或获取对象指定的文件名或路径window.location.search ...

  10. C#计算时间差 TimeSpan

    TimeSpan的相关属性 Add:与另一个TimeSpan值相加. Days:返回用天数计算的TimeSpan值. Duration:获取TimeSpan的绝对值. Hours:返回用小时计算的Ti ...