SensorTile 模块不但可以实时传输传感器数据,还可以通过SD存储,这个功能使得离线数据也可以存下来进行过往传感器状态分析。在无人值守的野外环境非常有用。
这次测评就来分析一下SensorTile的SD存储功能。
这次分析的工程是STSW-STLKT01\en.stsw-stlkt01\STSW-STLKT01\Projects\SensorTile\Applications\DataLog 。
首先,例程给了两个数据输出方式:
- /* SendOverUSB = 0 --> Save sensors data on SDCard (enable with double click) */
- /* SendOverUSB = 1 --> Send sensors data via USB */
- uint8_t SendOverUSB = 1;
复制代码
一个是USB虚拟串口输出,默认为这个,另一个是SD卡存储。SendOverUSB 值需赋值为0。
接下来程序会初始化SD部分:
- void DATALOG_SD_Init(void)
- {
- char SDPath[4];
- if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0)
- {
- /* Register the file system object to the FatFs module */
- if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) != FR_OK)
- {
- /* FatFs Initialization Error */
- while(1)
- {
- BSP_LED_On(LED1);
- HAL_Delay(500);
- BSP_LED_Off(LED1);
- HAL_Delay(100);
- }
- }
- }
- }
复制代码
挂载SD卡。
之后就开始轮询传感器并将传感器值写入SD卡内。
- RTC_Handler( &RtcHandle );
- Accelero_Sensor_Handler( LSM6DSM_X_0_handle );
- Gyro_Sensor_Handler( LSM6DSM_G_0_handle );
- Magneto_Sensor_Handler( LSM303AGR_M_0_handle );
- Pressure_Sensor_Handler( LPS22HB_P_0_handle );
- if(!no_T_HTS221)
- {
- Temperature_Sensor_Handler( HTS221_T_0_handle );
- }
- if(!no_H_HTS221)
- {
- Humidity_Sensor_Handler( HTS221_H_0_handle );
- }
- if(!no_GG)
- {
- Gas_Gauge_Handler(GG_handle);
- }
复制代码
RTC时间写入
- else if(SD_Log_Enabled) /* Write data to the file on the SDCard */
- {
- uint8_t size;
- size = sprintf( dataOut, "%d:%d:%d.%d\t", stimestructure.Hours, stimestructure.Minutes, stimestructure.Seconds, subSec);
- res = f_write(&MyFile, dataOut, size, (void *)&byteswritten);
- }
复制代码
加速度计写入
- else if(SD_Log_Enabled) /* Write data to the file on the SDCard */
- {
- uint8_t size;
- size = sprintf(dataOut, "%d\t%d\t%d\t", (int)acceleration.AXIS_X, (int)acceleration.AXIS_Y, (int)acceleration.AXIS_Z);
- res = f_write(&MyFile, dataOut, size, (void *)&byteswritten);
- }
复制代码
之后的各个传感器都是一样。
由此,每次循环记录传感器的值在SD卡里。但是有个问题就是每次都写,在什么地方关闭文件呢?如果中途断电,文件是一点都存不下来的。
于是看到程序最后这段:
- if(MEMSInterrupt)
- {
- MEMSInterrupt = 0;
- BSP_ACCELERO_Get_Double_Tap_Detection_Status_Ext(LSM6DSM_X_0_handle,&doubleTap);
- if(doubleTap) { /* Double Tap event */
- 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;
- }
- else
- {
- DATALOG_SD_Log_Disable();
- }
- HAL_Delay(100);
- }
- }
- }
- }
复制代码
这段代码的意思就是检测到双击的时候停止记录,双击过后继续记录。
- void DATALOG_SD_Log_Disable(void)
- {
- f_close(&MyFile);
- /* SD SPI Config */
- SD_IO_CS_DeInit();
- }
复制代码
而停止记录正是关闭文件。
- uint8_t DATALOG_SD_Log_Enable(void)
- {
- static uint16_t sdcard_file_counter = 0;
- char header[] = "Timestamp\tAccX [mg]\tAccY [mg]\tAccZ [mg]\tGyroX [mdps]\tGyroY [mdps]\tGyroZ [mdps]\tMagX [mgauss]\tMagY [mgauss]\tMagZ [mgauss]\tP [mB]\tT [°C]\tH [%]\tVOL [mV]\tBAT [%]\r\n";
- uint32_t byteswritten; /* written byte count */
- char file_name[30] = {0};
- /* SD SPI CS Config */
- SD_IO_CS_Init();
- sprintf(file_name, "%s%.3d%s", "SensorTile_Log_N", sdcard_file_counter, ".tsv");
- sdcard_file_counter++;
- HAL_Delay(100);
- // ret = f_open(&MyFile, (char const*)file_name, FA_CREATE_ALWAYS | FA_WRITE);
- if(f_open(&MyFile, (char const*)file_name, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
- {
- return 0;
- }
- if(f_write(&MyFile, (const void*)&header, sizeof(header)-1, (void *)&byteswritten) != FR_OK)
- {
- return 0;
- }
- return 1;
- }
复制代码
开始记录正是重新初始化并创建文件。
这个开始和停止非常巧妙的运用了SensorTile自身的功能来实现。值得借鉴。
|