温湿传感器(学习笔记下)
接着我们温湿传感器上半部分的学习,现在我们学习接下来的部分,编写GXHTC3驱动程序,也就是给gxhtc3.c文件添加代码,我们要判断gxhtc3芯片是否存在和正常,就要先读取gxhtc3的ID号,根据gxhtc3的数据手册,读取命令为0xEFC8,发送命令后,可以读出16位的ID号和1个CRC字节。CRC字节用来校验判断读取的数据是否正确。
首先,我们需要先写一个校验代码,如下代码所示,
#define POLYNOMIAL 0x31 // P(x) = x^8 + x^5 + x^4 + 1 = 00110001,POLYNOMIAL是多项式因子//CRC校验
uint8_t gxhtc3_calc_crc(uint8_t *crcdata, uint8_t len) //两个参数分别是需要校验的数据和数据长度
{uint8_t crc = 0xFF; for(uint8_t i = 0; i < len; i++){crc ^= (crcdata[i]); //crc初始值是0xFF,crcdata与crc按位与或运算后,把计算后的值赋值给crc,crcdata中位是0的位置会变成1,位是1的位置会变成0,这条语句的作用就是把crcdata的值,1变成0,0变成1,然后赋值给crcfor(uint8_t j = 8; j > 0; --j) //这里的for循环按位计算,如果位是0,直接左移1位,如果位是1,左移1位后再与多项式按位与或运算{if(crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;else crc = (crc << 1);}}return crc; //返回值是计算好的CRC字节(需要和读出的CRC字节做对比,一致的话正确)
}
接下来,我们需要写一个读取ID的代码,
// 读取ID
esp_err_t gxhtc3_read_id(void) //该函数返回一个 esp_err_t 类型的错误码,表示操作是否成功
{esp_err_t ret; // 用于存储函数执行过程中返回的错误码uint8_t data[3]; //用于存储从传感器读取的3字节数据(包括ID和CRC校验值)i2c_cmd_handle_t cmd = i2c_cmd_link_create(); //创建一个新的I2C命令链i2c_master_start(cmd); //发送I2C起始信号i2c_master_write_byte(cmd, 0x70 << 1 | I2C_MASTER_WRITE, true); //写入I2C设备的地址(0x70),并设置为写模式i2c_master_write_byte(cmd, 0xEF, true); //写入命令字节0xEF,用于选择传感器的ID读取命令i2c_master_write_byte(cmd, 0xC8, true); //写入命令字节0xC8,可能是用于配置或确认读取操作i2c_master_stop(cmd); //发送I2C停止信号ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS); //执行I2C命令链,超时时间为1000毫秒if (ret != ESP_OK) { //如果执行失败(ret != ESP_OK),则跳转到 end 标签,释放资源并返回错误码goto end;}cmd = i2c_cmd_link_create(); //重新创建一个新的I2C命令链i2c_master_start(cmd); //发送I2C起始信号i2c_master_write_byte(cmd, 0x70 << 1 | I2C_MASTER_READ, true); //写入I2C设备的地址(0x70),并设置为读模式i2c_master_read(cmd, data, 3, I2C_MASTER_LAST_NACK); //读取3字节数据到 data 数组中,最后一个字节读取后发送NACK信号i2c_master_stop(cmd); //发送I2C停止信号ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS); //执行I2C命令链,超时时间为1000毫秒if(data[2]!=gxhtc3_calc_crc(data,2)){ //计算前两个字节的CRC校验值 ret = ESP_FAIL; //如果计算的CRC值与读取的CRC值不匹配(data[2]),则将 ret 设置为 ESP_FAIL,表示校验失败}
end:i2c_cmd_link_delete(cmd); //释放I2C命令链资源return ret; //表示函数执行的结
}
因为函数中用到了i2c的函数,所以给这个文件也添加一个i2c.h头文件。上面的函数中用到了I2C_MASTER_NUM这个宏定义,这个宏定义是在myi2c.h文件中定义的,所以也需要添加myi2c.h头文件
#include "myi2c.h"
#include "driver/i2c.h"
接下来给gxhtc3.h文件中添加读取ID函数的声明
extern esp_err_t gxhtc3_read_id(void);
这里用到了esp_err_t类型,所以也需要调用一下对应的头文件
#include "esp_err.h"
然后我们在main.c文件中调用这个函看能正确读取ID号
void app_main(void)
{ESP_ERROR_CHECK(i2c_master_init()); //调用 i2c_master_init() 函数初始化I2C总线,并使用 ESP_ERROR_CHECK 宏检查初始化是否成功。如果初始化失败,程序将停止并打印错误信息ESP_LOGI(TAG, "I2C initialized successfully"); //如果I2C初始化成功,使用 ESP_LOGI 宏打印一条信息,表示I2C总线已成功初始化esp_err_t ret = gxhtc3_read_id(); //调用 gxhtc3_read_id() 函数读取GXHTC3传感器的ID,并将返回值存储在 ret 变量中while(ret != ESP_OK) // 如果读取ID失败(ret != ESP_OK),则进入循环{ret = gxhtc3_read_id(); //再次尝试读取GXHTC3传感器的IDESP_LOGI(TAG,"GXHTC3 READ ID"); //打印一条信息,表示正在尝试读取GXHTC3传感器的IDvTaskDelay(1000 / portTICK_PERIOD_MS); //延迟1000毫秒(1秒),然后再次尝试读取ID}ESP_LOGI(TAG,"GXHTC3 OK"); //如果成功读取GXHTC3传感器的ID(ret == ESP_OK),打印一条信息,表示读取成功
}
这里使用了vTaskDelay函数,需要在main.c文件中添加freeRTOS相关头文件
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
以上完成之后,我们就可以试着编译一下了。
还没有完,接着,我们继续学习编写读取温湿度数据程序,根据学习,我们再给gxhtc3.c文件中添加读取温湿度的相关函数。根据gxhtc3的数据手册上介绍,每一次读取数据,都需要经过四组命令,按照执行顺序,分别是唤醒、测量、读出、休眠,我们分别写这四个命令的函数,首先,我们要写一下唤醒的代码,以下是我写的
//唤醒
esp_err_t gxhtc3_wake_up(void) //该函数返回一个 esp_err_t 类型的错误码,表示操作是否成功
{int ret; //用于存储函数执行过程中返回的错误码i2c_cmd_handle_t cmd = i2c_cmd_link_create(); //创建一个新的I2C命令链i2c_master_start(cmd); //发送I2C起始信号i2c_master_write_byte(cmd, 0x70 << 1 | I2C_MASTER_WRITE, true); //写入I2C设备的地址(0x70),并设置为写模式 i2c_master_write_byte(cmd, 0x35, true); //写入命令字节0x35,用于唤醒传感器i2c_master_write_byte(cmd, 0x17, true); //写入命令字节0x17,可能是用于配置或确认唤醒操作i2c_master_stop(cmd); //发送I2C停止信号ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS); //执行I2C命令链,超时时间为1000毫秒,执行结果存储在 ret 变量中i2c_cmd_link_delete(cmd); //释放I2C命令链资源return ret; //表示函数执行的结果
}
接着,我们在写一下测量部分的函数
// 测量
esp_err_t gxhtc3_measure(void) //该函数返回一个 esp_err_t 类型的错误码,表示操作是否成功
{int ret; //用于存储函数执行过程中返回的错误码i2c_cmd_handle_t cmd = i2c_cmd_link_create(); //创建一个新的I2C命令链i2c_master_start(cmd); //发送I2C起始信号i2c_master_write_byte(cmd, 0x70 << 1 | I2C_MASTER_WRITE, true); //写入I2C设备的地址(0x70),并设置为写模式i2c_master_write_byte(cmd, 0x7c, true); //写入命令字节0x7c,用于触发传感器进行测量i2c_master_write_byte(cmd, 0xa2, true); //写入命令字节0xa2,可能是用于配置或确认测量操作i2c_master_stop(cmd); // 发送I2C停止信号ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS); //执行I2C命令链,超时时间为1000毫秒i2c_cmd_link_delete(cmd); // 释放I2C命令链资源return ret; //表示函数执行的结果
}
接着,我们写一下读取温湿数据部分的代码
// 读出温湿度数据
esp_err_t gxhtc3_read_tah(void) //该函数返回一个 esp_err_t 类型的错误码,表示操作是否成功
{int ret; //用于存储函数执行过程中返回的错误码i2c_cmd_handle_t cmd = i2c_cmd_link_create(); //创建一个新的I2C命令链i2c_master_start(cmd); //发送I2C起始信号i2c_master_write_byte(cmd, 0x70 << 1 | I2C_MASTER_READ, true); //写入I2C设备的地址(0x70),并设置为读模式i2c_master_read(cmd, tah_data, 6, I2C_MASTER_LAST_NACK); //从传感器读取6字节数据到 tah_data 数组中,最后一个字节读取后发送NACK信号i2c_master_stop(cmd); //发送I2C停止信号ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS); //执行I2C命令链,超时时间为1000毫秒i2c_cmd_link_delete(cmd); //释放I2C命令链资源return ret; //表示函数执行的结果
}
以上是读出温湿度数据的函数。读到的数据字节放到tah_data这个数组里面,需要在gxhtc3.c文件的include下面定义tah_data数组。读出函数需要跟在测量函数后使用,一次读取6个字节,分别是2个温度数据+1个温度CRC字节+2个湿度数据+1个湿度CRC字节
接着,我们写休眠部分的函数
// 休眠
esp_err_t gxhtc3_sleep(void) //该函数返回一个 esp_err_t 类型的错误码,表示操作是否成功
{int ret; //用于存储函数执行过程中返回的错误码i2c_cmd_handle_t cmd = i2c_cmd_link_create(); //创建一个新的I2C命令链i2c_master_start(cmd); //发送I2C起始信号i2c_master_write_byte(cmd, 0x70 << 1 | I2C_MASTER_WRITE, true); //写入I2C设备的地址(0x70),并设置为写模式i2c_master_write_byte(cmd, 0xB0, true); //写入命令字节0xB0,用于使传感器进入休眠模式i2c_master_write_byte(cmd, 0x98, true); //写入命令字节0x98,可能是用于配置或确认休眠操作i2c_master_stop(cmd); //发送I2C停止信号ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS); //执行I2C命令链,超时时间为1000毫秒i2c_cmd_link_delete(cmd); //执行结果存储在 ret 变量中return ret; //表示函数执行的结果
}
接下来,我们再写一个函数,把上面的4个命令函数使用上,获取温湿度
uint16_t rawValueTemp, rawValueHumi; //rawValueTemp: 用于存储从传感器读取的原始温度数据。// rawValueHumi: 用于存储从传感器读取的原始湿度数据
float temp=0, humi=0;
uint8_t temp_int, humi_int;
// 获取并计算温湿度数据
esp_err_t gxhtc3_get_tah(void) //该函数返回一个 esp_err_t 类型的错误码,表示操作是否成功
{int ret; //用于存储函数执行过程中返回的错误码gxhtc3_wake_up(); //调用 gxhtc3_wake_up() 函数唤醒传感器,使其进入工作状态gxhtc3_measure(); //调用 gxhtc3_measure() 函数触发传感器进行温湿度测量vTaskDelay(20 / portTICK_PERIOD_MS); //延迟20毫秒,等待传感器完成测量gxhtc3_read_tah(); //调用 gxhtc3_read_tah() 函数从传感器读取温湿度数据,并存储在 tah_data 数组中gxhtc3_sleep(); //调用 gxhtc3_sleep() 函数使传感器进入休眠模式,以节省功耗if((tah_data[2]!=gxhtc3_calc_crc(tah_data,2)|| //gxhtc3_calc_crc(tah_data, 2): 计算前两个字节的CRC校验值
(tah_data[5]!=gxhtc3_calc_crc(&tah_data[3],2)))){ //gxhtc3_calc_crc(&tah_data[3], 2): 计算后两个字节的CRC校验值temp = 0; //如果CRC校验失败,将温度和湿度值设为0,并将 ret 设置为 ESP_FAILhumi = 0;temp_int = 0;humi_int = 0;ret = ESP_FAIL;}else{rawValueTemp = (tah_data[0]<<8) | tah_data[1]; // 将前两个字节合并为一个16位整数,表示原始温度数据rawValueHumi = (tah_data[3]<<8) | tah_data[4]; //将后两个字节合并为一个16位整数,表示原始湿度数据temp = (175.0 * (float)rawValueTemp) / 65535.0 - 45.0; //将原始温度数据转换为实际温度值(单位:摄氏度)humi = (100.0 * (float)rawValueHumi) / 65535.0; //将原始湿度数据转换为实际湿度值(单位:百分比)temp_int = round(temp); //将温度值四舍五入为整数humi_int = round(humi);ret = ESP_OK;}return ret;
}
转换整形数据的时候,用到了round函数,需要添加math.h头文件
#include <math.h>
然后我们在gxhtc3.h文件中,添加gxhtc3_get_tah函数声明,因为接下来要在main.c文件中调用
extern esp_err_t gxhtc3_get_tah(void);
因为用到了esp_err_t类型,所以还需要添加esp_err.h头文件
#include "esp_err.h"
现在打开main.c文件,在app_main函数中的while循环读取ID的下面,创建一个gxhtc3_task任务
xTaskCreate(gxhtc3_task, "gxhtc3_task", 4096, NULL, 6, NULL);
然后编写这个任务函数
static void gxhtc3_task(void *args) //该函数接受一个 void * 类型的参数 args,通常用于传递任务参数
{esp_err_t ret; //用于存储 gxhtc3_get_tah() 函数返回的错误码while(1){ret = gxhtc3_get_tah(); //调用 gxhtc3_get_tah() 函数获取温湿度数据,并将返回值存储在 ret 变量中if (ret!=ESP_OK) {ESP_LOGE(TAG,"GXHTC3 READ TAH ERROR."); //如果 gxhtc3_get_tah() 返回的错误码不是 ESP_OK,则使用 ESP_LOGE 宏打印错误信息,表示读取温湿度数据失败}else{ESP_LOGI(TAG, "TEMP:%.1f HUMI:%.1f", temp, humi); //如果 gxhtc3_get_tah() 返回成功(ESP_OK),则使用 ESP_LOGI 宏打印温湿度数据ESP_LOGI(TAG, "TEMP:%d HUMI:%d", temp_int, humi_int); //打印整数格式的温度和湿度值}vTaskDelay(1000 / portTICK_PERIOD_MS); //调用 vTaskDelay 函数延迟1000毫秒(1秒),然后再次执行循环}
}
这其中用到了temp humi temp_int humi_int这几个变量,所以我们需要在函数前面声明一下来自外部文件
extern float temp,humi;
extern uint8_t temp_int,humi_int;
接下来,我们在主函数中调用这个任务函数
void app_main(void)
{ESP_ERROR_CHECK(i2c_master_init()); //调用 i2c_master_init() 函数初始化I2C总线,并使用 ESP_ERROR_CHECK 宏检查初始化是否成功。如果初始化失败,程序将停止并打印错误信息ESP_LOGI(TAG, "I2C initialized successfully"); //如果I2C初始化成功,使用 ESP_LOGI 宏打印一条信息,表示I2C总线已成功初始化esp_err_t ret = gxhtc3_read_id(); //调用 gxhtc3_read_id() 函数读取GXHTC3传感器的ID,并将返回值存储在 ret 变量中while(ret != ESP_OK) //如果读取ID失败(ret != ESP_OK),则进入循环{ret = gxhtc3_read_id(); //再次尝试读取GXHTC3传感器的IDESP_LOGI(TAG,"GXHTC3 READ ID"); //打印一条信息,表示正在尝试读取GXHTC3传感器的IDvTaskDelay(1000 / portTICK_PERIOD_MS); //延迟1000毫秒(1秒),然后再次尝试读取ID}ESP_LOGI(TAG,"GXHTC3 OK"); // 如果成功读取GXHTC3传感器的ID(ret == ESP_OK),打印一条信息,表示读取成功xTaskCreate(gxhtc3_task, "gxhtc3_task", 4096, NULL, 6, NULL); // 创建并启动一个任务,用于持续读取GXHTC3传感器的温湿度数据
}
最后,我们就可以进行编译了。
相关文章:
温湿传感器(学习笔记下)
接着我们温湿传感器上半部分的学习,现在我们学习接下来的部分,编写GXHTC3驱动程序,也就是给gxhtc3.c文件添加代码,我们要判断gxhtc3芯片是否存在和正常,就要先读取gxhtc3的ID号,根据gxhtc3的数据手册,读取命…...
期刊论文写作之word模板
一、zotero参考文献使用 下载zotero软件,请搜索相关帖子或者小破站即可; 把pdf拖到zotero软件里面,直接拉进去; 下面建立一个word演示: 1.导入pdf点击红框部分,根据期刊要求选择参考文献样式࿰…...
雷池社区版OPEN API使用教程
OPEN API使用教程 新版本接口支持API Token鉴权 接口文档官方没有提供,有需要可以自行爬取,爬了几个,其实也很方便 使用条件 需要使用默认的 admin 用户登录才可见此功能版本需要 > 6.6.0 使用方法 1.在系统管理创建API TOKEN 2.发…...
LSTM(Long Short-Term Memory,长短期记忆网络)在高端局效果如何
lstm 杂乱数据分析 LSTM(Long Short-Term Memory,长短期记忆网络)在高端局,即复杂的机器学习和深度学习应用中,展现出了其独特的优势和广泛的应用价值。以下是对LSTM在高端局中的详细解析: 一、LSTM的优势…...
模组操作宝典:4种关机重启技巧,让你的设备运行无忧
今天我说的是关于关机重启技巧。 给4G模组VBAT断电关机,模组关机前未能及时退出当前基站,会有什么影响呢? 基站会误以为设备还在线,下次开机仍会拿着上次驻网信息去连基站。基站一看,上次链接还在——认为你是非法设…...
利用API接口实现旺店通和金蝶系统的无缝数据对接
旺店通销售出库对接金蝶销售订单(线下)的技术实现 在企业日常运营中,数据的高效流转和准确对接是确保业务顺畅运行的关键。本文将聚焦于一个具体案例:如何通过轻易云数据集成平台,实现旺店通企业奇门的数据无缝对接到金蝶云星空系统。我们将…...
热题100(hash)
热题100(Hash) 三道题目 1.两数之和(√) 49.字母异位词分组(题解) 128.最长连续序列(题解) 思路 第1题简单hash映射,O(n) 第49题,关键点在于Hashmap的形式,‘HashMap<Stri…...
Ubuntu下Mysql修改默认存储路径
首先声明,亲身经验,自己实践,网上百度了好几个帖子,全是坑,都TMD的不行,修改各种配置文件,就是服务起不来,有以下几种配置文件需要修改 第一个文件/etc/mysql/my.cnf 这个文件是存…...
LVGL移植教程(超详细)——基于GD32F303X系列MCU
版本:LVGL Kernel V8.3.0,运行压力测试Demo Stress首先放一张最终Stress Demo 运行图: 一、准备 1. GD32 Keil工程 准备任意一个屏幕可以正常显示的GD32工程: 2. LVGL源码 最新版现在已经是V9.2了,这里我选择了…...
《计算机原理与系统结构》学习系列——处理器(中)
系列文章目录 目录 流水线数据通路与控制概述5个流水级指令周期与流水级 流水线性能流水线时钟周期的长度T和数量cycles流水线性能 流水线数据通路流水线寄存器流水线分析图形化流水线流水线控制 流水线数据通路与控制 概述 5个流水级 指令周期与流水级 单周期实现中&#x…...
深入解析 OceanBase 数据库中的局部索引和全局索引
深入解析 OceanBase 数据库中的局部索引和全局索引 引言 在分布式数据库中,索引的设计对于优化查询性能至关重要。OceanBase 作为一款高性能的分布式关系数据库,支持局部索引和全局索引两种索引类型。理解这两种索引的特点和适用场景,对于数…...
2024防晒衣市场社媒营销洞察报告
2024年,硬防晒已经从单一的户外场景,扩展到通勤、外出游玩、穿搭等更多场景,多样化的需求导致的消费群体不断扩大,“防晒经济”迎来自己的主场时刻。 当前,防晒衣不仅需要满足不用场景的灵活切换,还要满足多…...
【Ubuntu20.04 Visual Studio Code安装】【VSCODE】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、打开VSCOE官网二、下载VSODE的Ubuntu版本三、安装VSCODE软件包四、导入工作空间(添加工作空间目录)五、安装插件:1.安装简体中文包2.安装ros插件…...
贪心算法day(1)
1.将数组和减半的最少操作次数 链接:. - 力扣(LeetCode) 思路:创建大跟堆将最大的数进行减半 注意点:double t queue.poll()会将queue队列数字减少一个后再除以2,queue.offer(queue.poll()/…...
窗口函数sql使用总结
一、开窗 基础知识:窗口分析函数 (1)LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值 第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往…...
python单因素分析
写了个简易小程序实现,以后用的时候直接复制就行: import numpy as np from scipy.stats import fdatas [[65,60,69,79,38,68,54,67,68,43],[74,71,58,49,58,49,48,68,56,47],[22,34,24,21,20,36,36,31,28,33] ] a 0.05def get_mean_var(data):data_m…...
「C/C++」C++ STL容器库 之 std::list 双向链表容器
✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...
应用程序框架进阶<HarmonyOS第一课>
一、判断题 1. 一个应用是由一个或多个HAP组成。 正确(True) 错误(False) 正确(True) 回答正确 2. UIAbility组件多实例启动模式是默认的启动模式。 正确(True)错误(False) 错误(False) 回答正确 二、单选题 1. 以下关于指定实例启动模式说法正确的是? …...
【C++】vector<string>-动态数组存储多个string
#1024程序员节 | 征文# //demo #include <iostream> #include <vector> #include <string>using namespace std; int main() {// 创建一个存储字符串的向量vector<string> Record;// 向向量中添加字符串Record.push_back("example");Record…...
66Analytics 汉化版,网站统计分析源码,汉化前台后台
66Analytics 汉化版,网站统计分析源码,汉化前台后台 本源码汉化前台后台,非其他只汉化前台版 网络分析变得容易。自托管、友好、一体化的网络分析工具。轻量级跟踪、会话回放、热图、用户旅程等 简单、好看、友好-大多数网络分析解决方案做得太多了,在大…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
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 开发者设计的强大库ÿ…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
