M5ATOMS3基础02传感器MPU6886
M5ATOMS3基础01按键
简洁版本
MPU6886是一款6轴IMU单元,具有3轴重力加速度计和3轴陀螺仪。它采用16位ADC,内置可编程数字滤波器和片上温度传感器,并通过I2C接口(地址为0x68)与上位机通信。MPU6886支持低功耗模式,并具有高性能规格,包括陀螺仪灵敏度误差±1%、陀螺仪噪声±4 mdps/√Hz、加速度计噪声100 μg/√Hz等。此外,它还支持EIS同步,可以应用于可穿戴设备、运动跟踪、无人机姿态确定、智能手机和平板电脑、物联网应用、基于运动的游戏控制器,以及用于互联网连接的DTV和机顶盒、3D鼠标等领域。
详细介绍:
(MPU6886)6轴IMU单元是带有3轴重力加速度计和3轴陀螺仪的6轴姿态传感器,可以实时计算倾斜角度和加速度。该芯片采用mpu6886,具有16位ADC,内置可编程数字滤波器和片上温度传感器,采用I2C接口(addr:0x68)与上位机通信,并支持低功耗模式。
产品特性
- 3轴重力加速度计和3轴陀螺仪
- 片上温度传感器
- 1KB 先进先出
- 支持低功耗
开发平台:Arduino,uiflow(块状,python)
-高性能规格:
- 陀螺仪灵敏度误差:±1%
- 陀螺仪噪声:±4 mdps/√Hz
- 加速度计噪声:100 μg/√Hz
- 支持 EIS 同步
-产品应用
- 可穿戴设备
- 运动跟踪
- 无人机姿态确定
- 智能手机和平板电脑
- 物联网应用
- 基于运动的游戏控制器
- 用于互联网连接 DTV 和机顶盒,3D鼠标
M5AtomS3官方示例代码:
/*
*******************************************************************************
* Copyright (c) 2021 by M5Stack
* Equipped with AtomS3 sample source code
* 配套 AtomS3 示例源代码
* Visit for more information: https://docs.m5stack.com/en/core/AtomS3
* 获取更多资料请访问:https://docs.m5stack.com/zh_CN/core/AtomS3
*
* Describe: MPU6886. 姿态传感器示例
* Date: 2022/12/19
*******************************************************************************
*/
#include "M5AtomS3.h"/* After AtomS3 is started or reset the program in the setUp ()
function will be run, and this part will only be run once.
在 AtomS3 启动或者复位后,即会开始执行setup()函数中的程序,该部分只会执行一次。
*/
void setup() {M5.begin(true, true, true,false); // Init AtomS3(Initialize LCD, serial port).// 初始化 AtomS3(初始化LCD、串口)M5.IMU.begin(); // Init IMU sensor. 初始化姿态传感器USBSerial.printf("whoAmI() = 0x%02x\n", M5.IMU.whoAmI());
}/* After the program in setup() runs, it runs the program in loop()
The loop() function is an infinite loop in which the program runs repeatedly
在setup()函数中的程序执行完后,会接着执行loop()函数中的程序
loop()函数是一个死循环,其中的程序会不断的重复运行 */
float ax, ay, az, gx, gy, gz, t;
void loop() {M5.Lcd.setCursor(0, 40);M5.Lcd.clear(); // Delay 100ms 延迟100msM5.IMU.getAccel(&ax, &ay, &az); // Read tri-axial accel 读取三轴加速度M5.IMU.getGyro(&gx, &gy, &gz); // Read gyroscope data 读取陀螺仪数据M5.IMU.getTemp(&t); // Read temperature data 读取温度数据USBSerial.printf("%f,%f,%f,%f,%f,%f,%f\n", ax, ay, az, gx, gy, gz,t); // serial port output the formatted string. 串口输出M5.Lcd.printf("IMU:\r\n");M5.Lcd.printf("%0.2f %0.2f %0.2f\r\n", ax, ay, az);M5.Lcd.printf("%0.2f %0.2f %0.2f\r\n", gx, gy, gz);delay(500);
}
arduino中获取MPU6886常规代码如下:
#include <Wire.h> #define MPU6886_ADDRESS 0x68 byte int16_array[14] ;
float posture[3] ; void setup() { Wire.begin(); Wire.beginTransmission(MPU6886_ADDRESS); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (reset) Wire.endTransmission(false); Serial.begin(9600);
} void loop() { Wire.beginTransmission(MPU6886_ADDRESS); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU6886_ADDRESS, 14, true); // request 14 bytes of data for (int i = 0; i < 14; i++) { // read data into array int16_array[i] = Wire.read() << 8 | Wire.read(); } posture[0] = (float)int16_array[0] / 16384.0; // convert x-axis acceleration data to float posture[1] = (float)int16_array[1] / 16384.0; // convert y-axis acceleration data to float posture[2] = (float)int16_array[2] / 16384.0; // convert z-axis acceleration data to float Serial.print("Posture X: "); Serial.print(posture[0]); Serial.print(" | Y: "); Serial.print(posture[1]); Serial.print(" | Z: "); Serial.println(posture[2]); delay(100);
}
这个示例代码通过I2C接口与MPU6886通信,并读取加速度和角速度数据,然后将其转换为浮点数并输出到串口监视器中。在设置中,通过Wire.beginTransmission()和Wire.endTransmission()函数设置MPU6886的地址,并将其重置为默认设置。在循环中,通过Wire.requestFrom()函数从MPU6886请求数据,并将其读取到一个字节数组中。然后,将加速度数据转换为浮点数,并将其存储在一个浮点数数组中,最后将数据输出到串口监视器中。在示例代码中,延迟100毫秒,以便以适当的速率读取传感器数据。
简要解析:
IMU
新代码如下:
M5.IMU.getAccel(&ax, &ay, &az); // Read tri-axial accel 读取三轴加速度M5.IMU.getGyro(&gx, &gy, &gz); // Read gyroscope data 读取陀螺仪数据M5.IMU.getTemp(&t); // Read temperature data 读取温度数据
具体如何实现?
MPU6886.h
#ifndef __MPU6886_H__
#define __MPU6886_H__#include <Wire.h>#define MPU6886_DEFAULT_ADDRESS 0x68class MPU6886 {public:MPU6886(uint8_t deviceAddress = MPU6886_DEFAULT_ADDRESS,TwoWire& i2cPort = Wire1);int begin(void);uint8_t whoAmI();void getAccel(float* ax, float* ay, float* az);void getGyro(float* gx, float* gy, float* gz);void getTemp(float* t);private:uint8_t readByte(uint8_t address);void writeByte(uint8_t address, uint8_t data);void bitOn(uint8_t address, uint8_t bit);void bitOff(uint8_t address, uint8_t bit);TwoWire* _i2cPort;int _deviceAddress;
};#endif
MPU6886.c
#include "MPU6886.h"MPU6886::MPU6886(uint8_t deviceAddress, TwoWire& i2cPort) {_deviceAddress = deviceAddress;_i2cPort = &i2cPort;
}uint8_t MPU6886::readByte(uint8_t address) {_i2cPort->beginTransmission(_deviceAddress);_i2cPort->write(address);_i2cPort->endTransmission();_i2cPort->requestFrom(_deviceAddress, 1);uint8_t val = _i2cPort->read();ESP_LOGD("MPU6886", "readByte(%02X) = %02X", address, val);return val;
}void MPU6886::writeByte(uint8_t address, uint8_t data) {_i2cPort->beginTransmission(_deviceAddress);_i2cPort->write(address);_i2cPort->write(data);_i2cPort->endTransmission();ESP_LOGD("MPU6886", "writeByte(%02X) = %02X", address, data);
}void MPU6886::bitOn(uint8_t address, uint8_t bit) {uint8_t add = address;uint8_t val = readByte(add) | bit;writeByte(add, val);
}void MPU6886::bitOff(uint8_t address, uint8_t bit) {uint8_t add = address;uint8_t val = readByte(add) & ~bit;writeByte(add, val);
}int MPU6886::begin(void) {// WHO_AM_I : IMU Checkif (whoAmI() != 0x19) {return -1;}delay(1);// PWR_MGMT_1(0x6b)writeByte(0x6b, 0x00);delay(10);// PWR_MGMT_1(0x6b)writeByte(0x6b, 1 << 7);delay(10);// PWR_MGMT_1(0x6b)writeByte(0x6b, 1 << 0);delay(10);// ACCEL_CONFIG(0x1c) : +-8GwriteByte(0x1c, 0x10);delay(1);// GYRO_CONFIG(0x1b) : +-2000dpswriteByte(0x1b, 0x18);delay(1);// CONFIG(0x1a)writeByte(0x1a, 0x01);delay(1);// SMPLRT_DIV(0x19)writeByte(0x19, 0x05);delay(1);// INT_ENABLE(0x38)writeByte(0x38, 0x00);delay(1);// ACCEL_CONFIG 2(0x1d)writeByte(0x1d, 0x00);delay(1);// USER_CTRL(0x6a)writeByte(0x6a, 0x00);delay(1);// FIFO_EN(0x23)writeByte(0x23, 0x00);delay(1);// INT_PIN_CFG(0x37)writeByte(0x37, 0x22);delay(1);// INT_ENABLE(0x38)writeByte(0x38, 0x01);delay(100);return 0;
}uint8_t MPU6886::whoAmI(void) {return readByte(0x75);
}void MPU6886::getAccel(float* ax, float* ay, float* az) {float aRes = 8.0 / 32768.0;*ax = (int16_t)((readByte(0x3b) << 8) | readByte(0x3c)) * aRes;*ay = (int16_t)((readByte(0x3d) << 8) | readByte(0x3e)) * aRes;*az = (int16_t)((readByte(0x3f) << 8) | readByte(0x40)) * aRes;
}void MPU6886::getGyro(float* gx, float* gy, float* gz) {float gRes = 2000.0 / 32768.0;*gx = (int16_t)((readByte(0x43) << 8) | readByte(0x44)) * gRes;*gy = (int16_t)((readByte(0x45) << 8) | readByte(0x46)) * gRes;*gz = (int16_t)((readByte(0x47) << 8) | readByte(0x48)) * gRes;
}void MPU6886::getTemp(float* t) {*t = 25.0 + ((readByte(0x41) << 8) | readByte(0x42)) / 326.8;
}
都是一些固定流程。底层代码类似驱动,规范性是很重要的。
修改:
下段代码是一个使用ESP32-S3开发板的程序,通过连接M5AtomS3库来进行传感器数据的读取和显示。
代码主要包括两个函数:setup()
和loop()
。
setup()
函数是程序启动后首先执行的函数,它进行一些初始化的操作,包括初始化AtomS3(LCD和串口)和IMU传感器,然后延迟100毫秒,最后通过USB串口输出IMU传感器的信息。
loop()
函数是一个死循环,其中的程序会不断的重复运行。在每次循环中,程序通过M5AtomS3库的函数读取IMU传感器的数据,包括三轴加速度、陀螺仪数据和温度数据。然后通过USB串口输出这些数据,并在LCD屏幕上显示IMU传感器的信息,包括加速度、陀螺仪和温度。每次循环后,程序会延迟20毫秒。
整体来说,这段代码的功能是不断读取并显示IMU传感器的数据,包括加速度、陀螺仪和温度,并通过串口输出。同时,它还在LCD屏幕上显示了IMU传感器的信息。
#include "M5AtomS3.h"/* After AtomS3 is started or reset the program in the setUp ()
function will be run, and this part will only be run once.
在 AtomS3 启动或者复位后,即会开始执行setup()函数中的程序,该部分只会执行一次。
*/
void setup() {M5.begin(true, true, true,false); // Init AtomS3(Initialize LCD, serial port).// 初始化 AtomS3(初始化LCD、串口)M5.IMU.begin(); // Init IMU sensor. 初始化姿态传感器M5.Lcd.clear(); // Delay 100ms 延迟100msUSBSerial.printf("whoAmI() = 0x%02x\n", M5.IMU.whoAmI());
}/* After the program in setup() runs, it runs the program in loop()
The loop() function is an infinite loop in which the program runs repeatedly
在setup()函数中的程序执行完后,会接着执行loop()函数中的程序
loop()函数是一个死循环,其中的程序会不断的重复运行 */
float ax, ay, az, gx, gy, gz, t;
void loop() {M5.Lcd.setCursor(0, 40);M5.IMU.getAccel(&ax, &ay, &az); // Read tri-axial accel 读取三轴加速度M5.IMU.getGyro(&gx, &gy, &gz); // Read gyroscope data 读取陀螺仪数据M5.IMU.getTemp(&t); // Read temperature data 读取温度数据USBSerial.printf("%f,%f,%f,%f,%f,%f,%f\n", ax, ay, az, gx, gy, gz,t); // serial port output the formatted string. 串口输出M5.Lcd.printf("IMU:Accel\r\n");M5.Lcd.printf("%0.2f %0.2f %0.2f\r\n", ax, ay, az);M5.Lcd.printf("IMU:Gyro\r\n");M5.Lcd.printf("%0.2f %0.2f %0.2f\r\n", gx, gy, gz);M5.Lcd.printf("IMU:Temp\r\n");M5.Lcd.printf("%0.2f \r\n", t);delay(20);
}
为何做这样的修改呢?其实串口部分代码也可以去掉。
调试结果:
很明显温度等不太合适嘛?
AI给出注意事项如下:
在使用MPU6886传感器连接到ESP32单片机时,需要注意以下事项:
- 硬件连接:确保将MPU6886正确连接到ESP32单片机。这涉及到正确连接电源、I2C总线和地线。
- I2C通信:确认MPU6886的I2C地址正确设置,并在ESP32单片机的程序中正确配置I2C总线。
- 供电要求:MPU6886的电压范围为2.5V至5.5V。确保提供适当的电源,并注意电源稳定性。
- 数据处理:对于读取的数据,需要正确解释和校正。例如,加速度数据需要进行温度补偿和偏移校正,以获得更准确的结果。
- 休眠模式:ESP32单片机可以通过将MPU6886的电源引脚拉低来将其置于休眠模式,以降低功耗。
- 数据输出:确认MPU6886的数据输出格式,例如16位或32位,并根据需要对其进行处理。
- 温度补偿:使用MPU6886时,需要注意温度对加速度计和陀螺仪的影响。需要进行温度补偿以获得更准确的数据。
- 陀螺仪校准:在使用MPU6886之前,需要对陀螺仪进行校准。这可以通过在静态条件下运行陀螺仪一段时间来进行。
- 数据滤波:为了减少噪声和干扰,可以在数据读取和处理过程中应用滤波技术,例如低通滤波或卡尔曼滤波。
- 更新频率:根据应用需要,可以设置MPU6886的更新频率。例如,对于需要高频率数据的应用,可以增加更新频率。
以上是使用MPU6886连接到ESP32单片机时的一些注意事项。根据具体应用和硬件配置,可能还有其他需要注意的事项。建议参考相关文档和资料,以确保正确和可靠的使用。
背景知识点:
MPU6886和MPU6050都是六轴惯性测量单元(IMU),用于测量姿态、加速度和角速度等运动参数。它们的主要区别在于芯片结构和连接方式。
MPU6886采用I2C接口,内置了3轴加速度计和3轴陀螺仪,并提供了数字运动处理器(DMP)和可编程数字滤波器。它采用2.5V至5.5V的电源供应,具有低功耗模式,并支持快速唤醒。MPU6886的主要特点包括高精度、低功耗、快速启动和低噪声。
MPU6050是一个整合感应器,内含3轴加速度计和3轴陀螺仪,采用I2C接口。它具有131 LSBs/°的角速度全格感测范围,并内置了数字运动处理器(DMP)。MPU6050的工作电压为2.5V至5.5V,具有低功耗模式,并能唤醒快速。主要特点包括高精度、低功耗、快速启动和低噪声。
总体而言,MPU6886和MPU6050在功能和性能上非常相似,都具有高精度、低功耗、快速启动和低噪声等特点。主要区别在于连接方式和芯片结构。具体选择哪个取决于具体应用的需求和预算。
ESP32-S3是一款基于Xtensa LX7架构的32位Wi-Fi SoC,具有高性能和低功耗的特点。它集成了2.4 GHz Wi-Fi、蓝牙和NFC功能,并提供了丰富的外设接口,如SD卡接口、ADC、DAC、SPI、I2C、UART等。ESP32-S3还支持神经网络加速器和TensorFlow Lite,可用于机器学习和人工智能应用。
以下是ESP32-S3的一些主要特点:
- Xtensa LX7 32位处理器,最高主频可达240 MHz。
- 2.4 GHz Wi-Fi和蓝牙双模芯片,支持802.11 b/g/n和蓝牙5.0。
- 内置NFC功能,可实现近场通信。
- 低功耗设计,可支持多种电源供电方式,包括1.8V、3.3V和1.2V。
- 集成了32 KB SRAM和32 KB ROM。
- 支持SD卡接口,可用于存储和读取数据。
- 提供丰富的外设接口,如ADC、DAC、SPI、I2C、UART等。
- 支持神经网络加速器和TensorFlow Lite,可用于机器学习和人工智能应用。
ESP32-S3适用于各种物联网应用,如智能家居、智能城市、智能医疗、工业自动化等。它具有高性能、低功耗和丰富的外设接口,可为各种应用提供可靠的解决方案。
相关文章:

M5ATOMS3基础02传感器MPU6886
M5ATOMS3基础01按键 简洁版本 MPU6886是一款6轴IMU单元,具有3轴重力加速度计和3轴陀螺仪。它采用16位ADC,内置可编程数字滤波器和片上温度传感器,并通过I2C接口(地址为0x68)与上位机通信。MPU6886支持低功耗模式&#…...

vue 快速自定义分页el-pagination
vue 快速自定义分页el-pagination template <div style"text-align: center"><el-paginationbackground:current-page"pageObj.currentPage":page-size"pageObj.page":page-sizes"pageObj.pageSize"layout"total,prev,…...

0-虚拟机补充知识
虚拟机克隆 如果想要构建服务器集群,没有必要一台一台的去进行安装,只要通过克隆就可以。 快速获得多台服务器主要有两种方式,分别为:直接拷贝操作和vmware的克隆操作 直接拷贝 将之前安装虚拟机的所有文件进行拷贝࿰…...
如何将电机控制器添加到您的 ROS 机器人
一、说明 如果您正在构建与 ROS/ROS2 一起使用的移动机器人,您需要做的第一件事就是集成电机控制器。电机控制器的目的是接受来自更高级别的软件(如导航堆栈)的消息,并将其转换为驱动电机的信号。它还将从电机的编码器接收信息,以计算机器人的速度和位置。 您可以…...

ChatGPT统计“一到点就下班”的人数
ChatGPT统计“一到点就下班”的人数 1、到点下班 Chatgpt统计各部门F-D级员工到点下班人数占比,是在批评公司内部存在到点下班现象。 根据图片,该占比的计算方法是:最后一次下班卡在17:30-17:40之间,且1-5月合计有40天以上的人…...

Games101学习笔记 - 变换矩阵基础
二维空间下的变换 缩放矩阵 缩放变换: 假如一个点(X,Y)。x经过n倍缩放,y经过m倍缩放,得到的新点(X1,Y1);那么新点和远点有如下关系,X1 n*X, Y1 m*Y写成矩阵就是如下…...

Ubuntu18.04未安装Qt报qt.qpa.plugin could not load the Qt platform plugin xcb问题的解决方法
在Ubuntu 18.04开发机上安装了Qt 5.14.2,当将其可执行程序拷贝到另一台未安装Qt的Ubuntu 18.04上报错:拷贝可执行程序前,使用ldd将此执行程序依赖的动态库也一起拷贝过去,包括Qt5.14.2/5.14.2/gcc_64/plugins目录系的platforms目录…...

GPT4ALL私有化部署 01 | Python环境
进入以下链接: https://www.python.org/downloads/release/python-3100/ 滑动到底部 选择你系统对应的版本,如果你是win,那么大概率是win-64bit 有可能你会因为网络的问题导致下载不了,我提供了 链接 接着只需要打开 等待…...

GPT-AI 使用的技术概览
ChatGPT 使用的技术概览 智心AI-3.5/4模型,联网对话,MJ快速绘画 从去年 OpenAI 发布 ChatGPT 以来,AI 的能力再次惊艳了世人。在这样的一个时间节点,重新去学习相关技术显得很有必要。 ChatGPT 的内容很多,我计划采用…...

NoSQL-Redis持久化
NoSQL-Redis持久化 一、Redis 高可用:1.概述: 二、Redis持久化:1.持久化的功能:2.Redis 提供两种方式进行持久化: 三、RDB 持久化:1.定义:2.触发条件:3.执行流程:4.启动时…...

关于uniapp中的日历组件uni-calendar中的小红点
关于uniapp中的日历组件uni-calendar中的小红点 如果你使用过uni-calendar组件,可能你觉得这个小红点有点碍眼,但是官方给定的日历组件uni-calendar中如果你想要在某一天上添加一些信息例如:价格,签到,打卡之类,只要标…...

【Nodejs】Node.js简介
1.前言 Node 的重要性已经不言而喻,很多互联网公司都已经有大量的高性能系统运行在 Node 之上。Node 凭借其单线程、异步等举措实现了极高的性能基准。此外,目前最为流行的 Web 开发模式是前后端分离的形式,即前端开发者与后端开发者在自己喜…...

SpringBoot整合Druid
在Spring Boot中整合Druid时,需要导入Druid和JDBC的相关依赖,但不需要额外导入单独的JDBC包。 Druid是一个用于数据库连接池和监控的开源框架,它已经包含了对JDBC的实现。因此,当你导入Druid的依赖时,它已经包含了对J…...

mysql(二)SQL语句
目录 一、SQL语句类型 二、数据库操作 三、数据类型 四、创建 五、查看 六、更改 七、增、删、改、查 八、查询数据 一、SQL语句类型 SQL语句类型: DDL DDL(Data Definition Language,数据定义语言):用于…...

Unity自定义后处理——Tonemapping色调映射
大家好,我是阿赵。 继续介绍屏幕后处理,这一期介绍一下Tonemapping色调映射 一、Tone Mapping的介绍 Tone Mapping色调映射,是一种颜色的映射关系处理,简单一点说,一般是从原始色调(通常是高动态范围&…...
Redis学习 知识总结 一
Redis学习 知识总结 一 1 Redis初识1.1 Redis八大特性1.2 redis使用场景1.3 Docker安装redis 2 API的理解和使用2.1 通用命令2.2 字符串(String)类型2.3 哈希(Hash)类型2.4 有序列表(list)2.5 集合…...
Webpack5 vue-loader和VueLoaderPlugin
文章目录 vue-loader和VueLoaderPlugin的作用vue-loader具体使用方式注意事项 vue-loader和VueLoaderPlugin的作用 .vue 文件是用户用 HTML-like 的语法编写的 Vue 组件。每个vue 文件都包括三部分 , VueLoaderPlugin 是一个解析 Vue.js 的插件,用于在 webpack 构…...
【传统视觉】模板匹配和卡尺圆检测
模板匹配 粗定位 1、原理:模板匹配是指在当前图像A中匹配与图像B最相似的部分,那么A为输入图像,B为模板图像。 2、匹配方法:B在A上华东,逐个遍历所有像素完成匹配。 3、函数: result cv2.matchTemplate(…...

记一次简单的MySql注入试验
试验环境: 1.已经搭建好的php服务器,并可以通过访问到localhost/index.php; 2.已经安装好数据库,并创建表test,表内有name、age等字段,并随便创建几个假数据用于测试;如图: 开始测…...

软考开发思考(完善中)
软考开发思考 文章目录 软考开发思考1. 互联网媒体:新技术和新应用及当前的趋势和应用1.1 自动化报道1.2. 虚拟和增强现实1.3. 数据新闻1.4. 即时新闻推送1.5 智能助手和聊天机器人1.6 语音播报,语音检索,后台播放、播放倍速。1.6 机器人交互…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...