NodeMCU(ESP8266) WIFI配网及保存WiFi密码信息

NodeMCU(ESP8266) WIFI配网及保存WiFi密码信息

背景

在我们使用智能设备时经常会看到很多设备是接入WiFi的,刚买来的时候是需要连接WiFi的,配WiFi的方式有很多种,我遇到的比较多的是smartConfig声纹配网,如果是有触摸屏的话很多都是屏幕上直接输入WiFi密码即可。配置完网络后我们后续的使用时都是无需再次配WiFi信息。

WiFi配网原理

关于配网的原理我也是看别人的文章的,所以就不做搬运,如需了解请阅读下面这篇文章。

IoT】物联网之 WIFI 一键配网 smartConfig 浅析(ESP32)

demo视频

原本想这么一个简单的东西就没必要拍视频来展示,但是代码和文字都是很枯燥的,我这种学渣看到完全提不起兴趣,驱动个人去做的更多的可能还是看到别人的创意视频吧,所以我便想着用视频的方式来展示,希望也能驱动和我一样的小白玩家不断前行。

NodeMcu(ESP8266)一键配网及记住密码功能demo

功能讲解

  1. 先从EEPROM中获取WiFi的SSID和密码
  2. 如果已经有了SSID和密码,则直接使用SSID密码连接WIFI
  3. 如果是没有SSID和密码,则进入到配网模式
  4. 配网完成后将WiFi的SSID和密码存储到EEPROM存储器中
  5. 最后进入主程序,判断清除EEPROM存储器的功能键是否按下
  6. 如果按下则清空WiFi的SSID和密码信息,重置后回到步骤1

大致流程如下

NodeMCU(ESP8266) WIFI配网及保存WiFi密码信息_第1张图片

代码

这里代码推荐使用多文件的方式来写,第一复用性会比较高(拿到其他项目也能用),第二不会被很长的代码看迷糊。

  • smartconfig.h

这个主要就是将WiFi的SSID和密码存储起来


#include 

#ifndef _SMART_CONFIG_
// 声明
#define _SMART_CONFIG_

#define EEPROM_START 1024

struct WifiPwd {
  char ssid[32];
  char pwd[64];
};

/*
  保存参数到eeprom
*/
void saveConfig(WifiPwd *wifipwd) {
  EEPROM.begin(EEPROM_START);
  uint8_t *p = (uint8_t*)(wifipwd);
  for (int i = 0; i < sizeof(*wifipwd); i++) {
    EEPROM.write(i, *(p + i));
  }
  EEPROM.commit();
  // 释放内存
  delete wifipwd;
}

/*
   获取wifi账号密码信息
*/
WifiPwd* loadConfigs() {
  // 为变量请求内存
  WifiPwd *pvalue  = new WifiPwd;   
  EEPROM.begin(EEPROM_START);
  uint8_t *p = (uint8_t*)(pvalue);
  for (int i = 0; i < sizeof(*pvalue); i++) {
    *(p + i) = EEPROM.read(i);
  }
  EEPROM.commit();
  return pvalue;
}

/**
   清空wifi账号和密码
*/
void clearConfig() {
  EEPROM.begin(EEPROM_START);
  // 这里为啥是96 ,因为在结构体声明的长度之和就是96
  for (int i = 0; i < 96; i++) {
    EEPROM.write(i, 0);
  }
  EEPROM.commit();
}

#endif
  • smart-config-demo.ino

主程序,说明注释里面都有


#include 
#include 
#include "smartconfig.h"

// 功能按键
#define POWERKEY 5


/**
   一键配网
*/
void smartConfig() {
  // 先从flash中加载账号密码
  WifiPwd* wifipwd = loadConfigs();
  if (strlen(wifipwd->pwd) > 0 ) {
    Serial.println("\n\ruse password connect wifi");
    // 如果说有账号密码信息,那就直接用账号密码连接wifi
    WiFi.mode(WIFI_STA);
    WiFi.begin(wifipwd->ssid, wifipwd->pwd);
    while (WiFi.status() != WL_CONNECTED) {
      // 直到wifi连接成功为止
      blinkled();
    }
    // 删除内存
    delete wifipwd;
    // 设置自动连接
    WiFi.setAutoConnect(true);
  } else {
    Serial.println("\n\rwait smart config wifi");
    WiFi.beginSmartConfig();
    while (1) {
      blinkled();
      if (WiFi.smartConfigDone()) {
        WifiPwd *wifipwd  = new WifiPwd;
        strcpy(wifipwd->ssid, WiFi.SSID().c_str());
        strcpy(wifipwd->pwd, WiFi.psk().c_str());
        // 记住wifi账号密码
        saveConfig(wifipwd);
        // 设置自动连接
        WiFi.setAutoConnect(true);
        break;
      }
    }
  }
  Serial.println("\n\rWiFi Connected IP address: ");
  Serial.println(WiFi.localIP());
}

/**
   指示灯闪烁
*/
void blinkled() {
  digitalWrite(LED_BUILTIN, LOW);
  delay(200);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(200);
}

/**
   按键
*/
int keywords() {
  // 获取按键的值
  int keyValue = digitalRead(POWERKEY);
  // 目前是直接返回的,todo 后续需要对按键除抖和长按处理等
  return keyValue;
}


void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(POWERKEY, OUTPUT);
  smartConfig();
  digitalWrite(LED_BUILTIN, LOW);
  Serial.println("wifi connected");
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    // 如果wifi断开的话就重连
    WiFi.reconnect();
  }
  // 判断是否按下重置按钮
  if (keywords() == 1) {
    // 如果按键按下则清空eeprom和重置单片机
    clearConfig();
    Serial.println("wifi账号密码已经清除");
  }
}

你可能感兴趣的:(arduino,物联网)