各位大神好,本人小白一个,手里有块D1 WIFI Arduino UNO开发板,想通过接入阿里云物联平台实现阿里云智能APP手机远程控制WS2812 RGB LED,以及接入天猫精灵。经过几天的摸索和东拼西凑,现在已经实现开发板接入阿里云,并可以通过平台在线调试发送指令远程控制WS2812 RGB LED的开关和调色。但想加入一键配网功能一直实现不了,尝试过使用WiFi.beginSmartConfig()函数,但代码上传到开发板后用微信却可以配网,而用云智能APP添加不了设备。也看了阿里云官方关于一键配网的文档https://help.aliyun.com/document_detail/111047.html#section-3ig-m8q-pnz,无奈理解不了。有没有相关经验的大神给指导一下,感激不尽- #include <ESP8266WiFi.h>
- #include <EEPROM.h>
- static WiFiClient espClient;
- #include <Arduino.h>
- #include <ArduinoJson.h>
- #include <aliyun_mqtt.h>
- #include "PubSubClient.h"
- #include "Ticker.h"
- /*****************网络设置项 *****************/
- const char *ssid2; //提供上网的无线路由ssid
- String ssid3;
- int ss;
- const char *password2; //提供上网的无线路由密码
- String password3;
- int pp;
- int count = 0;
- bool WIFI_Status = true;
- #include <Adafruit_NeoPixel.h>//rgb
- #ifdef __AVR__
- #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
- #endif
- #define PIXEL_PIN D10 // Digital IO pin connected to the NeoPixels.
- #define PIXEL_COUNT 16 // Number of NeoPixels
- Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
- #define WIFI_SSID "HONOR-510G1C"
- #define WIFI_PASSWD "qwaszx11"
- #define PRODUCT_KEY "a1OoF7GyNFB"
- #define DEVICE_NAME "9mui5RRSZbeuP4y8UinF"
- #define DEVICE_SECRET "1e4fcb1260667ed1321af8d7c7256e2d"
- #define REGION_ID "cn-shanghai"
- //设备下发命令的set主题
- #define ALINK_TOPIC_PROP_SET "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"
- //设备上传数据的post主题
- #define ALINK_TOPIC_PROP_POST "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
- //设备post上传数据要用到一个json字符串, 这个是拼接postJson用到的一个字符串
- #define ALINK_METHOD_PROP_POST "thing.event.property.post"
- //这是post上传数据使用的模板
- #define ALINK_BODY_FORMAT "{"id":"%u","version":"1.0","method":"%s","params":%s}"
- int postMsgId = 0; //记录已经post了多少条
- Ticker tim1; //这个定时器是为了每5秒上传一次数据
- PubSubClient mqttClient(espClient); //通过网络客户端连接创建mqtt连接客户端
- void setup()
- {
- strip.begin(); // Initialize NeoPixel strip object (REQUIRED)
- strip.show(); // Initialize all pixels to 'off'
- pinMode(LED_BUILTIN, OUTPUT);
- digitalWrite(LED_BUILTIN, 1);
- Serial.begin(115200);
- EEPROM.begin(1024);
- if (EEPROM.read(0) == 200) {
- Serial.println("OK"); //测试数据
- WiFi.mode(WIFI_STA);
- ss = EEPROM.read(1); //ssid长度
- pp = EEPROM.read(2); //密码长度
- ssid3 = ssid1(ss, 10);
- ssid2 = ssid3.c_str();
- password3 = password1(pp, 30);
- password2 = password3.c_str();
- WiFi.begin(ssid2, password2);
- delay(1000);
- Serial.println("\r\n正在连接");
- while (WiFi.status() != WL_CONNECTED)
- {
- if (WIFI_Status)
- {
- Serial.print(".");
- digitalWrite(LED_BUILTIN, HIGH);
- delay(500);
- digitalWrite(LED_BUILTIN, LOW);
- delay(500);
- count++;
- if (count >= 5) //5s
- {
- WIFI_Status = false;
- Serial.println("WiFi连接失败,可能errom中数据出错,请用手机重新进行配网");
- }
- }
- else
- {
- smartConfig(); //微信智能配网
- }
- }
- /*****************************************/
- }
- /*如果errom中没有数据,则开始执行配网*/
- else {
- Serial.println("Start module");
- smartConfig();
- }
- /*连接路由器*/
- setup_wifi();
- /*连接mqtt的onenet端口并设置回调函数*/
- if (connectAliyunMQTT(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET))
- {
- Serial.println("MQTT服务器连接成功!");
- };
- mqttClient.setCallback(callback); //绑定收到set主题时的回调(命令下发回调)
- tim1.attach(5, mqttPublish); //启动每5秒发布一次消息
- }
- void loop()
- {
- //检测有没有断线
- if (WiFi.status() != WL_CONNECTED) //先看WIFI是否还在连接
- {
- WiFi.begin(ssid2, password2);
- Serial.println("go to wifi");
- Serial.println(ssid2);
- Serial.println(password2);
- delay(1000);
- return;
- }
- else //如果WIFI连接了,
- {
- if (!mqttClient.connected()) //再看mqtt连接了没
- {
- Serial.println("mqtt已断开!尝试重新连接...");
- Serial.println(mqttClient.state());
- clientReconnect();
- }
- }
- mqttClient.loop();//mqtt客户端监听
- }
- void smartConfig() {
- WiFi.mode(WIFI_STA);
- Serial.println("\r\nWait for Smartconfig");
- //调用smartconfig功能
- WiFi.beginSmartConfig();
- while (1) {
- Serial.print(".");
- //若配置完成打印获取到的ssid
- if (WiFi.smartConfigDone()) {
- String s = "";
- String p = "";
- int cd1;
- int cd2;
- Serial.println("SmartConfig Success");
- Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
- Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
- s = WiFi.SSID();
- p = WiFi.psk();
- cd1 = s.length();
- cd2 = p.length();
- EEPROM.write(1, cd1);
- EEPROM.write(2, cd2);
- for (int i = 0; i < cd1; i++) {
- EEPROM.write(10 + i, s[i]);
- }
- for (int i = 0; i < cd2; i++) {
- EEPROM.write(30 + i, p[i]);
- }
- EEPROM.write(0, 200);
- EEPROM.commit();
- Serial.println(s);
- Serial.println(p);
- /*重新修改路由器账号和密码*/
- //ssid2=WiFi.SSID().c_str(); //重新修改路由器账号和密码
- //password2=WiFi.psk().c_str();
- Serial.println("ok");
- break;
- }
- }
- }
- /*读取errom数据*/
- String ssid1(int a, int b) {
- String data = "";
- for (int i = 0; i < a; i++) {
- data += char(EEPROM.read(b + i));
- }
- return data;
- }
- String password1(int a, int b) {
- String data = "";
- for (int i = 0; i < a; i++) {
- data += char(EEPROM.read(b + i));
- }
- return data;
- }
- /*连接WiFi函数*/
- void setup_wifi() {
- delay(10);
- // We start by connecting to a WiFi network
- Serial.println();
- Serial.print("Connecting to ");
- Serial.println(ssid2);
- WiFi.begin(ssid2, password2);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print("-)");
- }
- randomSeed(micros());
- Serial.println("");
- Serial.println("WiFi connected");
- Serial.println("IP address: ");
- Serial.println(WiFi.localIP());
- }
- void clientReconnect() //重连函数, 如果客户端断线,可以通过此函数重连
- {
- while (!mqttClient.connected()) //再重连客户端
- {
- Serial.println("重新连接 MQTT...");
- if (connectAliyunMQTT(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET))
- {
- Serial.println("connected");
- }
- else
- {
- Serial.println("failed");
- Serial.println(mqttClient.state());
- Serial.println("try again in 5 sec");
- delay(5000);
- }
- }
- }
- void callback(char *topic, byte *payload, unsigned int length)
- { //收到set主题的命令下发时的回调函数,(接收命令)
- if (strstr(topic, ALINK_TOPIC_PROP_SET))
- { //如果收到的主题里包含字符串ALINK_TOPIC_PROP_SET(也就是收到/sys/a17lGhkKwXs/esp32LightHome/thing/service/property/set主题)
- Serial.println("收到下发的命令主题:");
- Serial.println(topic);
- Serial.println("下发的内容是:");
- payload[length] = '\0'; //为payload添加一个结束附,防止Serial.println()读过了
- Serial.println((char *)payload);
- //接下来是收到的json字符串的解析
- DynamicJsonDocument doc(200);
- DeserializationError error = deserializeJson(doc, payload);
- if (error)
- {
- Serial.println("解析json失败parse json failed");
- return;
- }
- JsonObject setAlinkMsgObj = doc.as<JsonObject>();
- serializeJsonPretty(setAlinkMsgObj, Serial);
- Serial.println();
- int powerstate = setAlinkMsgObj["params"]["powerstate"];
- digitalWrite(LED_BUILTIN, !powerstate);
- if (powerstate == 1) { //如果“powerstate”开关指令为1
- colorWipe(strip.Color( 255, 255, 255), 20);
- Serial.println("\n 亮灯");
- } else if (powerstate == 0) {
- colorWipe(strip.Color( 0, 0, 0), 20);
- Serial.println("\n 灭灯");
- }
复制代码
。
|