/** * 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 50Adafruit_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);}}