使用ESP-IDF来驱动INMP441全向麦克风
之前的文章我们讲过了I2S。
I2S是什么通信协议?它如何传输音频数据?它和I2C是什么关系?_i2c接口和i2s-CSDN博客文章浏览阅读836次,点赞12次,收藏14次。这个可以参考ADC来理解,我们的ADC也是有左对齐和右对齐的,假设我们的数据是12位的,而传输数据是按照16bit传输的,这时候12bit填不满16bit,我们就需要选择是将数据左对齐还是右对齐了。我们平时打吃鸡可以听声辨位,最主要的原因就是有左右声道,我们左右耳机的声音其实是不一样的,而我们的大脑可以同时处理这两个声道的声音,从而根据声音来判断敌人的位置。我们刚刚说了WS是声道选择线,而WS同时也是帧同步线,它一个周期就表示一帧,而一帧的数据里包含左声道和右声道的数据,所以WS的频率就等于音频的采样率。_i2c接口和i2shttps://blog.csdn.net/m0_63235356/article/details/145260573?spm=1001.2014.3001.5501https://blog.csdn.net/m0_63235356/article/details/145260573?spm=1001.2014.3001.5501https://blog.csdn.net/m0_63235356/article/details/145260573?spm=1001.2014.3001.5501https://blog.csdn.net/m0_63235356/article/details/145260573?spm=1001.2014.3001.5501对协议不太了解的小伙伴可以先去看看
养兵千日用兵一时,我们就是为的今天用I2S来驱动INMP441这个麦克风模块。
当然了,其他音频相关的模块基本用的也都是I2S,所以我们今天就以INMP441为例,来看看如何使用ESP-IDF的I2S。
因为你现在上网一搜ESP32+INMP441,出来的要么是STM32的,要么是用Arduino来编写ESP32的,再要么就是直接把代码给你的。
所以这可能是全网最详细的关于ESP-IDF使用I2S来驱动INMP441模块的文章了(只要你前置定语加的足够多)
接下来我们来看看INMP441的手册来了解了解它。
因为没有官方的中文手册(至少我没找到),所以我用的搜狗翻译机翻了一下(主要是每个月有免费翻译的额度,不用白不用),虽然挺拉的,但我们还是勉强看看。
关注同名公众号“折途想要敲代码”回复关键词“INMP441”即可免费下载所有相关资料
它这边介绍了一下相关的参数,什么信噪比啦,灵敏度啦我们都不用管,我们要注意的就一个,那就是它输出的是24bit的数据。
接下来是WS的频率,我们知道,WS的频率就是声音的采样率,INMP441的采样率是7.8k~50k,一般来说常见的声音采样率是44.1k,所以INMP441是满足要求的。
INMP441一共是有九个引脚,不过模块就引出了六个,看上面表格也可以看的出来,在模块中八号引脚直接永久拉高表示有效。然后GND只需要引出一个即可。
SCK、SD、WS这仨就是I2S用到的线了。
L/R是低电平的时候表示INMP441采集左声道的数据,高电平就是采集右声道的数据。
因为INMP441只能采集一个声道的数据,所以如果我们要采集立体声道的话需要两个INMP441,一个采集左声道一个采集右声道。
上面是描述INMP441三种工作状态的,之所以没放中文版是因为机翻的有错误,比如说2^18翻译成了218,所以小伙伴们私信我下载的中文手册在看的时候还是要结合原版查看的。
当上电之后,INMP441会过2^18个周期之后再正式进入工作模式,所以我们可以通过延时一段时间(100ms左右,具体看SCK的频率)来跳过这一阶段,不跳也可以,但是采集的数据都会是0。
如果光是上电,但是没有时钟信号,那么就会进入待机模式(姑且这么叫吧),恢复时钟信号的时候需要等待2^14个周期(5ms左右,具体看SCK的频率)。
然后我们不能从待机模式直接过渡到关机模式。
关机模式就是把INMP441的使能引脚拉低,如果要恢复工作模式就把使能引脚拉高,然后等待2^17个周期。
不过我们买的INMP441模块没有把使能引脚引出来,所以我们不需要考虑这个。
但如果我们是自己画个板子要用到INMP441这个芯片的话,就可以把使能引脚接到主控芯片上了。
还有一点要注意,那就是不要在没有给INMP441提供VDD的时候给它时钟信号,否则有可能会损坏INMP441。
最后看看上面截的图,是机翻的,勉强看看。
我们要抓的重点就是三个红框框出来的。
首先INMP441发出的格式是24位二进制补码,所以我们拿到手的数据还需要转换一下格式。
第二点是SD数据线需要加一个100k的下拉电阻,关于这一点,拿INMP441芯片焊在自己板子上的小伙伴要注意一下,用模块的话就不需要管这一点了,因为模块上已经集成了一个104的电阻。
最后一个就是如果我们要采集双声道数据,那么使用两个INMP441连线就要参考第三个红框这样。
一个INMP441的L/R接低电平,另一个接高电平,这样每采集一帧数据,WS低电平的时候负责左声道的INMP441发送数据,WS高电平的时候负责右声道的INMP441发送数据,所以两个INMP441共用时钟线和数据线也是没问题的。
以上就是关于INMP441的部分了,剩下是一些跟音频参数相关的,我看不懂,感兴趣的小伙伴自己去看手册。
接下来我们来看看如何使用ESP-IDF的I2S。
I2S - ESP32-S3 - — ESP-IDF 编程指南 release-v5.1 文档https://docs.espressif.com/projects/esp-idf/zh_CN/release-v5.1/esp32s3/api-reference/peripherals/i2s.html#_CPPv419i2s_tdm_slot_mask_thttps://docs.espressif.com/projects/esp-idf/zh_CN/release-v5.1/esp32s3/api-reference/peripherals/i2s.html#_CPPv419i2s_tdm_slot_mask_thttps://docs.espressif.com/projects/esp-idf/zh_CN/release-v5.1/esp32s3/api-reference/peripherals/i2s.html#_CPPv419i2s_tdm_slot_mask_thttps://docs.espressif.com/projects/esp-idf/zh_CN/release-v5.1/esp32s3/api-reference/peripherals/i2s.html#_CPPv419i2s_tdm_slot_mask_t一定要记得选对芯片型号呀呀呀呀呀!!!
上面这个是ESP32S3的。
下面这个是ESP32的(ESP32不仅表示ESP32这类芯片,同时ESP32也是一个具体型号的芯片,这边指的是这个特定型号的芯片)
不同型号的芯片,对于I2S的处理是不一样的。
你们猜我为什么单独拎出来说。
我昨晚折腾了一晚上,然后发现芯片型号没选对,数据处理错误导致串口绘图的数据极其离谱
关于I2S的代码,官方的编程指南里直接就有简单的代码,我们直接复制下来改改就能用,不过我还是像往常一样把相关函数给大家一一讲解一遍吧。
我们看看上面这个状态图,我们要接收来自INMP441的数据,一共需要四步。
第一步是new一个通道,第二步初始化这个通道,第三步使能这个通道,第四步就是读取数据了。
所以我们只需要看上面四个函数就行。
第一步new一个通道。
第一个参数是配置用的结构体。
第二个参数是用来发送数据的通道句柄指针,属于传出参数。
第三个参数是用来发送数据的通道句柄指针,属于传出参数。
如果我们只需要接收数据而不需要发送数据,那么第二个参数可以直接给NULL表示我们不需要配置用来发送数据的通道句柄。
接着可以看看示例代码是怎么处理的。
i2s_chan_handle_t rx_handle;
/* 通过辅助宏获取默认的通道配置
* 这个辅助宏在 'i2s_common.h' 中定义,由所有 I2S 通信模式共享
* 它可以帮助指定 I2S 角色和端口 ID */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
/* 分配新的 TX 通道并获取该通道的句柄 */
i2s_new_channel(&chan_cfg, NULL, &rx_handle);
后两个参数不用说,我们看看第一个参数。
示例代码是使用了一个宏I2S_CHANNEL_DEFAULT_CONFIG来获取到第一个参数。
我们来看看这个宏返回了什么样的东西。
宏也有两个参数,用来配置在了返回的结构体的第一和第二个成员变量上。
配置的分别是使用的I2S资源编号和ESP32S3在I2S总线上扮演的角色。
示例代码中的参数表示自动分配I2S资源以及我们ESP32S3属于主机。
ESP32S3一共有两个I2S资源,I2S0和I2S1,一般我们就用示例代码中的参数,让它自动分配一个就行。
剩下三个参数都是配置DMA的,因为I2S的数据是用DMA来搬运的,不过我们不用管DMA,因为底层都帮我们封装好了。
三个参数的含义依次是使用的DMA的编号,DMA里I2S的数据帧数量,是否自动清理DMA的发送缓冲区。
如果我们I2S采集的数据是24bit的,那么dma_frame_num这个得配置为3的倍数,因为24bit是3Byte,不过它默认配置的240就是3的倍数,所以我们不用管。
DMA缓冲区大小不能超过4092(没错,就是4092),所以这个数据帧数量*3(INMP441一帧数据是24bit,也就是3Byte)不能超过4092。
在这个前提下,我们可以把这个参数配置的越大越好,因为缓冲区大小越大,容纳的数据越多,触发中断的次数也就越少,效率也就越高。
按照我个人的理解就是我们到时候读取数据的时候,一次性读取的数量不要超过这个数,但是实际测试下来好像超过了也没什么问题。
接下来我们进入第二步,初始化这个通道。
参数一传入要配置的通道句柄,我们就把我们刚刚new完的接收句柄传进去,然后参数二是配置用的结构体指针。
我们看看这个结构体。
这个结构体的成员有三个,也都是结构体,从上到下是配置时钟的,配置插槽的(???),配置相关GPIO口的。
我们再次一一查看。
配置时钟的结构体有三个成员,依次是采样率,时钟源,以及MCLK的倍数。
采样率就按照我们的需求来,时钟源就用默认的,这个MCLK在我们之前I2S那篇文章没提到,其实MCLK就是作为整个音频系统的参考时钟,确保所有设备同步工作。
我们使用采集24bit的数据的话,需要把这个MCLK配置为3的倍数,所以我们没得选只能用I2S_MCLK_MULTIPLE_384这个参数。
第二个插槽配置的结构体的成员比较多,不过我们不需要一一去配置。
示例代码里用了一个宏来直接帮我们获取一个配置好的这个结构体。
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_24BIT, I2S_SLOT_MODE_MONO),
然后我们看看这个宏帮我们配置的怎么样了。
然后关于这些参数都是什么意思,我懒得一个个去讲了,我们直接对着下面机翻的图来看吧。
我直接说我们要改的地方,第一个是slot_mask,这边默认是配了个both,实际上我们只用一个INMP441的话只采集一个声道的数据,所以我们这边要改成仅左声道或者是仅右声道。
第二个要改的是bit_order_lsb,是否低位先行,默认是false,也就是高位先行;这边我们改成true,也就是低位先行。
INMP441里面写了它是高位先行,那为什么我们这边要配置为低位先行呢?答案是我也不知道,我只知道配位高位先行的话得到的数据绝对值都非常大,配为低位先行的话会好一些(起码我说话的时候绘制的波形会跟着变动)。
关于这一点,我自己也有很多疑问,所以这边不一定是正确的。
数据不对也有可能是因为我自己数据没处理好,欢迎大家对我后面贴出的代码提出修正的建议。
最后是配置GPIO口的结构体,我们直接按照我们的接线去配置就行。
其中MCLK和DOUT我们不需要,因为我们没有MCLK且只接收数据不发送数据。
初始化完通道,接下来就是使能。
只需要把句柄传进去就行。
最后是读取数据。
参数一是句柄。
参数二是存放我们读取到的数据的地址,是传出参数。
参数三是我们要读取的数据长度,单位字节。
参数四是我们实际读取到的数据长度,是传出参数。
参数五是阻塞时间,会阻塞到我们真的读取到了参数三那么多个数据,可以直接给个portMAX_DELAY
然后我们要注意的是,我们要读取的数据长度得是3的倍数,因为INMP441的数据是24bit的,所以我们需要按照顺序把三个byte拼接起来,由于数据类型没有24bit的,所以我们只能使用32bit的数据类型。
而且INMP441传输的是补码,而实际上音频数据是有正负的,所以我们还需要把补码中是负数的拎出来处理一下(因为正数的补码和原码是一样的,所以不用管)。
处理的方式就是判断一下这个24bit的数据的最高位(也就是符号位)是否为1,为1就是负数,负数就要处理。
处理方式就是把有int32_t的高八位置1,这样就可以了,因为芯片存储数据本身用的也是补码,所以我们只要把24bit和32bit之间差的那8个bit补上1就是,如果是正数的话就补0,但是默认就是0,所以正数不用补。
如果上面一段看不懂的小伙伴可以直接用我下面的示例代码,或者去复习一下计算机原理这门课。
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s_std.h"
#include "driver/gpio.h"
#define INMP_SD 1
#define INMP_SCK 2
#define INMP_WS 3
// 每次读取多少帧数据
#define DATA_LEN 64
i2s_chan_handle_t rx_handle;
void I2S_Init(void){// 通过辅助宏获取默认的通道配置它可以帮助指定 I2S 角色和端口 IDi2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);chan_cfg.dma_frame_num = 1024;// 分配新的 TX 通道并获取该通道的句柄i2s_new_channel(&chan_cfg, NULL, &rx_handle);// 初始化或更新声道和时钟配置i2s_std_config_t std_cfg = {.clk_cfg = {.clk_src = I2C_CLK_SRC_DEFAULT, // 默认时钟.mclk_multiple = I2S_MCLK_MULTIPLE_384,.sample_rate_hz = 44100 // 44.1k采集率},.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_24BIT, I2S_SLOT_MODE_MONO),.gpio_cfg = {.mclk = I2S_GPIO_UNUSED, // 不需要.dout = I2S_GPIO_UNUSED, // 不需要.bclk = INMP_SCK,.ws = INMP_WS,.din = INMP_SD,.invert_flags = { // 都不需要.mclk_inv = false,.bclk_inv = false,.ws_inv = false,},},};std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_LEFT; // 修改为左声道std_cfg.slot_cfg.bit_order_lsb = true; // 低位先行,这边我不确定,但采集的数据确实受环境声音的改变而改变,高位先行却没有/* 初始化通道 */i2s_channel_init_std_mode(rx_handle, &std_cfg);/* 在读取数据之前,先启动 RX 通道 */i2s_channel_enable(rx_handle);
}
void app_main(void){I2S_Init();uint8_t* read_data_buff = (uint8_t*)malloc(sizeof(uint8_t) * 3 * DATA_LEN);size_t len = 0;for(;;){i2s_channel_read(rx_handle, read_data_buff, DATA_LEN * 3, &len, portMAX_DELAY);for(uint16_t i = 0; i < len; i += 3){int32_t real_data = (read_data_buff[i] << 16) | (read_data_buff[i + 1] << 8) | (read_data_buff[i + 2]); // 拼接3个byteif(real_data & 0x00800000) real_data |= 0xFF000000; // 如果是负数,那么由24bit无符号转有符号32bit,需要在前8个bit补上1,也就是FFprintf("%ld\r\n",real_data);}}
}
上面代码把采集到的数据直接打印出来了,我们可以使用SerialPlot这个软件来串口绘图。
先配置串口,一般不用动,串口都是这么配置的。
然后把数据类型改为ASCII,默认是Binary的,但是我们使用printf打印的是ASCII类型。
接着修改下面这些参数来调整xy轴来达到自己想要的效果。
下面是我没发出声音的时候的波形。
下面是我唱歌的时候的波形。
估计是数据没有处理好,没有人家那样很漂亮的声波形状。
相关文章:
使用ESP-IDF来驱动INMP441全向麦克风
之前的文章我们讲过了I2S。 I2S是什么通信协议?它如何传输音频数据?它和I2C是什么关系?_i2c接口和i2s-CSDN博客文章浏览阅读836次,点赞12次,收藏14次。这个可以参考ADC来理解,我们的ADC也是有左对齐和右对…...
C/C++跳动的爱心
系列文章 序号直达链接1C/C李峋同款跳动的爱心2C/C跳动的爱心3C/C经典爱心4C/C满屏飘字5C/C大雪纷飞6C/C炫酷烟花7C/C黑客帝国同款字母雨8C/C樱花树9C/C奥特曼10C/C精美圣诞树11C/C俄罗斯方块小游戏12C/C贪吃蛇小游戏13C/C孤单又灿烂的神14C/C闪烁的爱心15C/C哆啦A梦16C/C简单…...
blender笔记2
一、物体贴地 物体->变换->对齐物体 ->对齐弹窗(对齐模式:反方,相对于:场景原点,对齐:z)。 之后可以设置原点->原点--3d游标 二、面上有阴影 在编辑模式下操作过后,物体面有阴影。 数据-&g…...
关于在mac中配置Java系统环境变量
引言 在 macOS 上开发 Java 或 Flutter 应用时,正确配置环境变量是至关重要的。环境变量不仅能让系统找到开发工具的位置,还能简化命令行操作。本文将手把手教你从零开始安装 Java SDK,并详细配置环境变量,涵盖常见问题解决和优化…...
透彻理解:方差、协方差、相关系数、协方差矩阵及其应用
最近看了几篇跨领域特征对齐方面的经典文献,学者们搞了很多花样,如有的提出一阶统计特征对齐,有的提出二阶统计特征对齐,有的学者提出高阶统计特征对齐。 通俗而言,就是在统计特征层面对跨域特征进行对齐,…...
【SPIE出版,见刊快速,EI检索稳定,浙江水利水电学院主办】2025年物理学与量子计算国际学术会议(ICPQC 2025)
2025年物理学与量子计算国际学术会议(ICPQC 2025)将于2025年4月18-20日在中国杭州举行。本次会议旨在汇聚全球的研究人员、学者和业界专家,共同探讨物理学与量子计算领域的最新进展与前沿挑战。随着量子技术的快速发展,其在信息处…...
jmeter后端监视器的妙用和实现方法
JMeter 的后端监视器(Backend Listener)是一个强大的工具,可用于收集、存储和分析测试过程中的性能指标。它允许将测试数据发送到外部系统(如 InfluxDB、Graphite 等),并借助这些系统的可视化工具ÿ…...
Docker 的安全配置与优化(二)
Docker 安全优化策略 (一)多阶段构建优化镜像大小 多阶段构建是 Docker 17.05 版本引入的强大功能,它允许在一个 Dockerfile 中定义多个构建阶段,每个阶段都可以使用不同的基础镜像和依赖项,最终只将必要的文件和依赖…...
宝塔扩容——阿里云如何操作
一、创建快照 磁盘快照,将数据备份,防止丢失。 1.登录“阿里云”账号 2.点击“控制台”——“云服务器 ECS” 3.点击“基本信息”下,右下角“系统盘” 4.点击“创建快照” 二、磁盘扩容 1.点击“云盘扩容” 2. 选择自己要扩容的大小 …...
vscode settings(一):全局| 用户设置常用的设置项
参考资料 Visual Studio Code权威指南 by 韩骏 一. 全局设置与用户设置 1.1 Vscode支持两种不同范围的设置 用户设置(User Settings):这是一个全局范围的设置,会应用到所有的Visual Studio Code实例中。工作区设置(Workspace Settings):设…...
DeepSeek R1本地+私有云版医疗AI部署开发成功案例技术剖析
1. 引言 1.1 研究背景与意义 随着科技的飞速发展,人工智能(AI)在医疗领域的应用正逐渐成为推动医疗行业变革的重要力量。近年来,医疗 AI 取得了显著的进展,从疾病诊断、药物研发到医疗管理等各个环节,AI 技术都展现出了巨大的潜力。它能够处理和分析海量的医疗数据,为…...
CMOS图像传感器——偏振光图像传感器技术
最近,在索尼官网看到了其提到的偏光图像传感器技术Polarsens,感到好奇,查阅了相关资料,总结如下。。。。 一、偏振光 偏振实际上是光的一种基本属性,表述光电场振动的方向。振动方向和光波前进的方向构成的平面叫振动面。大多数的光源,比如太阳,发出非偏振光,这里我们…...
ROS2 中 TF 变换发布与订阅:实现 base_link 和 test_link 实时可视化显示
视频讲解 ROS2 中 TF 变换发布与订阅:实现 base 安装环境依赖 sudo apt-get install ros-humble-tf2-ros ros-humble-tf2-geometry-msgs ros-humble-tf-transformations 创建一个包名为tf_test_pkg的包 ros2 pkg create --build-type ament_python tf_test_pkg -…...
SQLMesh 系列教程9- 宏变量及内置宏变量
SQLMesh 的宏变量是一个强大的工具,能够显著提高 SQL 模型的动态化能力和可维护性。通过合理使用宏变量,可以实现动态时间范围、多环境配置、参数化查询等功能,从而简化数据模型的开发和维护流程。随着数据团队的规模扩大和业务复杂度的增加&…...
逻辑函数的神经网络实现
1.单层感知器实现基本逻辑函数 先给大家抛出一道例题 (一)种类 a.OR函数 目标:当至少一个输入为1时,输出1;否则输出0。 权重设置: 输入权重:所有 wi1(i1,2,...,m)。…...
链表-基础训练(二)链表 day14
两两交换链表中的节点 题目示意: 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 原先我的思路是图像上的思路,但是我感觉还是很复杂…...
使用大语言模型对接OA系统,实现会议室预定功能
随着人工智能技术的不断进步,越来越多的企业开始借助 AI 助手来提高工作效率,尤其是在日常事务的自动化处理中。比如,在许多公司里,会议室的预定是一个常见且频繁的需求,通常需要员工手动检查空闲时间并做出选择。而通…...
hugging face---transformers包
一、前言 不同于计算机视觉的百花齐放,不同网络适用不同情况,NLP则由Transformer一统天下。transformer是2017年提出的一种基于自注意力机制的神经网络架构,transformers库是hugging face社区创造的一个py库,通过该库可以实现统一…...
1. 自定义组件基础
相关资源: 📎day10 图片素材.zip 1. 自定义组件基础 概念:在ArkUI中由框架直接提供的称为系统组件 -> Column,Button等,由开发者定义的称为自定义组件 作用:自定义组件可以对 UI和业务逻辑进行封装&…...
连接Sql Server时报错无法通过使用安全套接字层加密与 SQL Server 建立安全连接
文章目录 一. 前言二. 解决方案 方案1方案2 三. 总结 一. 前言 在《数据库原理》这门课的实验上,需要使用SQL Server,然后使用jdbc连接sql server突然报错为:SQLServerException: “Encrypt”属性设置为“true”且 “trustServerCertific…...
python使用httpx_sse调用sse流式接口对响应格式为application/json的错误信息的处理
目录 问题描述方案 问题描述 调用sse流式接口使用httpx_sse的方式 import httpxfrom httpx_sse import connect_sse# 省略无关代码try:with httpx.Client() as client:with connect_sse(client, "GET", url, paramsparam) as event_source:clear_textbox(response_t…...
R 语言科研绘图 --- 散点图-汇总
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
【语音科学计算器】当前汇率
JSON_MARKER_HORN{“base”:“USD”,“rates”:{“EUR”:0.9758,“JPY”:157.68,“GBP”:0.8190,“CNY”:7.3327,“HKD”:7.7872,“AUD”:1.6260,“CAD”:1.4422,“CHF”:0.9157,“SGD”:1.3714,“KRW”:1473.05,“NZD”:1.7992,“THB”:34.54,“MYR”:4.4930,“PHP”:57.32,“…...
python 进程池的基本使用
Python 进程池:Pool任务调度实现 在现代计算机系统重,处理器核心数量的增加为并行计算提供了强大的硬件基础。Python的 multiprocessing 模块中的进程池(Pool)机制,为开发者提供了 一个高效且易用的并行处理框架。 通…...
初识XML
初识XML <?xml version"1.0" encoding"utf-8" ?> <!--根标签只能有一个--> <!--第一行永远都是 <?xml version"1.0" encoding"utf-8" ?> 前面不允许出现任何其他东西,空格换行等均不行 --> &…...
VisActor/VTable - 快速搭建表格
VTable源于VisActor体系,该体系是从字节跳动大量可视化场景沉淀而来,旨在提供面向叙事的智能可视化解决方案。VisActor包括渲染引擎、可视化语法、数据分析组件、图表组件、表格组件、GIS组件、图可视化组件、智能组件等多个模块,以及周边生态…...
网络安全营运周报
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 第三章网络安全基础 一、网络安全概述 1、网络安全现状及安全挑战 网络安全范畴极其广泛,可以说是涉及多方面。 因为计算机病毒层出不穷以及黑客的…...
网络运维学习笔记 017 HCIA-Datacom综合实验01
文章目录 综合实验1实验需求总部特性 分支8分支9 配置一、 基本配置(IP二层VLAN链路聚合)ACC_SWSW-S1SW-S2SW-Ser1SW-CoreSW8SW9DHCPISPGW 二、 单臂路由GW 三、 vlanifSW8SW9 四、 OSPFSW8SW9GW 五、 DHCPDHCPGW 六、 NAT缺省路由GW 七、 HTTPGW 综合实…...
【Viewer.js】vue3封装图片查看器
效果图 需求 点击图片放大可关闭放大的 图片 下载 cnpm in viewerjs状态管理方法 stores/imgSeeStore.js import { defineStore } from pinia export const imgSeeStore defineStore(imgSeeStore, {state: () > ({showImgSee: false,ImgUrl: ,}),getters: {},actions: {…...
hot100_108. 将有序数组转换为二叉搜索树
hot100_108. 将有序数组转换为二叉搜索树 思路 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。 示例 1: 输入:nums [-10,-3,0,5,9] 输出:[0,-3,9,-10,null,5] 解释&#…...
给小米/红米手机root(工具基本为官方工具)——KernelSU篇
目录 前言准备工作下载刷机包xiaomirom下载刷机包【适用于MIUI和hyperOS】“hyper更新”微信小程序【只适用于hyperOS】 下载KernelSU刷机所需程序和驱动文件 开始刷机设置手机第一种刷机方式【KMI】推荐提取boot或init_boot分区 第二种刷机方式【GKI】不推荐 结语 前言 刷机需…...
(四)趣学设计模式 之 原型模式!
目录 一、 啥是原型模式?二、 为什么要用原型模式?三、 原型模式怎么实现?四、 原型模式的应用场景五、 原型模式的优点和缺点六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式…...
Linux 命令大全完整版(08)
3. 文档编辑命令 joe 功能说明:编辑文本文件。语 法:joe [-asis][-beep][-csmode][-dopadding][-exask][-force][-help][-keepup][-lightoff][-arking][-mid][-nobackups][-nonotice][-nosta][-noxon][-orphan][-backpath<目录>][-columns<…...
【DeepSeek-R1背后的技术】系列十一:RAG原理介绍和本地部署(DeepSeek+RAGFlow构建个人知识库)
【DeepSeek-R1背后的技术】系列博文: 第1篇:混合专家模型(MoE) 第2篇:大模型知识蒸馏(Knowledge Distillation) 第3篇:强化学习(Reinforcement Learning, RL)…...
[python脚本]论文1.(一)CPU/内存数据分析和分组
CPU 收集到的CPU数据,格式如下: 由于这里6个数据为一组来收集latency的数据以及各个分位值的数据,而本质上每一行都是一次完整的测试,因此这里将这个csv文件分为两个文件,第一个是和latency相关的,将6条数…...
git - 从一个远端git库只下载一个文件的方法
文章目录 git - 从一个远端git库只下载一个文件的方法概述笔记写一个bash脚本来自动下载get_github_raw_file_from_url.shreanme_file.shfind_key_value.sh执行命令 END git - 从一个远端git库只下载一个文件的方法 概述 github上有很多大佬上传了电子书库,如果只…...
【C++】list 链表的使用+模拟实现
目录 文章目录 前言 一、list的简介 二、list的使用方法 三、list的模拟实现 1.基本框架: 2.迭代器实现 3.常用接口实现 四、完整代码 总结 前言 本文主要介绍C【STL】容器中的 list,包括接口说明和模拟实现。其中讲解了迭代器功能上的分类&am…...
@Configuration与 @Component的差异
继承关系 Configuration确实可以视为Component的派生注解。从源码层面来看,Configuration本身通过元注解方式标记了Component,这意味着所有被Configuration注解的类本质上也会被Spring识别为组件(Component)。这种设计使得Config…...
c++第一课(基础c)
目录 1.开场白 2.char(字符) 3.字符数组 4.ASCII码 1.开场白 OK,咱们也是亿(不是作者故意的)天没见,话不多说,直接开始! 2.char(字符) 众所不周知&…...
element ui的time时间和table表格
<el-date-picker v-model"value1" align"right" type"date" placeholder"选择日期" value-format"yyyy-MM-dd" change"changeDate"></el-date-picker><el-date-picker v-model"datetime"…...
安装 tensorflow 遇到的问题
Q1: 没发现满足需求的版本 ERROR: Could not find a version that satisfies the requirement keras-nightly~2.5.0.dev (from tensorflow) (from versions: none) ERROR: No matching distribution found for keras-nightly~2.5.0.dev 按照官方文档Installation — TensorFl…...
音视频封装格式:多媒体世界的“容器”与“桥梁”
一、音视频封装格式的核心概念 音视频封装格式(容器)是一种将编码后的视频、音频、字幕等数据按规则整合的文件格式,其本质是多媒体数据容器,核心作用包含: 同步多轨道数据:通过时间戳(PTS/DTS)实现音画同步。组织数据流:统一管理视频流、音频流、字幕流等,并存储元…...
【学习资料】嵌入式人工智能Embedded AI
图片来源: Embedded Artificial Intelligence for Business Purposes | DAC.digital 随着AI在设备端的应用,我们看到越来越多的可穿戴设备出现以及自动驾驶汽车的发展,可以看到嵌入式人工智能是新的发展方向。我为大家介绍嵌入式人工智能的…...
Linux命令大全完整版
1. linux 系统管理命令 adduser 功能说明:新增用户帐号。语 法:adduser补充说明:在 Slackware 中,adduser 指令是个 script 程序,利用交谈的方式取得输入的用户帐号资料,然后再交由真正建立帐号的 use…...
红队内网攻防渗透:内网渗透之内网对抗:实战项目VPC2打靶父子域三层路由某绒免杀下载突破约束委派域控提权
红队内网攻防渗透 实战网络攻防靶场记录1.靶机配置信息讲解2.靶场渗透完整流程2.1 入口点:192.168.139.130(win2008 R2)2.1.1 tomcat后台war包获取权限2.1.2 tomcat使用后门上线CS平台2.1.3 信息收集获取数据库密码2.2 入口点横向:192.168.10.11 (win2012 SQL)2.2.1 SQLs…...
always和assign语法区别
always语句可以带时钟, 也可以不带时钟。 一,assign和always区别 assign 语句使用时不能带时钟。 assign a=1; assign b=2; 在always不带时钟时,逻辑功能和assign完全一致,都是只产生组合逻辑。比较简单的组合逻辑推荐使用assign语句,比较复杂的组合逻辑推荐使用 al…...
深入了解ThreadLocal底层原理-高并发架构
目录 什么是ThreadLocal应用场景需求实现 ThreadLocal核心源码解读Thread 、ThreadLocal、ThreadLocalMap 三者的关系 四大引用-强软弱虚类型ThreadLocal内存泄漏ThreadLocal为什么需要设计成弱引用?并且ThreadLocal用完需要remove呢?原因 什么是ThreadL…...
《AI与NLP:开启元宇宙社交互动新纪元》
在科技飞速发展的当下,元宇宙正从概念逐步走向现实,成为人们关注的焦点。而在元宇宙诸多令人瞩目的特性中,社交互动体验是其核心魅力之一。人工智能(AI)与自然语言处理(NLP)技术的迅猛发展&…...
基于vue和微信小程序的校园自助打印系统(springboot论文源码调试讲解)
第3章 系统设计 3.1系统功能结构设计 本系统的结构分为管理员和用户、店长。本系统的功能结构图如下图3.1所示: 图3.1系统功能结构图 3.2数据库设计 本系统为小程序类的预约平台,所以对信息的安全和稳定要求非常高。为了解决本问题,采用前端…...
电脑开机一段时间就断网,只有重启才能恢复网络(就算插网线都不行),本篇文章直接解决,不要再看别人的垃圾方法啦
下面的是我解决问题的心路历程,不想看的可以直接跳到解决方法上面! 内心思路: w11电脑更新过系统后,我的电脑是常年不关机的,但是一天突然断网,试了很多方法都连不上,重启电脑就会好࿰…...