
本帖最后由 点点&木木 于 2019-4-12 09:47 编辑 : I$ `2 v/ B+ G: E) m 介绍 在我们家里,我们有各种类型的家用电器,如冰箱,空调,冷却器,净水器,抽水马达,磨床,搅拌机等。这些设备有内部电机泵送或吸入空气和水; 当它们无法完成此功能时,电机会产生噪音,并且会产生刺激性并可能导致声音污染。由于永久使用这些设备是危险的,因此需要进行维护。为了申请保修,我们可以向公司发送报告以更换或进行维护。有关设备运行状况的详细报告可能更适用于保修索赔目的,因此我们需要类似SensorTile的设备。通过该设备,我们可以测量系统加速度,噪音,振动并完成报告。当我们在电话中与他们互动时,我们的技术人员设备的问题将会有点难以理解。所以他们需要先来检查并再次提供所需材料进行维护。在这个过程中,将有一些休息时间来了解系统健康状况以及为什么水是我们的重要来源。 以下步骤说明如何使用SensorTile设备向授权服务中心发送有关净水器健康状况的详细数据报告,以进行维护或更换。 ![]() / [ }1 _/ d; h4 n- X% Z 5 z' A* ^6 v2 @6 G( t7 Z3 X! x* T 这个项目中使用的东西 硬件组件 STM32 SensorTile × 1 ! D9 X+ k# R2 ^( z# y- j$ n/ `# z, ]. | 步骤1: 当净化器处于良好的工作状态时,它没有产生任何噪音或振动。一段时间后,家里的净水器出现了问题,它产生了振动噪音,纯净水无法充满水箱。 - z$ ~( Z& N3 T1 O5 x2 i![]() / f! Z+ E5 s1 q6 Y3 O 净水器工作不正常 # v+ m% Y8 r; y! _; D& t( x) a) I$ Q/ h) X1 _ , a, K( g% {& r+ `$ Q# f 第2步: SensorTile放置在净水器上,记录振动和噪音水平。 ![]() SensorTile放置在净水器上以测量振动噪声。 : ]' d* a4 E# F4 L 第3步: 打开ST BlueMS Android Mobile应用程序以记录数据并开始搜索以识别设备。 , [ L. `" B P9 X5 n; _$ R8 j![]() ST BlueMS应用程序在Android手机中打开。 第4步: 务必在手机上打开SensorTile和蓝牙,然后该应用程序会识别您列出的设备。单击设备以进行接口连接。 ![]() 应用已识别您的设备。 $ V* a. G8 w" h4 x7 {0 {+ G' @3 ]& q8 I% }; U0 H: [; M# |- D5 T 第5步: 建立连接后,应用程序屏幕将如下图所示。单击START LOGGING以记录来自车载传感器的温度,湿度,压力,加速度,方向,位置和噪声等参数的数据。滑动屏幕以在移动屏幕上查看录制数据。 ![]() 筛选测试参数的应用程序。 " A: [9 P! a: H9 |- Z第6步: 这是传感器技术从PCB设计软件时的外观。 ![]() 这是SensorTile的gerber图像。 0 l4 \" ?- a+ d7 P8 O' v! h: Z! x, o9 B- n5 o 第7步: 可以在屏幕上查看测量值,该加速度显示系统在运行时产生振动。它可能表示图中的小振荡,但对于这个小系统,这些水平更高。 : d5 y+ ^2 q" m9 n/ c; T![]() 应用程序屏幕上的加速显示振动级别。 $ n% U h& q5 o/ }1 }+ r/ W. i) ~7 V 第8步: 我们可以通过在应用程序中选择MIC选项来达到噪音水平。一旦我们打开净水器,噪音水平立即增加,这表明系统状况不佳,强度等级对人耳是危险的。下图显示了开机时声音的增加。 ![]() 一旦净化器开启,噪音水平立即增加 , i4 n2 {7 ~+ Y9 i$ \* {第9步: 一旦系统关闭,噪音水平就会下降,这表明系统不能使用,也没有将水泵送到水箱。 ![]() 系统关闭导致噪音水平下降 / I }. w7 Q9 b, N. S 第10步: 进行分析并从记录的数据绘制图表。分析图显示了车载加速度计和陀螺仪,实现对系统健康状况的确认。两个传感器都指示高振动水平。而两者之间的直线表示它已关闭。 ![]() 来自Accelerometer和Gyro的振动水平分析报告。 . O# [& n8 r' T* ~8 O5 k: c0 i: w第11步: 在执行健康检查后,记录的数据可以通过电子邮件发送到授权服务中心。 ![]() 记录的数据邮寄到服务中心。 该视频显示了我们如何使用SensorTile设备执行仪器运行状况检查。 8 c' z+ O, {5 v/ s# a" s6 H" Q' f% \- ^8 Y3 G7 e & ^% i& m; |% q0 }: i 结论: SensorTile设备适用于监控和检查家中的电气系统,因为它具有板载功能。使用此功能,我们可以检查任何系统的健康状况,并可以在保修期内将数据发送到授权服务中心进行维护或更换。它有助于技术人员了解设备的故障,因此他们可以提供适当的材料来提前检修。水是人类的重要资源,所以应该尽快纠正这个问题。这就是SensorTile在我们家中检查系统健康状况的重要作用。 相关代码 /*Program for SensorTile*/ /* Includes------------------------------------------------------------------*/ #include "main.h" #include "cmsis_os.h" #include "datalog_application.h" /* Private typedef-----------------------------------------------------------*/ /* Private define------------------------------------------------------------*/ #define DATAQUEUE_SIZE ((uint32_t)100) typedef enum { THREAD_1 = 0, THREAD_2 } Thread_TypeDef; /* Private variables---------------------------------------------------------*/ osThreadId GetDataThreadId,WriteDataThreadId; osMessageQId dataQueue_id; osMessageQDef(dataqueue, DATAQUEUE_SIZE,int); osPoolId sensorPool_id; osPoolDef(sensorPool, DATAQUEUE_SIZE,T_SensorsData); osSemaphoreId readDataSem_id; osSemaphoreDef(readDataSem); osSemaphoreId doubleTapSem_id; osSemaphoreDef(doubleTapSem); /* LoggingInterface = USB_Datalog --> Save sensors data on SDCard (enablewith double click) */ /* LoggingInterface = SDCARD_Datalog --> Send sensors data via USB */ LogInterface_TypeDef LoggingInterface =USB_Datalog; USBD_HandleTypeDef USBD_Device; static volatile uint8_t MEMSInterrupt = 0; volatile uint8_t no_H_HTS221 = 0; volatile uint8_t no_T_HTS221 = 0; void *LSM6DSM_X_0_handle = NULL; void *LSM6DSM_G_0_handle = NULL; void *LSM303AGR_X_0_handle = NULL; void *LSM303AGR_M_0_handle = NULL; void *LPS22HB_P_0_handle = NULL; void *LPS22HB_T_0_handle = NULL; void *HTS221_H_0_handle = NULL; void *HTS221_T_0_handle = NULL; /* Private function prototypes-----------------------------------------------*/ static void GetData_Thread(void const *argument); static void WriteData_Thread(void const *argument); static void Error_Handler( void ); static void initializeAllSensors( void ); void enableAllSensors( void ); void disableAllSensors( void ); void setOdrAllSensors( void ); void dataTimer_Callback(void const *arg); void dataTimerStart(void); void dataTimerStop(void); osTimerId sensorTimId; osTimerDef(SensorTimer, dataTimer_Callback); uint32_t exec; /* Private functions---------------------------------------------------------*/ /** *@brief Main program *@param None *@retval None */ int main(void) { HAL_Init(); /* Configure the System clock to 80 MHz */ SystemClock_Config(); if(LoggingInterface ==USB_Datalog) { /* Initialize LED */ BSP_LED_Init(LED1); BSP_LED_Off(LED1); } /* enable USB power on Pwrctrl CR2 register */ HAL_PWREx_EnableVddUSB(); if(LoggingInterface ==USB_Datalog) /* Configure the USB */ { /*** USB CDC Configuration ***/ /* Init Device Library */ USBD_Init(&USBD_Device, &VCP_Desc, 0); /* Add Supported Class */ USBD_RegisterClass(&USBD_Device, USBD_CDC_CLASS); /* Add Interface callbacks for AUDIO and CDC Class */ USBD_CDC_RegisterInterface(&USBD_Device, &USBD_CDC_fops); /* Start Device Process */ USBD_Start(&USBD_Device); } else /* Configure the SDCard */ { DATALOG_SD_Init(); } /* Thread 1 definition */ osThreadDef(THREAD_1, GetData_Thread, osPriorityAboveNormal, 0,configMINIMAL_STACK_SIZE*4); /* Thread 2 definition */ osThreadDef(THREAD_2, WriteData_Thread, osPriorityNormal, 0,configMINIMAL_STACK_SIZE*4); /* Start thread 1 */ GetDataThreadId = osThreadCreate(osThread(THREAD_1), NULL); /* Start thread 2 */ WriteDataThreadId = osThreadCreate(osThread(THREAD_2), NULL); /* Start scheduler */ osKernelStart(); /* We should never get here as control is now taken bythe scheduler */ for (;;); } /** *@brief Get data raw from sensors toqueue *@param thread not used *@retval None */ static void GetData_Thread(void const *argument) { (void) argument; uint8_t doubleTap = 0; T_SensorsData *mptr; sensorPool_id = osPoolCreate(osPool(sensorPool)); dataQueue_id = osMessageCreate(osMessageQ(dataqueue), NULL); readDataSem_id = osSemaphoreCreate(osSemaphore(readDataSem), 1); osSemaphoreWait(readDataSem_id, osWaitForever); doubleTapSem_id = osSemaphoreCreate(osSemaphore(doubleTapSem), 1); osSemaphoreWait(doubleTapSem_id, osWaitForever); /* Configure and disable all the Chip Select pins */ Sensor_IO_SPI_CS_Init_All(); /* Initialize and Enable the available sensors */ initializeAllSensors(); enableAllSensors(); if(LoggingInterface ==USB_Datalog) { dataTimerStart(); } for (;;) { osSemaphoreWait(readDataSem_id, osWaitForever); if(MEMSInterrupt&& LoggingInterface == SDCARD_Datalog) { MEMSInterrupt = 0; BSP_ACCELERO_Get_Double_Tap_Detection_Status_Ext(LSM6DSM_X_0_handle,&doubleTap); if(doubleTap) { if(SD_Log_Enabled) { dataTimerStop(); osMessagePut(dataQueue_id, 0x00000007, osWaitForever); } else { osMessagePut(dataQueue_id, 0x00000007, osWaitForever); } } } else { /* Try to allocate a memory block and checkif is not NULL */ mptr = osPoolAlloc(sensorPool_id); if(mptr != NULL) { /* Get Data from Sensors */ if(getSensorsData(mptr)== COMPONENT_OK) { /* Push the new memory Block in the DataQueue */ if(osMessagePut(dataQueue_id,(uint32_t)mptr, osWaitForever) != osOK) { Error_Handler(); } } else { Error_Handler(); } } else { Error_Handler(); } } } } /** *@brief Write data in the queue on fileor streaming via USB *@param argument not used *@retval None */ static void WriteData_Thread(void const *argument) { (void) argument; osEvent evt; T_SensorsData *rptr; intsize; char data_s[256]; for (;;) { evt = osMessageGet(dataQueue_id, osWaitForever); // wait formessage if (evt.status ==osEventMessage) { if(evt.value.v ==0x00000007) { if(SD_Log_Enabled) { DATALOG_SD_Log_Disable(); SD_Log_Enabled=0; } else { while(SD_Log_Enabled != 1) { if(DATALOG_SD_Log_Enable()) { SD_Log_Enabled=1; osDelay(100); dataTimerStart(); } else { //DATALOG_SD_Log_Disable(); DATALOG_SD_DeInit(); DATALOG_SD_Init(); osDelay(100); } } } } else { rptr = evt.value.p; if(LoggingInterface== USB_Datalog) { size = sprintf(data_s, "TimeStamp: %d\r\n Acc_X: %d, Acc_Y: %d,Acc_Z :%d\r\n Gyro_X:%d, Gyro_Y:%d, Gyro_Z:%d\r\n Magn_X:%d, Magn_Y:%d, Magn_Z:%d\r\n Press:%5.2f, Temp:%5.2f, Hum:%4.1f\r\n", rptr->ms_counter, (int)rptr->acc.AXIS_X, (int)rptr->acc.AXIS_Y,(int)rptr->acc.AXIS_Z, (int)rptr->gyro.AXIS_X, (int)rptr->gyro.AXIS_Y,(int)rptr->gyro.AXIS_Z, (int)rptr->mag.AXIS_X, (int)rptr->mag.AXIS_Y,(int)rptr->mag.AXIS_Z, rptr->pressure,rptr->temperature, rptr->humidity); osPoolFree(sensorPool_id, rptr); // free memory allocated for message BSP_LED_Toggle(LED1); CDC_Fill_Buffer(( uint8_t * )data_s, size); } else { size = sprintf(data_s, "%d, %d, %d, %d,%d, %d, %d, %d, %d, %d, %5.2f, %5.2f, %4.1f\r\n", rptr->ms_counter, (int)rptr->acc.AXIS_X, (int)rptr->acc.AXIS_Y,(int)rptr->acc.AXIS_Z, (int)rptr->gyro.AXIS_X, (int)rptr->gyro.AXIS_Y,(int)rptr->gyro.AXIS_Z, (int)rptr->mag.AXIS_X, (int)rptr->mag.AXIS_Y,(int)rptr->mag.AXIS_Z, rptr->pressure, rptr->temperature,rptr->humidity); osPoolFree(sensorPool_id, rptr); // free memory allocated for message DATALOG_SD_writeBuf(data_s, size); } } } } } void dataTimer_Callback(void const *arg) { osSemaphoreRelease(readDataSem_id); } void dataTimerStart(void) { osStatus status; // Create periodic timer exec = 1; sensorTimId = osTimerCreate(osTimer(SensorTimer), osTimerPeriodic,&exec); if (sensorTimId) { status = osTimerStart (sensorTimId, DATA_PERIOD_MS); // start timer if (status != osOK) { // Timer could not be started } } } void dataTimerStop(void) { osTimerStop(sensorTimId); } /** * @brief Initialize all sensors * @param None * @retval None */ static void initializeAllSensors( void ) { if (BSP_ACCELERO_Init(LSM6DSM_X_0, &LSM6DSM_X_0_handle ) != COMPONENT_OK) { while(1); } if (BSP_GYRO_Init(LSM6DSM_G_0, &LSM6DSM_G_0_handle ) != COMPONENT_OK) { while(1); } if (BSP_ACCELERO_Init(LSM303AGR_X_0, &LSM303AGR_X_0_handle ) != COMPONENT_OK) { while(1); } if (BSP_MAGNETO_Init(LSM303AGR_M_0, &LSM303AGR_M_0_handle ) != COMPONENT_OK) { while(1); } if (BSP_PRESSURE_Init(LPS22HB_P_0, &LPS22HB_P_0_handle ) != COMPONENT_OK) { while(1); } if(BSP_TEMPERATURE_Init( LPS22HB_T_0, &LPS22HB_T_0_handle ) != COMPONENT_OK) { while(1); } if(BSP_TEMPERATURE_Init(HTS221_T_0, &HTS221_T_0_handle ) == COMPONENT_ERROR) { no_T_HTS221 = 1; } if(BSP_HUMIDITY_Init(HTS221_H_0, &HTS221_H_0_handle ) == COMPONENT_ERROR) { no_H_HTS221 = 1; } if(LoggingInterface ==SDCARD_Datalog) { /* Enable HW Double Tap detection */ BSP_ACCELERO_Enable_Double_Tap_Detection_Ext(LSM6DSM_X_0_handle,INT2_PIN); BSP_ACCELERO_Set_Tap_Threshold_Ext(LSM6DSM_X_0_handle,LSM6DSM_TAP_THRESHOLD_MID); } } /** * @brief Enable all sensors * @param None * @retval None */ void enableAllSensors( void ) { BSP_ACCELERO_Sensor_Enable( LSM6DSM_X_0_handle ); BSP_GYRO_Sensor_Enable( LSM6DSM_G_0_handle ); BSP_ACCELERO_Sensor_Enable( LSM303AGR_X_0_handle ); BSP_MAGNETO_Sensor_Enable( LSM303AGR_M_0_handle ); BSP_PRESSURE_Sensor_Enable( LPS22HB_P_0_handle ); BSP_TEMPERATURE_Sensor_Enable( LPS22HB_T_0_handle ); if(!no_T_HTS221) { BSP_TEMPERATURE_Sensor_Enable( HTS221_T_0_handle ); } if(!no_H_HTS221) { BSP_HUMIDITY_Sensor_Enable( HTS221_H_0_handle ); } } /** * @brief Set ODR all sensors * @param None * @retval None */ void setOdrAllSensors( void ) { BSP_ACCELERO_Set_ODR_Value( LSM303AGR_X_0_handle, ACCELERO_ODR); BSP_MAGNETO_Set_ODR_Value( LSM303AGR_M_0_handle, MAGNETO_ODR); BSP_GYRO_Set_ODR_Value(LSM6DSM_G_0_handle, GYRO_ODR); BSP_PRESSURE_Set_ODR_Value( LPS22HB_P_0_handle, PRESSURE_ODR); BSP_TEMPERATURE_Set_ODR_Value( HTS221_T_0_handle, TEMPERATURE_ODR); BSP_HUMIDITY_Set_ODR_Value( HTS221_H_0_handle, TEMPERATURE_ODR ); } /** * @brief Disable all sensors * @param None * @retval None */ void disableAllSensors( void ) { BSP_ACCELERO_Sensor_Disable( LSM6DSM_X_0_handle ); BSP_ACCELERO_Sensor_Disable( LSM303AGR_X_0_handle ); BSP_GYRO_Sensor_Disable( LSM6DSM_G_0_handle ); BSP_MAGNETO_Sensor_Disable( LSM303AGR_M_0_handle ); BSP_HUMIDITY_Sensor_Disable( HTS221_H_0_handle ); BSP_TEMPERATURE_Sensor_Disable( HTS221_T_0_handle ); BSP_TEMPERATURE_Sensor_Disable( LPS22HB_T_0_handle ); BSP_PRESSURE_Sensor_Disable( LPS22HB_P_0_handle ); } /** * @brief EXTI line detection callbacks * @param GPIO_Pin: Specifies the pins connected EXTI line * @retval None */ void HAL_GPIO_EXTI_Callback( uint16_tGPIO_Pin ) { MEMSInterrupt=1; osSemaphoreRelease(readDataSem_id); } /** * @brief This function is executed in case of error occurrence * @param None * @retval None */ static void Error_Handler( void ) { while (1) {} } #ifdef USE_FULL_ASSERT /** *@brief Reports the name of the sourcefile and the source line number * where the assert_param errorhas occurred. *@param file: pointer to the source filename *@param line: assert_param error linesource number *@retval None */ void assert_failed(uint8_t *file, uint32_tline) { /* User can add his own implementation to report the filename and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n",file, line) */ /* Infinite loop */ while (1) {} } #endif /************************ (C) COPYRIGHTSTMicroelectronics *****END OF FILE****/ |