当前位置: 首页 > news >正文

天津开发区建网站公司/简述获得友情链接的途径

天津开发区建网站公司,简述获得友情链接的途径,wordpress发文章的id怎么不连续,汕头企业自助建站忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2022-03-19 ❤️❤️ 本篇更新记录 2022-03-19 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝&#x1f64…

忘记过去,超越自己

  • ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️
  • ❤️ 本篇创建记录 2022-03-19 ❤️
  • ❤️ 本篇更新记录 2022-03-19 ❤️
  • 🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝
  • 🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!
  • 🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志 🔥

快速导读

    • 1、背景说明
    • 2、涉及内容
      • 2.1 AliyunIoTSDK.h 增加存储自定义主题
      • 2.2 AliyunIoTSDK.h 增加两个自定义订阅、取消订阅主题方法
      • 2.3 AliyunIoTSDK.cpp 实现订阅、取消订阅方法
      • 2.4 AliyunIoTSDK.cpp 检测自定义主题修改点
    • 3、具体实例使用(只是说明用法)
    • 4、具体库(直接copy覆盖即可)
      • 4.1 AliyunIoTSDK.h
      • 4.2 AliyunIoTSDK.cpp

手把手代码注释,完整案例讲解开发过程以及细节,一键式运行代码。
ESP保姆级付费专栏群 707958244,不喜勿加,凭借付费专栏订单号加入

  • ESP 保姆级教程 系列导读(此专栏非常适合刚刚入门ESP开发的初学者)

1、背景说明

  • 之前使用AliyunIoTSDK的时候发现不支持订阅自定义主题,所以干脆就升级一下,方便使用

2、涉及内容

AliyunIoTSDK只有两个文件:
在这里插入图片描述

2.1 AliyunIoTSDK.h 增加存储自定义主题

// 最多绑定20个回调
static poniter_desc poniter_array[20];
// 最多绑定10个主题
static poniter_desc poniter_topic[10];
static p_poniter_desc p_poniter_array;

2.2 AliyunIoTSDK.h 增加两个自定义订阅、取消订阅主题方法

  /*** 绑定事件回调,云服务下发的特定事件会进入回调* @param eventId 事件名*/// static void bindEvent(const char * eventId, MQTT_CALLBACK_SIGNATURE);/*** 绑定属性回调,云服务下发的数据包含此 key 会进入回调,用于监听特定数据的下发* @param key 物模型的key*/static int bindData(char *key, poniter_fun fp);/*** 卸载某个 key 的所有回调(慎用)* @param key 物模型的key*/static int unbindData(char *key);static int bindTopic(char *topic, poniter_fun fp);/*** 卸载某个 key 的所有回调(慎用)* @param key 物模型的key*/static int unbindTopic(char *topic);

2.3 AliyunIoTSDK.cpp 实现订阅、取消订阅方法

int AliyunIoTSDK::bindTopic(char *topic, poniter_fun fp)
{int i;for (i = 0; i < 10; i++){if (!poniter_topic[i].fp){poniter_topic[i].key = topic;poniter_topic[i].fp = fp;return 0;}}return -1;
}int AliyunIoTSDK::unbindTopic(char *topic)
{int i;for (i = 0; i < 10; i++){if (!strcmp(poniter_topic[i].key, topic)){poniter_topic[i].key = NULL;poniter_topic[i].fp = NULL;return 0;}}return -1;
}

2.4 AliyunIoTSDK.cpp 检测自定义主题修改点

void AliyunIoTSDK::mqttCheckConnect()
{if (client != NULL && !mqttConnecting){if (!client->connected()){client->disconnect();Serial.println("Connecting to MQTT Server ...");mqttConnecting = true;if (client->connect(clientId, mqttUsername, mqttPwd)){// 自定义主题订阅for (int i = 0; i < 10; i++){if (poniter_topic[i].fp){client->subscribe(poniter_topic[i].key);}}Serial.println("MQTT Connected!");}else{Serial.print("MQTT Connect err:");Serial.println(client->state());retry_count++;if(retry_count > RETRY_CRASH_COUNT){resetFunc();}}mqttConnecting = false;}else{Serial.println("state is connected");retry_count = 0;}}
}static void topicPass(char *topic,JsonVariant parm)
{for (int i = 0; i < 10; i++){if (poniter_topic[i].key){if (strstr(topic, poniter_topic[i].key)){poniter_topic[i].fp(parm);}}}
}

3、具体实例使用(只是说明用法)


/*** 功能: smartArduino** 详细描述:*   1、esp8266连接上wifi热点*   2、通过mqtt client方式连接上阿里云物联网平台*   3、监听阿里云控制信息,控制ws2812开关以及颜色*/
#include <ESP8266WiFi.h>  // 引入Arduino ESP8266核心库
#include "AliyunIoTSDK.h" // 引入阿里云 IoT SDKconst char* WIFI_SSID     = "TP-LINK_5344"; // WiFi账号密码,更改成自己的
const char* WIFI_PASSWORD = "xxxxx"; // WiFi密码,更改成自己的//-------- 设置产品和设备的信息,从阿里云物联网设备信息里查看 -------//
#define PRODUCT_KEY "gw5eDB82FOO"
#define DEVICE_NAME "device_8266"
#define DEVICE_SECRET "xxxxx"
#define REGION_ID "cn-shanghai"
#define TOPIC_RGB "/gw5eDB82FOO/device_8266/user/rgb"
#define TOPIC_STATUS "/gw5eDB82FOO/device_8266/user/status"
//-------- 设置产品和设备的信息,从阿里云物联网设备信息里查看 -------///******************* 函数声明 **********************/
void rgbCallback(JsonVariant p);
/******************* 函数声明 **********************/int red = 255; // 红色
int green = 255; // 绿色
int blue = 255; // 蓝色static WiFiClient espClient; // TCP Clientvoid setup() {// 延时2s,让电源稍微稳定一下delay(2000);// 初始化串口Serial.begin(115200);Serial.println("Project Running~");// 初始化网络wifi_station_set_auto_connect(0);//关闭自动连接ESP.wdtEnable(5000); //  启用看门狗doWiFiTick();// 设置两个自定义主题处理函数AliyunIoTSDK::bindTopic(TOPIC_STATUS,statusCallback);AliyunIoTSDK::bindTopic(TOPIC_RGB,rgbCallback);// 初始化 iot,需传入 wifi 的 client,和设备产品信息AliyunIoTSDK::begin(espClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, REGION_ID);
}void loop() {// 定时喂狗ESP.wdtFeed();// wifi连接状态检测以及重连doWiFiTick();// Wifi处于连接状态if (WiFi.status() == WL_CONNECTED) {// 检测MQTT 阿里云AliyunIoTSDK::loop();}delay(1000);
}// 控制开关的回调函数
// 数据协议:{"s":xxxx}
void statusCallback(JsonVariant p)
{Serial.println(F("statusCallback"));int status = p["s"];if (status == 1){// 启动设备switchWS2812(true);} else {// 关闭设备switchWS2812(false);}
}// rgb颜色控制的回调函数
// 数据协议:{"r":xxxx,"g":xxxx,"b":xxxx}
void rgbCallback(JsonVariant p)
{Serial.println(F("rgbCallback"));red = p["r"]; // 红色green = p["g"]; // 绿色blue = p["b"]; // 蓝色handleWS2812RGB(red,green,blue);
}/*** 功能:设置ws2812颜色*/
void handleWS2812RGB(int red,int green,int blue){
}/*** 功能:开关ws2812*/
void switchWS2812(bool open){
}/*** 功能:连接Wifi路由心跳函数*/
void doWiFiTick() {static bool taskStarted = false;static bool startSTAFlag = false;static uint32_t lastWiFiCheckTick = 0;if (!startSTAFlag) {startSTAFlag = true;Serial.print(F("connect to ap:"));Serial.println(WIFI_SSID);// 断开网络WiFi.disconnect();// 设置为Station模式WiFi.mode(WIFI_STA);// 连接到wifi热点WiFi.begin(WIFI_SSID, WIFI_PASSWORD);Serial.printf("Heap size:%d\r\n", ESP.getFreeHeap());int cnt = 0;while (WiFi.status() != WL_CONNECTED) {delay(500);cnt++;Serial.print(".");if(cnt>=40){cnt = 0;//重启系统delayRestart(1);}}}//未连接1s重连if ( WiFi.status() != WL_CONNECTED ) {if (millis() - lastWiFiCheckTick > 1000) {lastWiFiCheckTick = millis();Serial.print(".");}}//连接成功建立else {if (taskStarted == false) {taskStarted = true;Serial.print(F("\r\nGet IP Address: "));Serial.println(WiFi.localIP());}}
}

4、具体库(直接copy覆盖即可)

4.1 AliyunIoTSDK.h

#ifndef ALIYUN_IOT_SDK_H
#define ALIYUN_IOT_SDK_H
#include <Arduino.h>
#include <ArduinoJson.h>
#include "Client.h"typedef void (*poniter_fun)(JsonVariant ele); //定义一个函数指针typedef struct poniter_desc
{char *key;poniter_fun fp;
} poniter_desc, *p_poniter_desc;// 最多绑定20个回调
static poniter_desc poniter_array[20];
// 最多绑定10个主题
static poniter_desc poniter_topic[10];
static p_poniter_desc p_poniter_array;class AliyunIoTSDK
{
private:// mqtt 链接信息,动态生成的static char mqttPwd[256];static char clientId[256];static char mqttUsername[100];static char domain[150];// 定时检查 mqtt 链接static void mqttCheckConnect();static void messageBufferCheck();static void sendBuffer();
public:// 标记一些 topic 模板static char ALINK_TOPIC_PROP_POST[150];static char ALINK_TOPIC_PROP_SET[150];static char ALINK_TOPIC_EVENT[150];// 在主程序 loop 中调用,检查连接和定时发送信息static void loop();/*** 初始化程序* @param ssid wifi名* @param passphrase wifi密码*/static void begin(Client &espClient,const char *_productKey,const char *_deviceName,const char *_deviceSecret,const char *_region);/*** 发送数据* @param param 字符串形式的json 数据,例如 {"${key}":"${value}"}*/static void send(const char *param);/*** 发送 float 格式数据* @param key 数据的 key* @param number 数据的值*/static void send(char *key, float number);/*** 发送 int 格式数据* @param key 数据的 key* @param number 数据的值*/static void send(char *key, int number);/*** 发送 double 格式数据* @param key 数据的 key* @param number 数据的值*/static void send(char *key, double number);/*** 发送 string 格式数据* @param key 数据的 key* @param text 数据的值*/static void send(char *key, char *text);/*** 发送事件到云平台(附带数据)* @param eventId 事件名,在阿里云物模型中定义好的* @param param 字符串形式的json 数据,例如 {"${key}":"${value}"}*/static void sendEvent(const char *eventId, const char *param);/*** 发送事件到云平台(空数据)* @param eventId 事件名,在阿里云物模型中定义好的*/static void sendEvent(const char *eventId);/*** 绑定回调,所有云服务下发的数据都会进回调*/// static void bind(MQTT_CALLBACK_SIGNATURE);/*** 绑定事件回调,云服务下发的特定事件会进入回调* @param eventId 事件名*/// static void bindEvent(const char * eventId, MQTT_CALLBACK_SIGNATURE);/*** 绑定属性回调,云服务下发的数据包含此 key 会进入回调,用于监听特定数据的下发* @param key 物模型的key*/static int bindData(char *key, poniter_fun fp);/*** 卸载某个 key 的所有回调(慎用)* @param key 物模型的key*/static int unbindData(char *key);static int bindTopic(char *topic, poniter_fun fp);/*** 卸载某个 key 的所有回调(慎用)* @param key 物模型的key*/static int unbindTopic(char *topic);
};
#endif

4.2 AliyunIoTSDK.cpp


#include "AliyunIoTSDK.h"
#include "PubSubClient.h"
#include <SHA256.h>#define CHECK_INTERVAL 10000
#define MESSAGE_BUFFER_SIZE 10
#define RETRY_CRASH_COUNT 5static const char *deviceName = NULL;
static const char *productKey = NULL;
static const char *deviceSecret = NULL;
static const char *region = NULL;struct DeviceProperty
{String key;String value;
};DeviceProperty PropertyMessageBuffer[MESSAGE_BUFFER_SIZE];#define MQTT_PORT 1883#define SHA256HMAC_SIZE 32
#define DATA_CALLBACK_SIZE 20#define ALINK_BODY_FORMAT "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}"
#define ALINK_EVENT_BODY_FORMAT "{\"id\": \"123\",\"version\": \"1.0\",\"params\": %s,\"method\": \"thing.event.%s.post\"}"static unsigned long lastMs = 0;
static int retry_count = 0;static PubSubClient *client = NULL;char AliyunIoTSDK::clientId[256] = "";
char AliyunIoTSDK::mqttUsername[100] = "";
char AliyunIoTSDK::mqttPwd[256] = "";
char AliyunIoTSDK::domain[150] = "";char AliyunIoTSDK::ALINK_TOPIC_PROP_POST[150] = "";
char AliyunIoTSDK::ALINK_TOPIC_PROP_SET[150] = "";
char AliyunIoTSDK::ALINK_TOPIC_EVENT[150] = "";static String hmac256(const String &signcontent, const String &ds)
{byte hashCode[SHA256HMAC_SIZE];SHA256 sha256;const char *key = ds.c_str();size_t keySize = ds.length();sha256.resetHMAC(key, keySize);sha256.update((const byte *)signcontent.c_str(), signcontent.length());sha256.finalizeHMAC(key, keySize, hashCode, sizeof(hashCode));String sign = "";for (byte i = 0; i < SHA256HMAC_SIZE; ++i){sign += "0123456789ABCDEF"[hashCode[i] >> 4];sign += "0123456789ABCDEF"[hashCode[i] & 0xf];}return sign;
}static void parmPass(JsonVariant parm)
{//    const char *method = parm["method"];for (int i = 0; i < DATA_CALLBACK_SIZE; i++){if (poniter_array[i].key){bool hasKey = parm["params"].containsKey(poniter_array[i].key);if (hasKey){poniter_array[i].fp(parm["params"]);}}}
}static void topicPass(char *topic,JsonVariant parm)
{for (int i = 0; i < 10; i++){if (poniter_topic[i].key){if (strstr(topic, poniter_topic[i].key)){poniter_topic[i].fp(parm);}}}
}// 所有云服务的回调都会首先进入这里,例如属性下发
static void callback(char *topic, byte *payload, unsigned int length)
{Serial.print("Message arrived [");Serial.print(topic);Serial.print("] ");payload[length] = '\0';Serial.println((char *)payload);if (strstr(topic, AliyunIoTSDK::ALINK_TOPIC_PROP_SET)){StaticJsonDocument<200> doc;DeserializationError error = deserializeJson(doc, payload); //反序列化JSON数据if (!error) //检查反序列化是否成功{parmPass(doc.as<JsonVariant>()); //将参数传递后打印输出}} else {StaticJsonDocument<200> doc;DeserializationError error = deserializeJson(doc, payload); //反序列化JSON数据if (!error) //检查反序列化是否成功{topicPass(topic,doc.as<JsonVariant>()); //将参数传递后打印输出}}
}static bool mqttConnecting = false;
void(* resetFunc) (void) = 0; //制造重启命令
void AliyunIoTSDK::mqttCheckConnect()
{if (client != NULL && !mqttConnecting){if (!client->connected()){client->disconnect();Serial.println("Connecting to MQTT Server ...");mqttConnecting = true;if (client->connect(clientId, mqttUsername, mqttPwd)){// 自定义主题订阅for (int i = 0; i < 10; i++){if (poniter_topic[i].fp){client->subscribe(poniter_topic[i].key);}}Serial.println("MQTT Connected!");}else{Serial.print("MQTT Connect err:");Serial.println(client->state());retry_count++;if(retry_count > RETRY_CRASH_COUNT){resetFunc();}}mqttConnecting = false;}else{Serial.println("state is connected");retry_count = 0;}}
}void AliyunIoTSDK::begin(Client &espClient,const char *_productKey,const char *_deviceName,const char *_deviceSecret,const char *_region)
{client = new PubSubClient(espClient);productKey = _productKey;deviceName = _deviceName;deviceSecret = _deviceSecret;region = _region;long times = millis();String timestamp = String(times);sprintf(clientId, "%s|securemode=3,signmethod=hmacsha256,timestamp=%s|", deviceName, timestamp.c_str());String signcontent = "clientId";signcontent += deviceName;signcontent += "deviceName";signcontent += deviceName;signcontent += "productKey";signcontent += productKey;signcontent += "timestamp";signcontent += timestamp;String pwd = hmac256(signcontent, deviceSecret);strcpy(mqttPwd, pwd.c_str());sprintf(mqttUsername, "%s&%s", deviceName, productKey);sprintf(ALINK_TOPIC_PROP_POST, "/sys/%s/%s/thing/event/property/post", productKey, deviceName);sprintf(ALINK_TOPIC_PROP_SET, "/sys/%s/%s/thing/service/property/set", productKey, deviceName);sprintf(ALINK_TOPIC_EVENT, "/sys/%s/%s/thing/event", productKey, deviceName);sprintf(domain, "%s.iot-as-mqtt.%s.aliyuncs.com", productKey, region);client->setServer(domain, MQTT_PORT); /* 连接WiFi之后,连接MQTT服务器 */client->setCallback(callback);mqttCheckConnect();
}void AliyunIoTSDK::loop()
{client->loop();if (millis() - lastMs >= CHECK_INTERVAL){lastMs = millis();mqttCheckConnect();messageBufferCheck();}
}void AliyunIoTSDK::sendEvent(const char *eventId, const char *param)
{char topicKey[156];sprintf(topicKey, "%s/%s/post", ALINK_TOPIC_EVENT, eventId);char jsonBuf[1024];sprintf(jsonBuf, ALINK_EVENT_BODY_FORMAT, param, eventId);Serial.println(jsonBuf);boolean d = client->publish(topicKey, jsonBuf);Serial.print("publish:0 成功:");Serial.println(d);
}
void AliyunIoTSDK::sendEvent(const char *eventId)
{sendEvent(eventId, "{}");
}
unsigned long lastSendMS = 0;// 检查是否有数据需要发送
void AliyunIoTSDK::messageBufferCheck()
{int bufferSize = 0;for (int i = 0; i < MESSAGE_BUFFER_SIZE; i++){if (PropertyMessageBuffer[i].key.length() > 0){bufferSize++;}}// Serial.println("bufferSize:");// Serial.println(bufferSize);if (bufferSize > 0){if (bufferSize >= MESSAGE_BUFFER_SIZE){sendBuffer();}else{unsigned long nowMS = millis();// 3s 发送一次数据if (nowMS - lastSendMS > 5000){sendBuffer();lastSendMS = nowMS;}}}
}// 发送 buffer 数据
void AliyunIoTSDK::sendBuffer()
{int i;String buffer;for (i = 0; i < MESSAGE_BUFFER_SIZE; i++){if (PropertyMessageBuffer[i].key.length() > 0){buffer += "\"" + PropertyMessageBuffer[i].key + "\":" + PropertyMessageBuffer[i].value + ",";PropertyMessageBuffer[i].key = "";PropertyMessageBuffer[i].value = "";}}buffer = "{" + buffer.substring(0, buffer.length() - 1) + "}";send(buffer.c_str());
}void addMessageToBuffer(char *key, String value)
{int i;for (i = 0; i < MESSAGE_BUFFER_SIZE; i++){if (PropertyMessageBuffer[i].key.length() == 0){PropertyMessageBuffer[i].key = key;PropertyMessageBuffer[i].value = value;break;}}
}
void AliyunIoTSDK::send(const char *param)
{char jsonBuf[1024];sprintf(jsonBuf, ALINK_BODY_FORMAT, param);Serial.println(jsonBuf);boolean d = client->publish(ALINK_TOPIC_PROP_POST, jsonBuf);Serial.print("publish:0 成功:");Serial.println(d);
}
void AliyunIoTSDK::send(char *key, float number)
{addMessageToBuffer(key, String(number));messageBufferCheck();
}
void AliyunIoTSDK::send(char *key, int number)
{addMessageToBuffer(key, String(number));messageBufferCheck();
}
void AliyunIoTSDK::send(char *key, double number)
{addMessageToBuffer(key, String(number));messageBufferCheck();
}void AliyunIoTSDK::send(char *key, char *text)
{addMessageToBuffer(key, "\"" + String(text) + "\"");messageBufferCheck();
}int AliyunIoTSDK::bindData(char *key, poniter_fun fp)
{int i;for (i = 0; i < DATA_CALLBACK_SIZE; i++){if (!poniter_array[i].fp){poniter_array[i].key = key;poniter_array[i].fp = fp;return 0;}}return -1;
}int AliyunIoTSDK::bindTopic(char *topic, poniter_fun fp)
{int i;for (i = 0; i < 10; i++){if (!poniter_topic[i].fp){poniter_topic[i].key = topic;poniter_topic[i].fp = fp;return 0;}}return -1;
}int AliyunIoTSDK::unbindTopic(char *topic)
{int i;for (i = 0; i < 10; i++){if (!strcmp(poniter_topic[i].key, topic)){poniter_topic[i].key = NULL;poniter_topic[i].fp = NULL;return 0;}}return -1;
}int AliyunIoTSDK::unbindData(char *key)
{int i;for (i = 0; i < DATA_CALLBACK_SIZE; i++){if (!strcmp(poniter_array[i].key, key)){poniter_array[i].key = NULL;poniter_array[i].fp = NULL;return 0;}}return -1;
}
http://www.lbrq.cn/news/838711.html

相关文章:

  • 注销网站 注销主体/中国十大网络销售公司
  • 开发小程序游戏需要多少钱/青岛seo
  • 湖南交通建设监理协会网站/微信营销号
  • 武汉建站网站/广告投放平台都有哪些
  • web前端开发案例/北京自动seo
  • 网站开发预算表/网上怎么免费推广
  • 大连建设工业产品网站/搜索排名怎么做
  • 做外卖系统哪家网站做的好/外贸营销网站建设
  • 搜索网站的浏览器/谷歌seo和百度seo区别
  • 国外室内设计网站大全/建立网站要多少钱一年
  • 无锡做食品网站的公司简介/优化推广网站怎么做最好
  • 南岸网站建设哪家好/免费广告发布平台
  • 是做网站的怀孕后/百度商家平台登录
  • 四川做网站多少钱/站长源码
  • 网站建设推广入什么费用/广告接单平台app
  • 自己的主机做网站服务器/it培训班
  • 专门做企业名录的网站/谷歌seo怎么做
  • 衢州网站建设平台/seo的特点是什么
  • 天津做网站外包公司有哪些/web网址
  • 本地东莞网站建设/官方百度下载安装
  • hbuider 做网站/seminar什么意思中文
  • b2b电子商务网站的收益模式是什么?/爱站长尾词挖掘工具
  • 大连做网站 智域/站长工具app官方下载
  • 胶州企业网站建设/百度地图客服人工电话
  • 网页开发环境一般写什么/东莞seo外包平台
  • 河北省建设网站锁安装什么驱动/指数查询
  • 做药的常用网站/网站建设报价方案
  • 邯山区建设局网站/网络科技公司
  • 网站被挂黑链/百度指数官网查询
  • 南宁最高端网站建设/晋中网站seo
  • 林曦词典|文质彬彬
  • 杭州卓健信息科技有限公司 Java 面经
  • 2024年ASOC SCI2区TOP,基于干扰模型的灰狼优化算法IIE-GWO+复杂丘陵地形农业无人机轨迹规划,深度解析+性能实测
  • 零基础学Vue3组件化开发
  • 【代码】Matlab鸟瞰图函数
  • 鸿蒙系统账号与签名内容整理