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

//----------------------------------------------------------------------------------------//
//-----------------------------------程序功能-----------------------------------------//
/*
总功能:  制作一个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(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){
//  初始化连接
   reconnect();//确保连上服务器,否则一直等待。
//  订阅话题等待
   client.loop();//MUC接收数据的主循环函数。   

//  从串口读数据
    String serial_string=serial_read();
// 将串口数据发送给服务器

    serial_mqtt_sendmsg(serial_string);

    serial_string="";

   }
   else
   {
     Serial.println("wifi fail!");
     setup_wifi() ;   // wifi
    }

    }

  

原文地址:https://www.cnblogs.com/kekeoutlook/p/10859051.html

时间: 2024-08-30 13:22:06

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

微信硬件平台 (1) 总说明

微信硬件平台 本文目的,使用微信公众号控制ESP8266的LED开和关.进一步使用微信当遥控器(避免写APP或者IOS或者小程序),控制一切设备.给两个关键的总教程参考. 官网教程  微信硬件平台 微信控制arduino点亮LED教程 目前整体测试效果 打开微信,关注自己的公众号 功能结构图 1 公众号注册 1.申请认证公众号&开通设备功能 1.1公众号申请: https://mp.weixin.qq.com 个人订阅号    功能有限,不能有设备管理模块功能,本教程系列使用的是订阅号,做一个测

微信硬件平台的基础接入和硬件云标准接入分析

本文分析基于微信硬件平台的物联网架构,将从物联网的核心要素.物联网的关键场景.微信硬件平台的通信协议分析三个维度去分析.更多的微信硬件平台开发的深度技术原创分享请订阅微信公众号:嵌入式企鹅圈. 微信硬件平台包括基础接入方案与微信硬件云标准接入方案.前者是在应用端和设备端都完全由厂商开发,微信硬件平台只负责用户管理.设备管理和透明的消息推送:后者是在前者的基础上,给设备端提供了直连SDK(可以适配linux/Android等平台).提供设备API给第三方硬件平台接入,甚至在应用端根据各种家电场景定

一张图读懂基于微信硬件平台的物联网架构

本文从物联网的核心要素.物联网的关键场景.微信硬件平台的通信协议分析三个维度去分析基于微信硬件平台的物联网架构.相关的背景知识请阅读微信公众号:嵌入式企鹅圈发布的有关物联网和微信硬件专题文章. 一. 基于微信硬件平台的物联网架构图示 上图涵盖以下信息: 1.   基于微信硬件平台的物联网的架构组成,有微信公众平台/硬件平台.第三方厂商云后端.手机微信/公众号.微信硬件设备终端(Wifi和蓝牙BLE). 2.   绿色代表腾讯向开发者和公众提供的基础平台和服务,并通过红色(airsync/airk

微信硬件平台(二) 企业服务号号设备注册和绑定

该教程目的:在教程1里,完成了微信服务器向自己的服务器转发公众号收到的数据.但是缺少用户认证,设备注册,设备绑定等功能.这里使用调试助手模拟一个实际的设备(空调,灯),直接向微信硬件云注册和授权,绑定个人的微信账号.这里暂时没有用的自己的服务器. 微信教程 网友调试过程    微信硬件平台下设备与微信通信 需要: 1 申请一个服务号(必须有企业组织代码,法人等信息). 没有公司的开通一个测试账号.这里使用的是一个公司注册后的服务号. 2 在公众号-设备功能-添加几个设备 (图标随便上传的) 因为

微信硬件平台(六) 设备直连微信云

微信硬件开发文档 智能硬件厂家的痛点 微信硬件平台是基于微信公众号体系的智能硬件平台,在公众号的技术架构里,设备厂商必须要有自己的服务器.厂商服务器主要完成两部分工作: 1.管理设备的连接登录.鉴权.状态上报.命令发送.固件更新等基础网络功能: 2.通过H5页面或者微信公众平台消息接口,接收设备用户的操作命令,处理设备业务逻辑,展示设备状态给微信用户. 这两部分工作相对独立. 对于硬件设备厂家来说,服务器第一项工作受到各种因素限制,实现起来相对困难,增加了研发投入时间.精力.资金成本. 同时各个

微信硬件平台

调用openApi 微信硬件平台是微信推出连接物与人,物与物的IOT解决方案.也就是说可以通过微信控制各种智能设备.比如一些蓝牙设备.空调.电视等等. 我本身不懂硬件(虽然是电子信息专业),硬件是北航的两个研究生在弄,小团队里我负责开发H5自定义面板,刚开始看官方文档各种迷糊,对于jssdk.jsapi.Airkiss.openApi.直连SDK都不知道该用哪个做,官方论坛问问题基本上没结果,加了几个微信硬件群问问题,发现好些开发者和我一样,同一个问题,发到几个群里问,画面好心酸.给wxthin

微信公众平台开发(十二) 发送客服消息

原文:微信公众平台开发(十二) 发送客服消息 一.简介 当用户主动发消息给公众号的时候(包括发送信息.点击自定义菜单.订阅事件.扫描二维码事件.支付成功事件.用户维权),微信将会把消息数据推送给开发者,开发者在一段时间内(目前修改为48小时)可以调用客服消息接口,通过POST一个JSON数据包来发送消息给普通用户,在48小时内不限制发送次数.此接口主要用于客服等有人工消息处理环节的功能,方便开发者为用户提供更加优质的服务. 二.思路分析 官方文档中只提供了一个发送客服消息的接口,开发者只要POS

微信硬件平台框架说明及接入流程

微信硬件平台框架说明及接入流程1 / 15 硬件平台框架说明及接入流程 V0.5 Tencent Confidential 硬件平台框架说明及接入流程 2 / 15 文档变更日志 部门 微信事业群\开放平台创新部\创新二组 版本 描述 撰写人员 更新日期 V0.1 初稿 jeffqi.genewu 2014/07/8 V0.2 加入Q&A jeffqi.genewu 2014/07/8 V0.3 针对常见问题,增加说明.流程图优化. jeffqi.genewu 2014/07/9 V0.4 添加

微信Wifi物联架构---机智云/云智易如何接入微信硬件平台

本文由嵌入式企鹅圈原创团队成员-华南师范大学物联网创新中心黄鑫执笔. 嵌入式企鹅圈已经就微信蓝牙物联架构做过很多次的分析了,这里就不再啰嗦了.这里主要分析物联网远场控制场景,就是wifi物联,当然也包括GPRS.3G.4G等等. 一.微信wifi物联的使命 基于Wifi物联网平台很早就有了,远在微信硬件平台出现之前,所以在wifi物联方面,微信除了抱着一个极大的流量入口,其他方面并不具有什么优势.马化腾说过微信硬件是要连接一切嘛,那微信硬件自然要去适配已经存在的平台和设备.而已有的wifi物联平