zoukankan      html  css  js  c++  java
  • ESP8266串口和MQTT服务器消息互传(版本一) 单纯透传+保存WIFI账号信息

     目标

    制作一个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("
    --------------WIFi CONNECT!-------------
    ");
      Serial.printf("SSID:%s
    ", WiFi.SSID().c_str());
      Serial.printf("PSW:%s
    ", 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]='';
       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("
    Wait 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
    ", WiFi.SSID().c_str());
          Serial.printf("PSW:%s
    ", 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! 
     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("
     try to  begin smartConfig! 
    ");
          smartConfig();// 手机灵活设置WIFI
          break;
        }
       
          // 不按按键,自动连接上传WIFI
        if (millis() - preTick2 > 5 * 1000) {   
            Serial.println("
     try to connect  wifi! 
    ");
          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() ;
        }
        
        }
    
           
    
            
    

      

  • 相关阅读:
    【数据库功能测试】之shell脚本执行sql命令
    【数据库使用】 mysql服务启动脚本
    【数据库功能测试】之存储过程
    各类排序算法实现
    Poj1830开关问题,高斯消元
    Poj3370Halloween treats鸽巢原理
    Poj2356Find a multiple鸽巢原理
    Poj3145Harmony Forever线段树+鸽巢原理
    hiho16动态lca
    hiho15周离线lca
  • 原文地址:https://www.cnblogs.com/kekeoutlook/p/10424296.html
Copyright © 2011-2022 走看看