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

STM32HAL库+ESP8266+cJSON+微信小程序_连接华为云物联网平台

STM32HAL库+ESP8266+cJSON+微信小程序_连接华为云物联网平台

实验使用资源:正点原子F407

USART1:PA9P、A10(串口打印调试)

USART3:PB10、PB11(WiFi模块)

DHT11:PG9(采集数据、上报)

LED0、1:PF9、PF10(根据收到的命令,控制亮灭)

显示屏(可有可无)

0 前置内容准备

以下内容请参考之前写过的博客

  • HAL库创建工程【STM32CubeMX安装_stm32cubemx下载-CSDN博客】
  • ESP8266固件烧录【ESP8266烧录AT指令】

1 华为云物联网平台创建产品

1.1新建产品

  1. 在华为云设备接入IoTDA平台,点击左上角的【创建产品】,参考下图填写产品信息。

在这里插入图片描述

  1. 创建完成后进入创建的产品,进行产品模型设置。首先先创建一个服务,服务ID自己根据实际写。
  2. 点击【新增属性】,根据实际需求,添加需要交互的数据及其类型和访问方式。

  1. 点击【添加命令】,进行指令的设置,【下发参数】就是下发指令控制设备,【响应参数】就是读取设备上传信息。

在这里插入图片描述

1.2 新建设备

在【所有设备】界面,点击的【注册设备】添加设备

在这里插入图片描述

1.3 获取MQTT三元素

在新创建的设备中,点击查看MQTT连接参数,即可获取三元素

在这里插入图片描述

1.4 获取订阅Topic

在之前创建的产品中,Topic管理里面包含我们需要订阅的Topic

在这里插入图片描述

2 usart模块

  1. 将【stm32f1xx_it.c】里面的void USART1_IRQHandler(void)void USART3_IRQHandler(void)函数注释掉

在这里插入图片描述

  1. 将下面的代码粘贴到【usart.c】中的最下面的/* USER CODE BEGIN 1 *//* USER CODE END 1 */之间
/*** @brief       ATK-MW8266D UART printf* @param       fmt: 待打印的数据* @retval      无*/
void atk_mw8266d_uart_printf(char *fmt, ...)
{va_list ap;uint16_t len;va_start(ap, fmt);vsprintf((char *)g_uart_tx_buf, fmt, ap);va_end(ap);len = strlen((const char *)g_uart_tx_buf);HAL_UART_Transmit(&huart3, g_uart_tx_buf, len, HAL_MAX_DELAY);
}/*** @brief       ATK-MW8266D UART重新开始接收数据* @param       无* @retval      无*/
void atk_mw8266d_uart_rx_restart(void)
{g_uart_rx_frame.sta.len     = 0;g_uart_rx_frame.sta.finsh   = 0;
}/*** @brief       获取ATK-MW8266D UART接收到的一帧数据* @param       无* @retval      NULL: 未接收到一帧数据*              其他: 接收到的一帧数据*/
uint8_t *atk_mw8266d_uart_rx_get_frame(void)
{if (g_uart_rx_frame.sta.finsh == 1){g_uart_rx_frame.buf[g_uart_rx_frame.sta.len] = '\0';return g_uart_rx_frame.buf;}else{return NULL;}
}/*** @brief       获取ATK-MW8266D UART接收到的一帧数据的长度* @param       无* @retval      0   : 未接收到一帧数据*              其他: 接收到的一帧数据的长度*/
uint16_t atk_mw8266d_uart_rx_get_frame_len(void)
{if (g_uart_rx_frame.sta.finsh == 1){return g_uart_rx_frame.sta.len;}else{return 0;}
}void USART1_IRQHandler(void)
{
#if SYS_SUPPORT_OS                                                   /* 使用OS */OSIntEnter();
#endifHAL_UART_IRQHandler(&huart1);                               /* 调用HAL库中断处理公用函数 */while (HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE) != HAL_OK)     /* 重新开启中断并接收数据 */{/* 如果出错会卡死在这里 */}#if SYS_SUPPORT_OS                                                   /* 使用OS */OSIntExit();
#endif
}void USART3_IRQHandler(void)
{/* USER CODE BEGIN USART3_IRQn 0 *//* USER CODE END USART3_IRQn 0 */HAL_UART_IRQHandler(&huart3);/* USER CODE BEGIN USART3_IRQn 1 */uint8_t tmp;if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_ORE) != RESET)        /* UART接收过载错误中断 */{__HAL_UART_CLEAR_OREFLAG(&huart3);                           /* 清除接收过载错误中断标志 */(void)huart3.Instance->SR;                                   /* 先读SR寄存器,再读DR寄存器 */(void)huart3.Instance->DR;}if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_RXNE) != RESET)       /* UART接收中断 */{HAL_UART_Receive(&huart3, &tmp, 1, HAL_MAX_DELAY);           /* UART接收数据 */if (g_uart_rx_frame.sta.len < (256 - 1))   /* 判断UART接收缓冲是否溢出* 留出一位给结束符'\0'*/{g_uart_rx_frame.buf[g_uart_rx_frame.sta.len] = tmp;             /* 将接收到的数据写入缓冲 */g_uart_rx_frame.sta.len++;                                      /* 更新接收到的数据长度 */}else                                                                /* UART接收缓冲溢出 */{g_uart_rx_frame.sta.len = 0;                                    /* 覆盖之前收到的数据 */g_uart_rx_frame.buf[g_uart_rx_frame.sta.len] = tmp;             /* 将接收到的数据写入缓冲 */g_uart_rx_frame.sta.len++;                                      /* 更新接收到的数据长度 */}}if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_IDLE) != RESET)       /* UART总线空闲中断 */{g_uart_rx_frame.sta.finsh = 1;                                      /* 标记帧接收完成 */__HAL_UART_CLEAR_IDLEFLAG(&huart3);                          /* 清除UART总线空闲中断 */}/* USER CODE END USART3_IRQn 1 */
}
  1. 在【usart.c】上面的的/* USER CODE BEGIN 0 *//* USER CODE END 0 */之间加入下面的代码
#include <stdarg.h>
#include <stdio.h>
#include <string.h>#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ int handle; }; FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   USART1->DR = (uint8_t) ch;      return ch;
}
#endif uint8_t g_rx_buffer[RXBUFFERSIZE];  /* HAL库使用的串口接收缓冲 */
  1. 在【usart.c】中的void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)函数中调整中断优先级,WiFi的usart3的高于串口的,同时添加usar使能

在这里插入图片描述

  1. 在【usart.h】中的/* USER CODE BEGIN Private defines *//* USER CODE END Private defines */之间加入下面的代码
static struct
{uint8_t buf[256];              /* 帧接收缓冲 */struct{uint16_t len    : 15;                               /* 帧接收长度,sta[14:0] */uint16_t finsh  : 1;                                /* 帧接收完成标志,sta[15] */} sta;                                                  /* 帧状态信息 */
} g_uart_rx_frame = {0};                                    /* ATK-MW8266D UART接收帧缓冲信息结构体 */
static uint8_t g_uart_tx_buf[1024]; /* ATK-MW8266D UART发送缓冲 */
#define RXBUFFERSIZE   1                        /* 缓存大小 */
  1. 在【usart.h】中的/* USER CODE BEGIN Prototypes *//* USER CODE END Prototypes */之间加入下面的代码
void atk_mw8266d_uart_printf(char *fmt, ...);       /* ATK-MW8266D UART printf */
void atk_mw8266d_uart_rx_restart(void);             /* ATK-MW8266D UART重新开始接收数据 */
uint8_t *atk_mw8266d_uart_rx_get_frame(void);       /* 获取ATK-MW8266D UART接收到的一帧数据 */
uint16_t atk_mw8266d_uart_rx_get_frame_len(void);   /* 获取ATK-MW8266D UART接收到的一帧数据的长度 */

3 WiFi模块

将提前编写好的esp8266.c/.h文件分别加入Src和Inc文件夹,然后再在keil里将esp8266.c文件加入工程。

4 CJSON模块移植

移植过程查看之前写的另一篇博客【CJSON模块】

5 WIFI连接华为云

  1. 创建wifi_HW.c/.h文件。
  2. 在wifi_HW.h中宏定义连接华为云相关参数。
// Wi-Fi用户名和密码
#define WIFI_User 						 "***"  // Wi-Fi网络名称
#define WIFI_Pass   					 "***"  // Wi-Fi网络密码// ESP8266设备在华为云IoT平台的认证信息
#define ESP8266_UserName 				 "***"  // 用户名,通常为设备ID
#define ESP8266_PassWord				 "***"  // 密码或密钥
#define ESP8266_ClientID				 "***"  // MQTT客户端ID
#define ESP8266_Domain_Name				 "***"  // 华为云IoT平台的域名
#define ESP8266_Port 					 1883  // MQTT服务端口
#define ESP8266_Reconnect				 1  // 是否允许设备在断开连接后尝试重新连接// 华为云MQTT服务相关设置
#define HUAWEI_MQTT_ServiceID			 "***"  // 服务ID
#define HUAWEI_MQTT_DeviceID	         "***"  // 设备ID
#define HUAWEI_MQTT_commands             "$oc/devices/***/sys/commands/#"  // 命令订阅主题
#define HUAWEI_MQTT_commands_response    "$oc/devices/***/sys/commands/response/request_id="  // 命令响应主题
#define HUAWEI_MQTT_report               "$oc/devices/***/sys/properties/report"  // 属性上报主题
  1. 编写wifi_HW.c文件,调用esp8266.c中编写的函数连接华为云,然后将该函数名加入wifi_HW.h中。
void wifi_init(void){uint8_t ret = 0;ret  = ESP8266_Reset();printf("1: %d\r\n",ret);ret = ESP8266_ATE(0);printf("2: %d\r\n",ret);ret = ESP8066_Mode(1);printf("3: %d\r\n",ret);ret = ESP8266_WiFi(WIFI_User, WIFI_Pass);printf("4: %d\r\n",ret);ret = ESP8266_MQTTUSERCFG(ESP8266_UserName, ESP8266_PassWord);printf("5: %d\r\n",ret);ret = ESP8266_MQTTCLIENTID(ESP8266_ClientID);printf("6: %d\r\n",ret);ret =  ESP8266_MQTTCONN(ESP8266_Domain_Name,ESP8266_Port,ESP8266_Reconnect);printf("7: %d\r\n",ret);ret =  ESP8266_MQTTSUB(HUAWEI_MQTT_commands);printf("8: %d\r\n",ret);
}

6 数据交互

6.1 设备属性上报

参考华为云官方给出的MQTT属性上报样例,在wifi_HW.c中编写report_Json函数,使用cJSON模块封装传感器数据,然后将其发送到云平台。

在这里插入图片描述

可以看出该消息的JSON格式:

(1) 在根对象中,有一个名为services的键,其值是一个数组。

(2) 在services数组中,有一个服务对象,它包含两个键:service_id和properties

(3) 在properties对象中,存放的键值对就是在产品中创建的属性。

根据这种格式,在report_Json函数中封装JSON消息

void report_Json(uint8_t temperature, uint8_t humidity,uint8_t adcx){uint8_t cmd[1024]; // 用于存储构建的AT命令char *str = NULL; // 指向JSON字符串的指针int i = 0; // 循环迭代变量uint8_t params_buf[1024]; // 用于存储处理过的JSON字符串uint16_t move_num = 0; // 用于记录字符串处理过程中的移动次数cJSON *json = cJSON_CreateObject(); // 创建一个空的JSON对象cJSON *properties_cjson = cJSON_CreateObject(); // 创建一个空的子JSON对象,用于存储属性cJSON *service = cJSON_CreateObject(); // 创建一个空的子JSON对象,用于存储服务信息cJSON *services_array = cJSON_CreateArray(); // 创建一个空的JSON数组,用于存储服务数组// 向属性对象中添加温度、湿度和光照强度数据cJSON_AddNumberToObject(properties_cjson, "temperature", temperature);cJSON_AddNumberToObject(properties_cjson, "humidity", humidity);cJSON_AddNumberToObject(properties_cjson, "light", adcx);// 向服务对象中添加服务ID和属性cJSON_AddStringToObject(service, "service_id", "yun");cJSON_AddItemToObject(service, "properties", properties_cjson);cJSON_AddItemToObject(json, "services", services_array);// 将服务数组添加到JSON对象中cJSON_AddItemToArray(services_array, service);// 将JSON对象转换为无格式的字符串str = cJSON_PrintUnformatted(json);// 打印JSON格式的字符串//printf("json格式 = %s\r\n", str);// 为MQTT发布添加转义字符for(i = 0; *str != '\0'; i++){params_buf[i] = *str;// 如果下一个字符是引号或逗号,添加转义字符if(*(str + 1) == '"' || *(str + 1) == ','){params_buf[++i] = '\\';}str++;move_num++;}str = str - move_num; // 回退指针到JSON字符串的开始// 打印处理过的JSON字符串//printf("params_buf = %s\r\n", params_buf);// 构建AT命令sprintf((char *)cmd,"AT+MQTTPUB=0,\""HUAWEI_MQTT_report"\",\"%s\",0,0\r\n",params_buf);// 打印即将发送的AT命令//printf("开始发送数据:%s", cmd);// 发送AT命令并通过ESP8266模块ESP8266_Sent_AT(cmd, "OK", 500);// 清理JSON对象占用的内存cJSON_Delete(json);// 如果分配了额外的字符串空间,释放它if(str != NULL){free(str);str = NULL;//printf("释放str空间成功\r\n");}
}

6.2 云端命令下发

参考华为云官方给出的MQTT下行请求样例,在wifi_HW.c中编写rcv_json函数,解析云平台下发的JSON消息字符串,如果成功接收后,需要给云平台返回接收成功的消息命令。
在这里插入图片描述

从给出的样例中可以看出,下发的指令在paras键所对应的JSON值中,只需分析其中的键的名字,然后读取相匹配的键的值,即可获取下发的命令。

参考下图响应参数的格式,可知响应参数只需发送订阅的topic和下发命令中的request_id的值即可,后面的JSON消息体均可省略。

在这里插入图片描述

void rcv_json(void){uint8_t *ret = NULL; // 用于存储接收到的数据帧cJSON *cjson = NULL; // 用于存储解析后的JSON对象char topic_buff[1024]; // 用于存储MQTT主题int num; // 用于存储接收数据的数量char recv_buffer[1024]; // 用于存储接收到的JSON数据char request_id[37];char device_id[256];uint8_t cmd[1024]; // 用于存储构建的AT命令ret = atk_mw8266d_uart_rx_get_frame(); // 获取UART接收到的数据帧atk_mw8266d_uart_rx_restart(); // 重启UART接收char *ptr_recv = strstr((const char *)ret,"+MQTTSUBRECV"); // 检查是否包含MQTT订阅数据标志if(ptr_recv!=NULL){ // 如果是MQTT订阅数据memset(device_id,0,sizeof(device_id)); memset(request_id,0,sizeof(request_id)); sscanf((char *)ret, "+MQTTSUBRECV:0,\"$oc/devices/%255[^/]/sys/commands/request_id=%36s\",%d,%255s", device_id, request_id, &num, recv_buffer);//printf("判断DeviceID:  %s\r\n",device_id);// printf("接收数据成功,开始解析  %s\r\n",recv_buffer);//判断DeviceIDif(strstr(device_id,HUAWEI_MQTT_DeviceID)) {// printf("接收数据成功,开始解析  %s\r\n",recv_buffer);cjson = cJSON_Parse(recv_buffer); // 解析JSON数据}if(cjson==NULL) // 如果JSON解析失败printf("cjson 解析错误\r\n"); // 打印错误信息else{cJSON *json_data = cJSON_GetObjectItem(cjson,"paras"); // 获取JSON对象中的paras项if(json_data==NULL){ printf("cjson  没有数据\r\n"); // 打印错误信息return;}else{// printf("cjson 内存大小为 = %d\r\n",sizeof(cjson)); // 打印JSON对象的内存大小// 解析数据if(cJSON_GetObjectItem(json_data,"led_flag")!=NULL) {LED_Switch = cJSON_GetObjectItem(json_data,"led_flag")->valueint; printf("csjon解析成功 LED_Switch = %d\r\n",LED_Switch); }if(cJSON_GetObjectItem(json_data,"temp_flag")!=NULL) {temp_LED_Switch = cJSON_GetObjectItem(json_data,"temp_flag")->valueint; printf("csjon解析成功 temp_LED_Switch = %d\r\n",temp_LED_Switch);}char full_topic[256];    snprintf(full_topic, sizeof(full_topic), "%s%s", HUAWEI_MQTT_commands_response, request_id);sprintf((char *)cmd, "AT+MQTTPUB=0,\"%s\",\"\",0,0\r\n", full_topic);ESP8266_Sent_AT(cmd, "OK", 500);}cJSON_Delete(cjson); // 删除JSON对象,释放内存//cJSON_Delete(json_data);}}
}

7 微信小程序连接华为云

7.1 开发方式

  1. 使用微信开发工具创建微信小程序项目
  2. 微信小程序调用应用侧API,获取云平台数据
  3. 将获得的数据进行显示

7.2 微信小程序创建

【略…】

7.3 创建IAM账户(云平台)

  1. 统一身份认证(Identity and Access Management,简称IAM)是华为云提供权限管理的基础服务,可以安全地控制云服务和资源的访问权限。应用侧需要通过IAM服务鉴权,获取token。因此在开发之前需要先创建IAM用户。
  2. 在【统一身份认证服务】页面,点击【创建用户】,参考下图创建账号,里面填写的自定义密码需要记住,然后将其加入【admin】用户组。

在这里插入图片描述

  1. 创建成功后,退出登录华为云,使用IAM账号登录华为云,验证是否成功。

7.3 获取Token(小程序)

  1. 参考华为云提供的请求示例,发送获取Token的http请求消息

在这里插入图片描述

  1. 华为云认证通过后向应用服务器返回鉴权令牌X-Subject-Token,接口返回的响应消息头中X-Subject-Token就是需要获取的用户Token。根据上述示例,在微信开发工具中,使用wx.request发送请求,然后分析响应消息头,获取Token。
gettoken(){var that=this;   wx.request({url: 'https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens',data:'{"auth": { "identity": {"methods": ["password"],"password": {"user": {"name": "***","password": "***","domain": {"name": "***"}}}},"scope": {"project": {"name": "cn-north-4"}}}}',method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECTheader: {'content-type': 'application/json' }, // 请求的 header success: function(res){// successvar token='';token=JSON.stringify(res.header['X-Subject-Token']);//解析消息头的tokentoken=token.replaceAll("\"", "");wx.setStorageSync('token',token);},});
}
  1. 获取Token后,再调用其他接口时,需要在请求消息头中添加X-Auth-Token,其值为获取到的Token。例如Token值为“ABCDEFJ…”,则调用接口时将“X-Auth-Token: ABCDEFJ…”加到请求消息头即可,如下所示。

在这里插入图片描述

7.4 获取设备影子(小程序)

  1. 参考请求示例,发送请求获取设备影子数据。

在这里插入图片描述

  1. 查看返回的HTTP响应消息,查看所需要的数据所在位置,如下图所示,可以发现我们需要的数据在data里面的shadow[0]中的reported下的properties里面。

在这里插入图片描述

  1. 根据分析的结果,在微信开发工具中编写代码,获取数据。
getinfo(){var that = thisvar token = wx.getStorageSync('token');//读缓存中保存的tokenwx.request({url: 'https://653a151f50.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/661f377e2ccc1a583881a678/devices/661f377e2ccc1a583881a678_yun_dht11/shadow',data:'',method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECTheader: {'content-type': 'application/json','X-Auth-Token':token },success: function (res) {that.setData({humi:res.data.shadow[0].reported.properties.humidity,temp:res.data.shadow[0].reported.properties.temperature,light:res.data.shadow[0].reported.properties.light})}});
}

7.5 下发设备命令(小程序)

参考请求示例,在微信开发工具中编写代码下发命令。

在这里插入图片描述

if(that.data.lset > that.data.light){wx.request({url: 'https://653a151f50.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/661f377e2ccc1a583881a678/devices/661f377e2ccc1a583881a678_yun_dht11/commands',data:'{"service_id": "yun","command_name": "led","paras": {"led_flag": true}}',method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECTheader: {'content-type': 'application/json','X-Auth-Token':token }, //请求的header success: function(res){console.log("下发命令成功");//打印完整消息}, });
}

8 小程序界面设计

8.1 主页数据显示

在wxml中设置布局,在wxss中设置样式,如下图所示。

在这里插入图片描述

8.2 Echarts数据可视化

ECharts一个使用JavaScript实现的开源可视化库。ECharts提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于BI的漏斗图,仪表盘,并且支持图与图之间的混搭。

微信小程序使用Echarts进行可视化的步骤如下所示。

  1. 将Echarts下载到本地,并放入的微信小程序工程文件夹中,如下图所示。

在这里插入图片描述

  1. 在lineset.json中引入ec-canvas组件,如下图所示。

在这里插入图片描述

  1. 参考官网给出的折线图堆叠示例,编写该图像的显示函数function line_set(chart,time_data,hum_data,tem_data,ligh_data)。

  2. 初始化图表,同时调用line_set函数显示。

init_chart: function (time_data,hum_data,tem_data,ligh_data) {        this.oneComponent.init((canvas, width, height, dpr) => {const chart = echarts.init(canvas, null, {width: width,height: height,devicePixelRatio: dpr });line_set(chart,time_data,hum_data,tem_data,ligh_data)this.chart = chart;return chart;});
}
  1. 将获得的影子设备的数据存入数组中,然后将其传入init_chart(date,humi,temp,ligh)中,进行数据实时可视化显示。
temp = that.data.Temperature;
humi = that.data.Humidity;
ligh = that.data.Light;
date = that.data.Time;
temp.push(res.data.shadow[0].reported.properties.temperature);
humi.push(res.data.shadow[0].reported.properties.humidity);
ligh.push(res.data.shadow[0].reported.properties.light);
date.push(formattedTime);
if (temp.length > 7) {temp.shift(); // 移除数组的第一个元素humi.shift();ligh.shift();date.shift();
}

32工程源码(CSDN):【免费】STM32HAL库+ESP8266+cJSON+微信小程序-连接华为云物联网平台.zip资源-CSDN文库

微信小程序源码(CSDN):【免费】STM32HAL库+ESP8266+cJSON+微信小程序-连接华为云物联网平台(微信小程序侧)资源-CSDN文库

32工程+微信小程序源码(GitHub):STM32HAL库+ESP8266+cJSON+微信小程序_连接华为云物联网平台

相关文章:

STM32HAL库+ESP8266+cJSON+微信小程序_连接华为云物联网平台

STM32HAL库ESP8266cJSON微信小程序_连接华为云物联网平台 实验使用资源&#xff1a;正点原子F407 USART1&#xff1a;PA9P、A10&#xff08;串口打印调试&#xff09; USART3&#xff1a;PB10、PB11&#xff08;WiFi模块&#xff09; DHT11&#xff1a;PG9&#xff08;采集数据…...

debian或Ubuntu中开启ssh允许root远程ssh登录的方法

debian或Ubuntu中开启ssh允许root远程ssh登录的方法 前因&#xff1a; 因开发需要&#xff0c;需要设置开发板的ssh远程连接。 操作步骤如下&#xff1a; 安装openssh-server sudo apt install openssh-server设置root用户密码&#xff1a; sudo passwd root允许root用户…...

C++《日期》实现

C《日期》实现 头文件实现文件 头文件 在该文件中是为了声明函数和定义类成员 using namespace std; class Date {friend ostream& operator<<(ostream& out, const Date& d);//友元friend istream& operator>>(istream& cin, Date& d);//…...

【面试题】MySQL(第三篇)

目录 1. MySQL中如何处理死锁&#xff1f; 2. MySQL中的主从复制是如何实现的&#xff1f; 3. MySQL中的慢查询日志是什么&#xff1f;如何使用它来优化性能&#xff1f; 4.存储过程 一、定义与基本概念 二、特点与优势 三、类型与分类 四、创建与执行 五、示例 六、总…...

tensorflow之欠拟合与过拟合,正则化缓解

过拟合泛化性弱 欠拟合解决方法&#xff1a; 增加输入特征项 增加网络参数 减少正则化参数 过拟合的解决方法&#xff1a; 数据清洗 增大训练集 采用正则化 增大正则化参数 正则化缓解过拟合 正则化在损失函数中引入模型复杂度指标&#xff0c;利用给w增加权重&#xff0c;…...

vue实现a-model弹窗拖拽移动

通过自定义拖拽指令实现 实现效果 拖动顶部&#xff0c;可对整个弹窗实施拖拽&#xff08;如果需要拖动底部、中间内容实现拖拽&#xff0c;把下面的ant-modal-header对应改掉就行&#xff09; 代码实现 编写自定义指令 新建一个ts / js文件&#xff0c;用ts举例 import V…...

速盾:如何加强网站的安全性

随着互联网的快速发展&#xff0c;网站的安全性变得越来越重要。CDN&#xff08;内容分发网络&#xff09;是一种常见的网络加速服务&#xff0c;它可以将网站的静态内容分发到全球各地的服务器上&#xff0c;以提供更快的访问速度。然而&#xff0c;CDN 也存在一些安全风险&am…...

【PyTorch单点知识】自动求导机制的原理与实践

文章目录 0. 前言1. 自动求导的基本原理2. PyTorch中的自动求导2.1 创建计算图2.2 反向传播2.3 反向传播详解2.4 梯度清零2.5 定制自动求导 3. 代码实例&#xff1a;线性回归的自动求导4. 结论 0. 前言 按照国际惯例&#xff0c;首先声明&#xff1a;本文只是我自己学习的理解&…...

【Java】搜索引擎设计:信息搜索怎么避免大海捞针?

一、内容分析 我们准备开发一个针对全网内容的搜索引擎&#xff0c;产品名称为“Bingoo”。 Bingoo的主要技术挑战包括&#xff1a; 针对爬虫获取的海量数据&#xff0c;如何高效地进行数据管理&#xff1b;当用户输入搜索词的时候&#xff0c;如何快速查找包含搜索词的网页…...

【Python】ModuleNotFoundError: No module named ‘distutils.util‘ bug fix

【Python】ModuleNotFoundError: No module named distutils.util bug fix 1. error like this2. how to fix why this error occured , because i remove the origin version python of ubuntu of 20.04. then the system trapped in tty1 , you must make sure the laptop li…...

痉挛性斜颈对生活有哪些影响?

痉挛性斜颈&#xff0c;这个名字听起来可能并不熟悉&#xff0c;但它实际上是一种神经系统疾病&#xff0c;影响着全球数百万人的生活质量。它以一种无法控制的方式&#xff0c;使患者的颈部肌肉发生不自主的收缩&#xff0c;导致头部姿势异常。对于患者来说&#xff0c;痉挛性…...

Javassist 修改 jar 包里的 class 文件

前言 Javassist 是一个用于处理 Java 字节码的类库&#xff0c;可以用以修改 class 文件或 jar 包里的 class 文件。 简单来说我们用Java编写的代码是放在 java 格式的代码文件里&#xff0c;在编译的时候会编译为 class 格式的字节码文件&#xff0c;然后一般所有 class 文件…...

交换机的二三层原理

相同VLAN的交换机交换原理&#xff08;二层交换原理&#xff09;&#xff1a; 交换机收到数据帧&#xff0c;首先会检查数据帧的VLAN标签和目标MAC&#xff0c;若属于相同VLAN&#xff0c;且该目标MAC在本地MAC表中&#xff0c;则直接根据出接口进行数据转发 不同VLAN的交换机…...

HarmonyOS ArkUi 字符串<展开/收起>功能

效果图&#xff1a; 官方API&#xff1a; ohos.measure (文本计算) 方式一 measure.measureTextSize 跟方式二使用一样&#xff0c;只是API调用不同&#xff0c;可仔细查看官网方式二 API 12 import { display, promptAction } from kit.ArkUI import { MeasureUtils } fr…...

Lianwei 安全周报|2024.07.09

新的一周又开始了&#xff0c;以下是本周「Lianwei周报」&#xff0c;我们总结推荐了本周的政策/标准/指南最新动态、热点资讯和安全事件&#xff0c;保证大家不错过本周的每一个重点&#xff01; 政策/标准/指南最新动态 01 《数字中国发展报告&#xff08;2023年&#xff09…...

火遍全网的15个Python的实战项目,你该不会还不知道怎么用吧!

经常听到有朋友说&#xff0c;学习编程是一件非常枯燥无味的事情。其实&#xff0c;大家有没有认真想过&#xff0c;可能是我们的学习方法不对&#xff1f; 比方说&#xff0c;你有没有想过&#xff0c;可以通过打游戏来学编程&#xff1f; 今天我想跟大家分享几个Python小游…...

快速使用BRTR公式出具的大模型Prompt提示语

Role:文章模仿大师 Background: 你是一位文章模仿大师&#xff0c;擅长分析文章风格并进行模仿创作。老板常让你学习他人文章后进行模仿创作。 Attention: 请专注在文章模仿任务上&#xff0c;提供高质量的输出。 Profile: Author: 一博Version: 1.0Language: 中文Descri…...

Xilinx FPGA DDR4 接口的 PCB 准则

目录 1. 简介 1.1 FPGA-MIG 与 DDR4 介绍 1.2 DDR4 信号介绍 1.2.1 Clock Signals 1.2.2 Address and Command Signals 1.2.3 Control Signals 1.2.4 Data Signals 1.2.5 Other Signals 2. 通用存储器布线准则 3. Xilinx FPGA-MIG 的 PCB 准则 3.1 引脚配置 3.1.1 …...

神经网络 | Transformer 基本原理

目录 1 为什么使用 Transformer&#xff1f;2 Attention 注意力机制2.1 什么是 Q、K、V 矩阵&#xff1f;2.2 Attention Value 计算流程2.3 Self-Attention 自注意力机制2.3 Multi-Head Attention 多头注意力机制 3 Transformer 模型架构3.1 Positional Encoding 位置编…...

浅析 VO、DTO、DO、PO 的概念

文章目录 I 浅析 VO、DTO、DO、PO1.1 概念1.2 模型1.3 VO与DTO的区别I 浅析 VO、DTO、DO、PO 1.1 概念 VO(View Object) 视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。DTO(Data Transfer Object): 数据传输对象,这个概念来源于J2EE的设…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...