ESP8266 自动配网+MQTT链接

使用WiFiManager 进行可视化网络配置。

/**
 * ESP8266 自动配网 MQTT
 */
// https://github.com/tzapu/WiFiManager/
#include <WiFiManager.h>
/**
 * MQTT
 */
//PubSubClient by Nick O`Leary
#include <PubSubClient.h>
#include <ArduinoJson.h>
/**
 * ws2812 led
 */
#include <Adafruit_NeoPixel.h>

// mqtt 参数
char* mqtt_server ="192.168.0.200";
char* mqtt_port = "1883";
WiFiClient espClient;
PubSubClient mqtt_client(espClient);

#define RING_LED_PIN    2
#define NUMPIXELS 24
#define BRIGHTNESS 50
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, RING_LED_PIN, NEO_GRB + NEO_KHZ800);

StaticJsonDocument<256> jsonState;                      //设备状态
/*============================================== web 配网 下===========================================================*/
/**
 * 初始化wifimanager
 */
void initWifi()
{
  WiFiManager wifiManager;                               // 创建 wifimanager 对象
//  wifiManager.resetSettings();                           // 重置保存的修改
  wifiManager.setConnectTimeout(10);                     // 配置连接超时
  wifiManager.setDebugOutput(true);                      // 打印调试内容
  wifiManager.setMinimumSignalQuality(30);               // 设置最小信号强度
  //设置AP
  IPAddress _ip = IPAddress(192, 168, 4, 1);             // 设置固定AP信息
  IPAddress _gw = IPAddress(192, 168, 4, 1);             // 设置固定AP信息
  IPAddress _sn = IPAddress(255, 255, 255, 0);           // 设置固定AP信息
  wifiManager.setAPStaticIPConfig(_ip, _gw, _sn);        // 设置固定AP信息
  // 回调
  wifiManager.setAPCallback(configModeCallback);         // 设置进入AP模式的回调
  wifiManager.setSaveConfigCallback(saveConfigCallback); // 设置点击保存的回调
  wifiManager.setBreakAfterConfig(true);                 // 设置 如果配置错误的ssid或者密码 退出配置模式
  // 自定义参数
  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
  WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 6);
  wifiManager.addParameter(&custom_mqtt_server);
  wifiManager.addParameter(&custom_mqtt_port);
  // 尝试连接网络,失败去到配置页面
  if (!wifiManager.autoConnect("ESP8266_AP", ""))    
  {
    Serial.println("failed to connect and hit timeout");
    ESP.reset();                                          // 重置并重试
    delay(1000);
  }
  // WiFi连接成功后将通过串口监视器输出连接成功信息
  Serial.println("== WIFI CONNECT SUCCESS ! ==");
  Serial.print("IP Address : ");
  Serial.println(WiFi.localIP());
  // 读取配置页面配置好的信息
  strcpy(mqtt_server, custom_mqtt_server.getValue());
  strcpy(mqtt_port, custom_mqtt_port.getValue());
}
// 配置进入AP模式通知回调
void configModeCallback(WiFiManager *myWiFiManager)
{
  Serial.println("Entered config mode"); //进入配置模式
  Serial.print("Wifi Name : ");
  Serial.println("Wifi Name : " + myWiFiManager->getConfigPortalSSID());
  Serial.print("Wifi IP : ");
  Serial.println(WiFi.softAPIP());
  // 附加参数
  Serial.print("MQTT Server : ");
  Serial.println(mqtt_server);
  Serial.print("MQTT Port : ");
  Serial.println(mqtt_port);
}
// 设置点击保存的回调
void saveConfigCallback()
{
  Serial.println("Should save config");
}
/*============================================== MQTT 下===========================================================*/
/* 初始化设备属性状态*/
void initState()
{
  jsonState["name"] = "ESP8266";
  jsonState["led"] = "OFF";
  jsonState["mode"] = "0";
  jsonState["update_time"] = random(100);
}
void initMQTT(){
  mqtt_client.setServer(mqtt_server, atoi(mqtt_port));
  mqtt_client.setCallback(mqtt_callback);
}
void mqtt_reconnect() {
    String clientId = "ESP-01A-" + String(random(0xffff), HEX);
    if (mqtt_client.connect(clientId.c_str())) {         //连接成功
      Serial.println("=== MQTT CONNECT SUCCESS ! ===");
      String msg;
      serializeJson(jsonState,msg);
      Serial.println(msg);
      mqtt_client.publish("hass/sensor/esp8266_1/led/state",msg.c_str());     // 连接成功发送初始状态信息
      mqtt_client.subscribe("hass/sensor/esp8266_1/led/set");
    } else {
      delay(5000);                                  // Wait 5 seconds before retrying
    }
}
/**
 * MQTT 接收数据
 */
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("接收消息:");
  DynamicJsonDocument doc(200);
  deserializeJson(doc, payload);
  serializeJson(doc,Serial);
  Serial.println("");
  // 业务处理
  String key = doc["key"];
  String value = doc["value"];
  // 更新状态
  jsonState[key] = value;
  jsonState["update_time"] = random(100);
  String msg;
  serializeJson(jsonState,msg);
  Serial.print("更新状态:");
  Serial.println(msg);
  mqtt_client.publish("hass/sensor/esp8266_1/led/state",msg.c_str());     // 状态信息
}
/*============================================== 环形灯===========================================================*/
void initRingLED(){
  strip.setBrightness(BRIGHTNESS);
  // 初始化Adafruit_NeoPixel库
  strip.begin();
  // 初始化时关闭所有LED      
  strip.show();
}
/**
 * 模式: 颜色擦除
 */
void colorWipe(uint32_t c, uint8_t wait) {
  strip.clear();
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

/**
 * 彩虹呼吸
 */
void rainbow(uint8_t wait) {
  uint16_t i, j;
  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i + j) & 255 ));
    }
    strip.show();
    delay(wait);
  }
}

/**
 * 彩虹呼吸-旋转
 */
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}
/**
 * 走马灯
 */
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}
/**
 * 走马灯-彩虹
 */
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}
uint32_t Wheel(byte WheelPos) {
  if (WheelPos < 85) {
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

//----------------------------------------------- 程序入口 ---------------------------------------------------
void setup()
{
  Serial.begin(9600);                             // 初始化串口设置
  pinMode(LED_BUILTIN, OUTPUT);                   // 设置 LED_BUILTIN(GPIO-16) 为输出功能
  digitalWrite(LED_BUILTIN, HIGH);                // 默认关闭
  // 配置状态信息
  initState();
  // 自动配网
  initWifi();
  // 配置MQTT
  initMQTT();
  // 配置环形灯
  initRingLED();
}
void loop()
{
  // mqtt
  if (!mqtt_client.connected()) {
    mqtt_reconnect();
  }
   mqtt_client.loop();
   // LED
   if (jsonState["led"] == "OFF") {          // 通过接收的信息 '1' 来控制开或关
     digitalWrite(LED_BUILTIN, HIGH); 
   } else {
     digitalWrite(LED_BUILTIN, LOW); 
   }
  // ring led
   if(jsonState["mode"]== "0"){ strip.clear(); }
   else if(jsonState["mode"]== "1"){ colorWipe(strip.Color(150, 150, 150), 20); }// BlueWite
   else if(jsonState["mode"]== "2"){ rainbow(5);}
   else if(jsonState["mode"]== "3"){ rainbowCycle(1);}
   else if(jsonState["mode"]== "4"){ theaterChase(strip.Color(127, 127, 127), 50);}
   else if(jsonState["mode"]== "5"){ theaterChaseRainbow(5);}

}
上一篇
下一篇