锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

#STM32学习#6D加速度传感器测量风机震动

时间:2022-11-05 13:00:00 14加速度传感器二向高g值加速度传感器lis3dh陀螺仪传感器3110加速度传感器3f振动速度传感器采用3轴加速度传感器

1、背景:

需要监控风扇的启动和停止,希望通过测量其振动频率来辅助判断。

2、传感器

如下图所示,传统的振动传感器有两个缺点:一是测量精度低,对小振动不敏感;二是分频信号无法测量。

选择使用LSM6DSL加速度/角速度传感器。传感器所在的板是X-NUCLEO-IKSO1A2.如下图所示。

LSM6DSL三轴方向的加速度和角速度可以测量,我们只需要加速度信息来监测振动。

3、建工程:

首先使用的开发底板是ST官方的MB1136。下面将链接所有相关信息。

习惯使用Stm32cubeMX快速建立项目。根据开发板的主芯片型号和传感器链接的引脚,配置所占用的资源。最后一键生成项目。(关于如何使用stm32MX,可以自己度娘,也可以在下面讨论)

值得一提的是:

(1)配置I2C当需要使用快速模式时,速度设置为最大(4万Hz),这可以加速与加速度传感器之间的通信。可以尽可能提高加速度传感器的输出频率。在实际测试中发现,在最快的时间IIC在通信速度下,传感器最大输出频率为3.33KHz。

(2)配置中断输入引脚,接收传感器数据时发送的中断。(也可以自己读取某个状态位)

(3)ST波特率为固定的9600。如果你想更高,你需要单独接线。(我是单独接线,设置为115200)

下一步是在项目中编写代码。我相信每个人都可以编写自己的逻辑代码。我的逻辑思维如下:

(1)初始化设备和传感器

(2)启动传感器,准备一组加速度数据(3个数据,X,Y,Z),引脚中断。

(3)F401RE接收中断,读取6个字节(3个加速度值)。(直接读取补码的形式,加速度值为正负,在定义变量时需要使用int16)

(4)矢量计算一组数据(3方向加速度),以获得其模长ACC。将ACC存储数组直到存储。(考虑到单片机存储空间有限,采用模长数组,1024个double数据)

(5)存放后,不再存放,放置在标志位置FFT傅里叶快速变换。相关知识参考:《C》C语言实现FFT算法_杨贵安博客-CSDN博客_c语言fft 。

该链接包含C语言代码,可直接运行。注意输入参数关系:

FFT需要定义与模长数组相同大小的多个数组,这需要更多的空间。

double pr[NUM],pi[NUM],fr[NUM],fi[NUM];

(6)存在得到的结果存在pr在[1024]中,如果需要观察变换的结果,可以在这个数组中使用double数据 打印到窗口助手中,再用excel观察变换结果。(打印时,单个数据接换行(\n\r),串口助手打印的一列数据直接复制到excel中)。数据列表中的第一个是直流分量,可以删除。另外,由于某种原因,剩余数据构成的图像呈现左右对称,显示时只取一半。如下图所示,传感器放置在计算机主机上,以测量主机风扇的振动。采样点共1024个。输出频率为833Hz。(增加采样点数,横坐标向右移动。提高输出频率,横坐标向左移动)(1024个采样点,833Hz输出频率对应145,145.66KHz输出频率对应72, 3.33KHz输出频率对应35)。

(7)水平坐标与振动频率直接相关。通过模拟输入数据观察,我发现采样点为1024时,傅里叶转换后获得的峰值高坐标与实际频率一致(略偏差,可理解)。

模拟输入pr[1024],包括10Hz,20Hz,30Hz,40Hz,50Hz,60Hz,70Hz,80Hz,90Hz。(参考频率与角速之间的关系)

for(i=0;i<1024;i ) {
pr[i]=cos(2*PI*0.001*i*10) cos(2*PI*0.001*i*20) cos(2*PI*0.001*i*30) cos(2*PI*0.001*i*40) cos(2*PI*0.001*i*50) cos(2*PI*0.001*i*60) cos(2*PI*0.001*i*70) cos(2*PI*0.001*i*80) cos(2*PI*0.001*i*90);
}

下图只使用了第一个~128点图(采样点数仍为1024)

4.编写上位机

上述显示过程有点繁琐,所以考虑为实时调试编写上位机。

转换后,下位机设备直接通过串口将数据发送到计算机。double数字首先转换为字符串,以字符串的形式发送。每个数据发送后,添加一个换行符\n,发送所有数据后,发送‘#’)

上位机编写,使用Qt和C 。有兴趣实现和源代码的童鞋可以问我。

我最好的计划是1024个采样点数组,传感器3.33KHz输出频率。计算机主机的频率测量为35Hz(每分钟2100转)。

纯个人经验总结,如有错误,欢迎讨论!

2020年12月17日 补充分享LSM6DSL 的初始化函数以及数据读取的函数

LSM6DSL pdf, LSM6DSL description, LSM6DSL datasheets, LSM6DSL view ::: ALLDATASHEET :::

#include "main.h" #define FUNC_CFG_ACCESS 0x01 //嵌入式功能配置寄存器 #define SENSOR_SYNC_TIME_FRAME 0x04 //传感器同步配置寄存器 #define SENSOR_SYNC_RES_RATIO 0x05 //传感器同步配置寄存器 #define FIFO_CTRL1 0x06 //FIFO 配置寄存器 #define FIFO_CTRL2 0x07 //FIFO 配置寄存器 #define FIFO_CTRL3 0x08 //FIFO 配置寄存器 #define FIFO_CTRL4 0x09 //FIFO 配置寄存器 #define FIFO_CTRL5 0x0a //FIFO 配置寄存器 #define DRDY_PULSE_CFG_G 0x0b // #define INT1_CTRL 0x0d // #define INT2_CTRL 0x0e // #define WHO_AM_I 0x0f //芯片ID #define CTRL1_XL 0x10 //加速度计和陀螺仪控制寄存器 #define CTRL2_G 0x11 // #define CTRL3_C 0x12 // #define CTRL4_C 0x13 // #define CTRL5_C 0x14 // #define CTRL6_C 0x15 // #define CTRL7_G 0x16 // #define CTRL8_XL 0x17 // #define CTRL9_XL 0x18 // #define CTRL10_C 0x19 // #define MASTER_CONFIG 0x1a //I2C主配置寄存器 #define WAKE_UP_SRC 0x1b //中断寄存器 #define TAP_SRC 0x1c //中断寄存器 #define D6D_SRC 0x1d //中断寄存器 #define STATUS_REG 0x1e //用户接口的状态数据寄存器 #define OUT_TEMP_L 0x20 //温度输出数据寄存器 #define OUT_TEMP_H 0x21 //温度输出数据寄存器 #define OUTX_L_G 0x22 //用户界面的陀螺仪输出寄存器 #define OUTX_H_G 0x23 //用户界面的陀螺仪输出寄存器 #define OUTY_L_G 0x24 //用户界面的陀螺仪输出寄存器 #define OUTY_H_G 0x25 //用户界面的陀螺仪输出寄存器 #define OUTZ_L_G 0x26 //用户界面的陀螺仪输出寄存器 #define OUTZ_H_G 0x27 //用户界面的陀螺仪输出寄存器 #define OUTX_L_XL 0x28 //加速度计输出寄存器 #define OUTX_H_XL 0x29 //加速度计输出寄存器 #define OUTY_L_XL 0x2a //加速度计输出寄存器 #define OUTY_H_XL 0x2b //加速度计输出寄存器 #define OUTZ_L_XL 0x2c //加速度计输出寄存器 #define OUTZ_H_XL 0x2d //加速度计输出寄存器 #define SENSORHUB1_REG 0x2e //传感器集线器输出寄存 #define SENSORHUB2_REG 0x2f //传感器集线器输出寄存 #define SENSORHUB3_REG 0x30 //传感器集线器输出寄存 #define SENSORHUB4_REG 0x31 //传感器集线器输出寄存 #define SENSORHUB5_REG 0x32 //传感器集线器输出寄存 #define SENSORHUB6_REG 0x33 //传感器集线器输出寄存 #define SENSORHUB7_REG 0x34 //传感器集线器输出寄存 #define SENSORHUB8_REG 0x35 //传感器集线器输出寄存 #define SENSORHUB9_REG 0x36 //传感器集线器输出寄存 #define SENSORHUB10_REG 0x37 //传感器集线器输出寄存 #define SENSORHUB11_REG 0x38 //传感器集线器输出寄存 #define SENSORHUB12_REG 0x39 //传感器集线器输出寄存 #define FIFO_STATUS1 0x3a //FIFO状态寄存器 #define FIFO_STATUS2 0x3b // #define FIFO_STATUS3 0x3c // #define FIFO_STATUS4 0x3d // #define FIFO_DATA_OUT_L 0x3e //FIFO数据输出寄存器 #define FIFO_DATA_OUT_H 0x3f // #define TIMESTAMP0_REG 0x40 //时间戳输出寄存器 #define TIMESTAMP1_REG 0x41 // #define TIMESTAMP2_REG 0x42 // /*reserved*/ #define STEP_TIMESTAMP_L 0x49 // #define STEP_TIMESTAMP_H 0x4A // #define STEP_COUNTER_L 0x4b // #define STEP_COUNTER_H 0x4c // #define SENSORHUB13_REG 0x4d //传感器集线器输出寄存 #define SENSORHUB14_REG 0x4e //传感器集线器输出寄存 #define SENSORHUB15_REG 0x4f //传感器集线器输出寄存 #define SENSORHUB16_REG 0x50 //传感器集线器输出寄存 #define SENSORHUB17_REG 0x51 //传感器集线器输出寄存 #define SENSORHUB18_REG 0x52 //传感器集线器输出寄存 #define FUNC_SRC1 0x53 //中断寄存器 #define FUNC_SRC2 0x54 // #define WRIST_TILT_IA 0x55 //中断寄存器 /*reserved*/ #define TAP_CFG 0x58 //中断寄存器 #define TAP_THS_6D 0x59 // #define INT_DUR2 0x5a // #define WAKE_UP_THS 0x5b // #define WAKE_UP_DUR 0x5c // #define FREE_FALL 0x5d // #define MD1_CFG 0x5e // #define MD2_CFG 0x5f // #define MASTER_CMD_CODE 0x60 //---------- #define SENS_SYNC_SPI_ERROR_CODE 0x61 // /*reserved*/ #define OUT_MAG_RAW_X_L 0x66 // #define OUT_MAG_RAW_X_H 0x67 // #define OUT_MAG_RAW_Y_L 0x68 // #define OUT_MAG_RAW_Y_H 0x69 // #define OUT_MAG_RAW_Z_L 0x6a // #define OUT_MAG_RAW_Z_H 0x6b // /*reserved*/ #define X_OFS_USR 0x73 //加速度用户偏移矫正 #define Y_OFS_USR 0x74 // #define Z_OFS_USR 0x75 // /* 配置 */ uint8_t LSM6DSL_Config[]={ CTRL3_C , 0x81,//软件重启 // FUNC_CFG_ACCESS , 0x00, // SENSOR_SYNC_TIME_FRAME , 0x00, // SENSOR_SYNC_RES_RATIO , 0x00, // FIFO_CTRL1 , 0x00, // FIFO_CTRL2 , 0x00, // FIFO_CTRL3 , 0x00, // FIFO_CTRL4 , 0x00, // FIFO_CTRL5 , 0x00, DRDY_PULSE_CFG_G , 0x80,//脉冲触发(不存中断引脚) INT1_CTRL , 0x01,//INT1引脚上各种中断事件的使能位//加速度中断 // INT2_CTRL , 0x02,//INT2引脚上各种中断事件的使能位//角速度中断 CTRL1_XL , 0x94,//加速度输出频率,量程,带宽//[0x60]416Hz 16g // CTRL2_G , 0x64,//角速度输出速率,量程,满量程125,0//416hZ 500DPS // CTRL4_C , 0x13,// // CTRL5_C , 0x14,// // CTRL6_C , 0x15,// // CTRL7_G , 0x16,// // CTRL8_XL , 0x17,// // CTRL9_XL , 0x18,// // CTRL10_C , 0x19,// // MASTER_CONFIG , 0x1a,//I2C主配置寄存器 // TAP_CFG , 0x58,//中断寄存器 // TAP_THS_6D , 0x59,// // INT_DUR2 , 0x5a,// // WAKE_UP_THS , 0x5b,// // WAKE_UP_DUR , 0x5c,// // FREE_FALL , 0x5d,// // MD1_CFG , 0x5e,// // MD2_CFG , 0x5f,// // MASTER_CMD_CODE , 0x60,//---------- // SENS_SYNC_SPI_ERROR_CODE , 0x61,// // X_OFS_USR , 0x73,//加速度用户偏移矫正 // Y_OFS_USR , 0x74,// // Z_OFS_USR , 0x75,// }; /* 初始化 */ int LSM6DSL_init() { uint8_t i=0,ID=0; //--------------------------------------- I2C_ReadData(&ID,1,WHO_AM_I); if(ID==0x6a) { //printf("product ID: 0x%02X\n\r",ID); } else { printf("[error] ID Wrong! %02X\n\r",ID); return -1; } //--------------------------------------- for(i=0;i

以下是硬件IIC 二次封装的函数,建议放在i2c.c文件中。

/* USER CODE BEGIN 1 */

#include 
//IIC
#define LSM6DSL_DEV_Adress  0xd6
#define IIS2DLPC_DEV_Adress 0x30
#define LIS2DH12_DEV_Adress 0x30
int I2C_WriteData(uint8_t* pData,uint16_t Size,uint16_t MeAddress)
{
	HAL_StatusTypeDef ret =HAL_ERROR;
	uint16_t DevAddress=0;//设备地址
  uint16_t MemAddsize=I2C_MEMADD_SIZE_8BIT;
	uint32_t Timeout=1000;
	I2C_HandleTypeDef* hi2cX=NULL;
  hi2cX=&hi2c1;
	DevAddress=LIS2DH12_DEV_Adress;
	//IIC发送
	ret=HAL_I2C_Mem_Write(hi2cX,DevAddress,MeAddress,MemAddsize,pData,Size,Timeout);
	return ret;
}

int I2C_ReadData(uint8_t* pData,uint16_t Size,uint16_t MeAddress)
{
	uint16_t DevAddress=0;//设备地址
	//uint16_t MeAddress=0;
  uint16_t MemAddsize=0;
	uint32_t Timeout=1000;
	I2C_HandleTypeDef* hi2cX=NULL;
	hi2cX=&hi2c1;
	DevAddress=LIS2DH12_DEV_Adress;
	MemAddsize=I2C_MEMADD_SIZE_8BIT;
	//IIC读取
	if(HAL_OK == HAL_I2C_Mem_Read(hi2cX,DevAddress,MeAddress,MemAddsize,pData,Size,Timeout)) {
		return 0;
	}
	return -1;
}



/* USER CODE END 1 */

以下函数 用于计算 加速度模长。


uint16_t Calculate_AccXYZ(int16_t X,int16_t Y,int16_t Z)
{
    uint32_t temp = X*X+Y*Y+Z*Z;
	  return (uint16_t)sqrt(temp);
}

以下函数为读取加速度值,其中ZZZ表示Z轴方向上的数值。

uint8_t Acc_Value[6];
int16_t ZZZ=0;
I2C_ReadData(Acc_Value,6,0x28);// 0x28 //加速度计输出寄存器
ZZZ =Acc_Value[4] + (Acc_Value[5]<<8);
		

希望能够对大家有所帮助。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章