//----------------------------------------------------------------------------------------//
//-----------------------------------程序功能-----------------------------------------//
/*
总功能: 制作一个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 "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
} }

  

微信硬件平台(十) 1 ESP8266通过mqtt交互消息的更多相关文章

  1. 微信硬件平台(一) 公众号 ESP8266 Arduino LED

    微信硬件平台 本文目的,使用微信公众号控制ESP8266的LED开和关.进一步使用微信当遥控器(避免写APP或者IOS或者小程序),控制一切设备.给两个关键的总教程参考. 官网教程  微信硬件平台 微 ...

  2. ESP8266串口和MQTT服务器消息互传(版本一) 单纯透传+保存WIFI账号信息

    目标 制作一个ESP8266串口和MQTT相互透传的小WIFI,可用手机修改其连接的路由器,由此该模块可以任意加载到各种串口传输的单片机上,完成硬件到云端的传输. 1 实物图 2 MQTT网页测试客户 ...

  3. 【002:ESP8266 移植 Mqtt 】

    系统环境: ubuntu 16.04 64bitSDK版本: esp_iot_sdk_v1.3.0记录时间: 2016年10月13日联系方式: yexiaopeng1992@126.com 背景:在E ...

  4. 微信硬件平台(八) 3-0ESP8266向微信服务器请求设备绑定的用户

    1调试助手 请求URL: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=自己微信ID&a ...

  5. 【好好编程-技术博客】微信小程序开发中前后端的交互

    微信小程序开发中前后端的交互 微信小程序的开发有点类似与普通网页的开发,但是也不尽然相同.小程序的主要开发语言是JavaScript,开发同普通的网页开发有很大的相似性,对于前端开发者而言,从网页开发 ...

  6. [3] 微信公众号开发 - 结合UEditor实现图文消息群发功能

    0.写在前面的话 如何实现微信平台后台管理中的,图文消息发送功能? 大概的过程如下: 通过类似表单的形式,将文章各部分内容提交到后台,封装成一个实体类,并持久化到数据库中 需要推送的时候,将不同的文章 ...

  7. 微信公众号开发C#系列-7、消息管理-接收事件推送

    1.概述 在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者在开发者中心处设置的服务器地址,从而开发者可以获取到该信息.其中,某些事件推送在发生后,是允许 ...

  8. C# 微信公众平台开发(4)-- 模版消息

    微信公众平台开发 --发送模版消息 发送模版消息是微信服务号给某个用户发送模版消息,类似于APP的推送通知: 1.添加模版消息 在页面的左上 有一个添加功能插件的 按钮,如题 添加完成后,我们就可以在 ...

  9. java微信开发API解析(二)-获取消息和回复消息

    java微信开发API解析(二)-获取消息和回复消息 说明 * 本演示样例依据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/20 ...

随机推荐

  1. Python实现堆

    堆 (heap) 是一种经过排序的完全二叉树,其中任一非叶子节点的值均不大于(或不小于)其左孩子和右孩子节点的值. 注:定义来自百度百科. 堆,又被为优先队列(priority queue).尽管名为 ...

  2. LInux因为缺失网关出现Name or service not known的解决方法

    笔者使用的VMware和CentOS 7.0.在安装完镜像包后,便开始配置静态ip.命令如下 vi /etc/sysconfig/network-scripts/ifcfg-ens33 将BOOTPR ...

  3. Java开发笔记(一百四十四)实现FXML对应的控制器

    前面介绍了如何通过fxml文件编排界面布局,可是光有静态界面根本没法处理业务,必须另外书写业务逻辑的代码,方能响应各按钮的单击事件,并将业务结果即使呈现到界面上.显然,fxml内部写不了Java代码, ...

  4. GO指南练习:切片

    最近开始GO语言的学习,在GO指南中练习到切片这个题目 练习:切片 实现 Pic.它应当返回一个长度为 dy 的切片,其中每个元素是一个长度为 dx,元素类型为 uint8 的切片.当你运行此程序时, ...

  5. LOJ2001 SDOI2017 树点涂色 LCT、线段树

    传送门 注意到每一次\(1\ x\)操作相当于一次LCT中的access操作.由LCT复杂度证明可以知道access的总次数不会超过\(O(nlogn)\),我们只需要模拟这个access的过程并在其 ...

  6. NOI2019 退役记

    最终还是在意料之中退役了. 总的来说,这一年确实曲折坎坷,曾踏足山巅,也曾陷入低谷,二者都让我受益良多. 没有太多不甘,水平已经正常发挥,哪敢还有一丝奢求. 省选时其实已经早就做好退役的准备了,但命运 ...

  7. Android 系统架构 和 各个版本代号介绍

    一.Android 系统架构: 1. linux内核层Android 基于Linux内核,为Android设备的各种硬件提供底层驱动 比如: 显示驱动.音频.照相机.蓝牙.Wi-Fi驱动,电源管理等 ...

  8. 高并发场景下System.currentTimeMillis()的性能问题的优化

    高并发场景下System.currentTimeMillis()的性能问题的优化 package cn.ucaner.alpaca.common.util.key; import java.sql.T ...

  9. Visual Studio 2019 使用.Net Core 3.0 二

    一.遇到难题 在微软官方逛了一圈,看到了这个. 马上点击,进去看看什么情况. 1.安装previewVisual studio 2019 2.设置SDK previews in Visual Stud ...

  10. 三星手机使用应用沙盒一键修改路由mac数据

    之前文章介绍了怎么在安卓手机上安装激活xposed框架,xposed框架的极强的功能大家都知道,能够不修改apk的前提下,修改系统底层的参数,打比方在某些应用情景,大家需要修改手机的某个系统参数,这情 ...