目标

制作一个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. js 中prototype运用(数组)

    转自:http://www.cnblogs.com/chiname/articles/216517.html(侵删)  /*   *  方法:Array.removeAt(Index)   *  功能 ...

  2. 洛谷P4103 [HEOI2014]大工程(虚树 树形dp)

    题意 链接 Sol 虚树. 首先建出虚树,然后直接树形dp就行了. 最大最小值直接维护子树内到该节点的最大值,然后合并两棵子树的时候更新一下答案. 任意两点的路径和可以考虑每条边两边的贡献,\(d[x ...

  3. clipboard.js -- js实现将文本复制到剪贴板的方法

    资源 推荐使用:clipboard.js 官方教程地址:https://clipboardjs.com/#example-text 官方github地址:https://github.com/zeno ...

  4. 一年过去了,25万月薪的AI工程师还存在吗?

    导读:2017 年的时候,AI 前线进行了一场有关人工智能领域薪资差异的专题策划,这篇名为<25 万年薪的你与 25 万月薪的他,猎头来谈你们之间的差别>的文章引起了读者们的热烈讨论.一年 ...

  5. Salesforce 大量数据部署的最佳实践

    本文参考自官方文档.原文链接 大量数据部署对Salesforce的影响 当用户需要在Salesforce中部署大量数据的时候,部署的过程往往会变慢.这时就需要架构师或开发者设计出更好的过程来提高大量数 ...

  6. 7.Odoo产品分析 (二) – 商业板块(3) –CRM(1)

    查看Odoo产品分析系列--目录 CMR:Customer Relationship Management.企业为提高核心竞争力,利用相应的信息技术以及互联网技术协调企业与顾客间在销售.营销和服务上的 ...

  7. Java:JavaBean和BeanUtils

    本文内容: 什么是JavaBean JavaBean的使用 BeanUitls 利用DBUtils从数据库中自动加载数据到javabean对象中 首发日期:2018-07-21 什么是JavaBean ...

  8. 虚拟机中安装Virtualbox,嵌套的虚拟机不能运行64位系统

    https://www.quora.com/Can-I-install-Virtualbox-in-a-virtual-machine Here is a previous question on Q ...

  9. Git多人协作常用命令

    Git多人协作工作模式: 首先,可以试图用git push origin branch-name推送自己的修改. 如果推送失败,则因为远程分支比你的本地更新早,需要先用git pull试图合并. 如果 ...

  10. Django-404错误处理

    404错误是用户输入错误的URL,在 URLconf 中匹配不到相应的URL而抛出的异常 如下图: 为了给用户提供一个友好的访问,需要配置404错误页面 1.在 templates 目录下新建 404 ...