完整的传感器子系统和计算平台,始终以最低功耗运行传感器数据处理算法。
A
A
硬件概览
它是如何工作的?
Smart Sens 2 Click基于Bosch Sensortec的BHI260AP、BME688、BMP390和BMM150,这些都是低功耗可编程智能传感器、环境和压力传感器以及磁力计。BHI260AP基于32位微控制器(Fuser2),主要作为协处理器卸载主CPU的任何传感器数据处理相关任务,在这种情况下处理来自多个板载传感器的数据。它集成了惯性测量单元(6DoF IMU)和事件驱动软件框架,使BHI260AP成为一个完整的传感器子系统和计算平台,以最低功耗运行始终开启的传感器数据处理算法。BMM150是一个地磁传感器,允许在三个垂直轴上进行磁场测量。应用专用电路(ASIC)将地磁传感器的输出转换为数字结果,然后通过辅助数字I2C接口发送到BHI260AP进行信号处理。同样,BME688和BMP390也通过I2C接口将其数据发送到BHI260AP进行进一步处理。
BME688检测挥发性有机物(VOCs)、硫化合物(VSCs)和其他气体,如一氧化碳和氢气,范围在ppb级,而BMP390进行压力和温度测量。Smart Sens 2 Click允许使用I2C和SPI接口与MCU通信。选择可以通过将标记为COMM SEL的SMD跳线放置在适当位置来完成。注意,所有跳线的位置必须在同一侧,否则Click板™可能会无响应。当选择I2C接口时,BHI260AP允许使用标记为ADDR SEL的SMD跳线选择其I2C从地址的最低有效位(LSB)。除了接口引脚外,此Click板™还使用复位引脚(mikroBUS™插槽上的RST引脚)和INT引脚(mikroBUS™插槽上的INT引脚),指示从BHI260AP到MCU的数据传输请求,以及一个用于事件中断指示的红色LED。由于所有板载传感器的操作需要1.8V电压才能准确工作,一个小型稳压LDO AP2112从
mikroBUS™电源轨提供1.8V电压。这就是为什么还具有电压电平转换器TXB0106和PCA9306的原因。接口总线线被路由到双向电压电平转换器,使此Click板™能够与3.3V和5V的MCU正确配合工作。此外,板载BOOT开关用于选择是使用主机接口(HOST位置),还是BHI260AP尝试从板载QSPI闪存(W25Q32JW)启动并在独立操作模式下运行(QSPI位置)。此外,在此Click板™的右侧,有一个额外的未填充头部,标记为JTAG,用于通过JTAG接口引脚(TCK和TMS)进行调试。此Click板™可以通过VIO SEL跳线选择使用3.3V或5V逻辑电压电平。这样,3.3V和5V能力的MCU都可以正确使用通信线。此外,此Click板™配备了包含易于使用的函数和示例代码的库,可用作进一步开发的参考。
功能概述
开发板
Clicker 4 for STM32F3 是一款紧凑型开发板,作为完整的解决方案而设计,可帮助用户快速构建具备独特功能的定制设备。该板搭载 STMicroelectronics 的 STM32F302VCT6 微控制器,配备四个 mikroBUS™ 插槽用于连接 Click boards™、完善的电源管理功能以及其他实用资源,是快速开发各类应用的理想平台。其核心 MCU STM32F302VCT6 基于高性能
Arm® Cortex®-M4 32 位处理器,运行频率高达 168MHz,处理能力强大,能够满足各种高复杂度任务的需求,使 Clicker 4 能灵活适应多种应用场景。除了两个 1x20 引脚排针外,板载最显著的连接特性是四个增强型 mikroBUS™ 插槽,支持接入数量庞大的 Click boards™ 生态系统,该生态每日持续扩展。Clicker 4 各功能区域标识清晰,界面直观简洁,极大
提升使用便捷性和开发效率。Clicker 4 的价值不仅在于加速原型开发与应用构建阶段,更在于其作为独立完整方案可直接集成至实际项目中,无需额外硬件修改。四角各设有直径 4.2mm(0.165")的安装孔,便于通过螺丝轻松固定。对于多数应用,只需配套一个外壳,即可将 Clicker 4 开发板转化为完整、实用且外观精美的定制系统。
微控制器概述
MCU卡片 / MCU

建筑
ARM Cortex-M4
MCU 内存 (KB)
256
硅供应商
STMicroelectronics
引脚数
100
RAM (字节)
40960
使用的MCU引脚
mikroBUS™映射器
“仔细看看!”
Click board™ 原理图

一步一步来
项目组装
实时跟踪您的结果
应用程序输出
1. 应用程序输出 - 在调试模式下,“应用程序输出”窗口支持实时数据监控,直接提供执行结果的可视化。请按照提供的教程正确配置环境,以确保数据正确显示。

2. UART 终端 - 使用UART Terminal通过USB to UART converter监视数据传输,实现Click board™与开发系统之间的直接通信。请根据项目需求配置波特率和其他串行设置,以确保正常运行。有关分步设置说明,请参考提供的教程。

3. Plot 输出 - Plot功能提供了一种强大的方式来可视化实时传感器数据,使趋势分析、调试和多个数据点的对比变得更加直观。要正确设置,请按照提供的教程,其中包含使用Plot功能显示Click board™读数的分步示例。在代码中使用Plot功能时,请使用以下函数:plot(insert_graph_name, variable_name);。这是一个通用格式,用户需要将“insert_graph_name”替换为实际图表名称,并将“variable_name”替换为要显示的参数。

软件支持
库描述
该库包含 Smart Sens 2 Click 驱动程序的 API。
关键功能:
smartsens2_register_fifo_parse_callback
- 当传感器事件在FIFO中可用时,链接回调和相关引用的函数。smartsens2_set_virt_sensor_cfg
- 设置虚拟传感器的采样率和延迟的函数。smartsens2_get_and_process_fifo
- 获取和处理FIFO的函数。
开源
代码示例
完整的应用程序代码和一个现成的项目可以通过NECTO Studio包管理器直接安装到NECTO Studio。 应用程序代码也可以在MIKROE的GitHub账户中找到。
/*!
* @file main.c
* @brief SmartSens2 Click example
*
* # Description
* This example showcases the ability of the Smart Sens 2 Click board.
* It has multiple examples that you can easily select with the
* defines at the top of the main. There are 9 examples: Euler, Quaternion,
* Vector (Accelerometer, Gyroscope, Magnetometer), and
* Environmental (Temperature, Barometer, Humidity, Gas).
*
* The demo application is composed of two sections :
*
* ## Application Init
* Initialization of communication modules (SPI/I2C) and additional
* pins(int_pin, rst). After that going through reset sequence and checking
* device and product IDs, interrupt mask, and host control is set to 0, so
* every interrupt enabled. If boot status is OK boot sequence is initiated,
* depending on the defines from the library header it will use RAM or Flash type
* of the boot. If RAM is selected firmware image first needs to be uploaded to RAM
* and then it will be booted. If Flash example is selected it will try to boot
* firmware first if it fails it will then write firmware image to flash and then
* try to boot it again. When firmware boot is finished Kernel version and Feature
* registers will be read to check if the firmware is loaded. Then all the callback function
* will be registered(meta event callback and whatever type of example parser you set),
* and driver will update the list of virtual sensors present, and finally will configure
* virtual sensor that will be used in the selected example.
*
* ## Application Task
* Wait for an interrupt to occur, then read wake-up, non-weak-up, and status FIFO.
* Parse received data and run the callback parsers to show data on the USB UART.
*
* @note
* Select one of the examples with macros at the top of the main file. Euler example is selected by default.
* You can choose one of 4 type of parsers: Euler, Quaternion, Vector, Environmental. If Vector example is selected
* you choose one of the 3 sensors to show X, Y, and Z values: Accelerometer, Gyroscope, or Magnetometer.
* If Environmental example is selected you choose one of the 4 sensors: Temperature, Barometer, Humidity, or Gas.
*
* @author Stefan Filipovic
*
*/
#include "board.h"
#include "log.h"
#include "smartsens2.h"
/**
* @brief Example parser selector.
* @details Macros for selecting example and its parser.
*/
#define EULER 1
#define QUATERNION 0
#define VECTOR 0
#define ENVIRONMENTAL 0
/**
* @brief Vector sensor selector.
* @details Macros for selecting vector's sensor.
*/
#define ACCELEROMETER 1
#define GYROSCOPE 0
#define MAGNETOMETER 0
/**
* @brief Environmental sensor selector.
* @details Macros for selecting environmental sensor.
*/
#define TEMPERATURE 1
#define BAROMETER 0
#define HUMIDITY 0
#define GAS 0
#define WORK_BUFFER_SIZE 2048
uint8_t work_buffer[ WORK_BUFFER_SIZE ] = { 0 };
static smartsens2_t smartsens2;
static log_t logger;
uint8_t accuracy; /* Accuracy is reported as a meta event. It is being printed alongside the data */
#if EULER
/**
* @brief Euler data.
* @details Struct for euler data of the Smart Sens 2 Click example.
*/
struct smartsens2_data_orientation
{
int16_t heading;
int16_t pitch;
int16_t roll;
};
/**
* @brief Euler callback parsing function.
* @details Callback function to parse euler data.
* @param[in] callback_info : Callback data.
* @param[in] callback_ref : Callback reference.
* @return Nothing
*/
static void parse_euler ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref );
#elif QUATERNION
/**
* @brief Quaternion data.
* @details Struct for quaternion data of the Smart Sens 2 Click example.
*/
struct smartsens2_data_quaternion
{
int16_t x;
int16_t y;
int16_t z;
int16_t w;
uint16_t accuracy;
};
/**
* @brief Parse FIFO frame data into quaternion
* @details Function to parse FIFO frame data into quaternion
* @param[in] callback_info : Callback data.
* @param[in] callback_ref : Callback reference.
*/
static void parse_quaternion ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref );
#elif VECTOR
/**
* @brief Vector data.
* @details Struct for vector data of the Smart Sens 2 Click example.
*/
struct smartsens2_data_xyz
{
int16_t x;
int16_t y;
int16_t z;
};
/**
* @brief Parse reference.
* @details Struct for parse reference data of the Smart Sens 2 Click example.
*/
struct parse_ref
{
struct
{
uint8_t accuracy;
float scaling_factor;
}
sensor[ SMARTSENS2_SENSOR_ID_MAX ];
uint8_t *verbose;
};
struct parse_ref parse_table;
/**
* @brief Vector callback parsing function.
* @details Callback function to parse vector data.
* @param[in] callback_info : Callback data.
* @param[in] callback_ref : Callback reference.
* @return Nothing
*/
static void parse_vector_s16 ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref );
#elif ENVIRONMENTAL
/**
* @brief Temperature callback parsing function.
* @details Callback function to parse temperature data.
* @param[in] callback_info : Callback data.
* @param[in] callback_ref : Callback reference.
* @return Nothing
*/
static void parse_temperature ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref );
/**
* @brief Barometer callback parsing function.
* @details Callback function to parse barometer data.
* @param[in] callback_info : Callback data.
* @param[in] callback_ref : Callback reference.
* @return Nothing
*/
static void parse_barometer ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref );
/**
* @brief Humidity callback parsing function.
* @details Callback function to parse humidity data.
* @param[in] callback_info : Callback data.
* @param[in] callback_ref : Callback reference.
* @return Nothing
*/
static void parse_humidity ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref );
/**
* @brief Gas callback parsing function.
* @details Callback function to parse gas data.
* @param[in] callback_info : Callback data.
* @param[in] callback_ref : Callback reference.
* @return Nothing
*/
static void parse_gas ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref );
#else
#error NO_EXAMPLE_DEFINED
#endif
/**
* @brief Meta event callback parsing function.
* @details Callback function to parse meta event data.
* @param[in] callback_info : Callback data.
* @param[in] callback_ref : Callback reference.
* @return Nothing
*/
static void parse_meta_event ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref );
/**
* @brief Get name of the virtual sensor by ID.
* @details Function return name of the virutal sensor by its ID.
* @param[in] sensor_id : Virtual sensor ID.
* @return Virtual sensor name.
*/
static char* get_sensor_name ( uint8_t sensor_id );
void application_init ( void )
{
log_cfg_t log_cfg; /**< Logger config object. */
smartsens2_cfg_t smartsens2_cfg; /**< Click config object. */
/**
* Logger initialization.
* Default baud rate: 115200
* Default log level: LOG_LEVEL_DEBUG
* @note If USB_UART_RX and USB_UART_TX
* are defined as HAL_PIN_NC, you will
* need to define them manually for log to work.
* See @b LOG_MAP_USB_UART macro definition for detailed explanation.
*/
LOG_MAP_USB_UART( log_cfg );
log_init( &logger, &log_cfg );
log_info( &logger, " Application Init " );
// Click initialization.
smartsens2_cfg_setup( &smartsens2_cfg );
SMARTSENS2_MAP_MIKROBUS( smartsens2_cfg, MIKROBUS_1 );
err_t init_flag = smartsens2_init( &smartsens2, &smartsens2_cfg );
if ( ( I2C_MASTER_ERROR == init_flag ) || ( SPI_MASTER_ERROR == init_flag ) )
{
log_error( &logger, " Communication init." );
for ( ; ; );
}
/* It can take a few seconds to configure and boot device */
log_info( &logger, " Configuring device..." );
if ( SMARTSENS2_ERROR == smartsens2_default_cfg ( &smartsens2 ) )
{
log_error( &logger, " Default configuration." );
for ( ; ; );
}
log_info( &logger, " Setting callbacks..." );
/* Set callbacks */
if ( smartsens2_register_fifo_parse_callback( &smartsens2, SMARTSENS2_SYS_ID_META_EVENT,
parse_meta_event, &accuracy ) )
{
log_error( &logger, " FIFO sys meta event." );
for ( ; ; );
}
if ( smartsens2_register_fifo_parse_callback( &smartsens2, SMARTSENS2_SYS_ID_META_EVENT_WU,
parse_meta_event, &accuracy ) )
{
log_error( &logger, " FIFO sys meta event wu." );
for ( ; ; );
}
uint8_t sensor_id;
smartsens2_fifo_parse_callback_t callback;
void *callback_ref;
#if EULER
sensor_id = SMARTSENS2_SENSOR_ID_ORI;
callback = parse_euler;
callback_ref = &accuracy;
#elif QUATERNION
sensor_id = SMARTSENS2_SENSOR_ID_RV;
callback = parse_quaternion;
callback_ref = NULL;
#elif VECTOR
#if ACCELEROMETER
parse_table.sensor[ SMARTSENS2_SENSOR_ID_ACC ].scaling_factor = 1.0f / 4096.0f;
sensor_id = SMARTSENS2_SENSOR_ID_ACC;
#elif GYROSCOPE
parse_table.sensor[ SMARTSENS2_SENSOR_ID_GYRO ].scaling_factor = 1.0f;
sensor_id = SMARTSENS2_SENSOR_ID_GYRO;
#elif MAGNETOMETER
parse_table.sensor[ SMARTSENS2_SENSOR_ID_MAG ].scaling_factor = 1.0f;
sensor_id = SMARTSENS2_SENSOR_ID_MAG;
#else
#error NO_VECTOR_EXAMPLE_DEFINED
#endif
callback = parse_vector_s16;
callback_ref = &parse_table;
#elif ENVIRONMENTAL
#if TEMPERATURE
sensor_id = SMARTSENS2_SENSOR_ID_TEMP;
callback = parse_temperature;
#elif BAROMETER
sensor_id = SMARTSENS2_SENSOR_ID_BARO;
callback = parse_barometer;
#elif HUMIDITY
sensor_id = SMARTSENS2_SENSOR_ID_HUM;
callback = parse_humidity;
#elif GAS
sensor_id = SMARTSENS2_SENSOR_ID_GAS;
callback = parse_gas;
#else
#error NO_ENVIRONMENTAL_EXAMPLE_DEFINED
#endif
callback_ref = NULL;
#else
#error NO_EXAMPLE_DEFINED
#endif
if ( smartsens2_register_fifo_parse_callback( &smartsens2, sensor_id, callback, callback_ref ) )
{
log_error( &logger, " FIFO sensor id." );
for ( ; ; );
}
/* Go through fifo process */
if ( smartsens2_get_and_process_fifo( &smartsens2, work_buffer, WORK_BUFFER_SIZE ) )
{
log_error( &logger, " FIFO get and process." );
for ( ; ; );
}
/* Update virtual sensor list in context object */
if ( smartsens2_update_virtual_sensor_list( &smartsens2 ) )
{
log_error( &logger, " Update virtual sensor list." );
for ( ; ; );
}
/* Set virtual sensor configuration */
float sample_rate = 10.0; /* Read out data at 10Hz */
uint32_t report_latency_ms = 0; /* Report immediately */
if ( smartsens2_set_virt_sensor_cfg( &smartsens2, sensor_id, sample_rate, report_latency_ms ) )
{
log_error( &logger, " Set virtual sensor configuration." );
for ( ; ; );
}
log_info( &logger, " Application Task " );
}
void application_task ( void )
{
/* Check interrupt and get and process fifo buffer */
if ( smartsens2_get_interrupt( &smartsens2 ) )
{
/* Data from the FIFO is read and the relevant callbacks if registered are called */
if ( smartsens2_get_and_process_fifo( &smartsens2, work_buffer, WORK_BUFFER_SIZE ) )
{
log_error( &logger, " Get and process fifo." );
for ( ; ; );
}
}
}
int main ( void )
{
/* Do not remove this line or clock might not be set correctly. */
#ifdef PREINIT_SUPPORTED
preinit();
#endif
application_init( );
for ( ; ; )
{
application_task( );
}
return 0;
}
#if EULER
static void parse_euler ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref )
{
struct smartsens2_data_orientation data_val;
uint8_t *accuracy = ( uint8_t* ) callback_ref;
if ( callback_info->data_size != 7 ) /* Check for a valid payload size. Includes sensor ID */
{
return;
}
data_val.heading = SMARTSENS2_LE2S16( callback_info->data_ptr );
data_val.pitch = SMARTSENS2_LE2S16( callback_info->data_ptr + 2 );
data_val.roll = SMARTSENS2_LE2S16( callback_info->data_ptr + 4 );
if ( accuracy )
{
log_printf( &logger, "SID: %s; H: %.3f, P: %.3f, R: %.3f; acc: %u; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
( float ) ( data_val.heading * 360.0f / 32768.0f ),
( float ) ( data_val.pitch * 360.0f / 32768.0f ),
( float ) ( data_val.roll * 360.0f / 32768.0f ),
( uint16_t ) ( *accuracy ),
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
}
else
{
log_printf( &logger, "SID: %s; H: %.3f, P: %.3f, R: %.3f; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
( float ) ( data_val.heading * 360.0f / 32768.0f ),
( float ) ( data_val.pitch * 360.0f / 32768.0f ),
( float ) ( data_val.roll * 360.0f / 32768.0f ),
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
}
}
#elif QUATERNION
static void parse_quaternion ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref )
{
struct smartsens2_data_quaternion data_val;
if ( callback_info->data_size != 11 ) /* Check for a valid payload size. Includes sensor ID */
{
return;
}
data_val.x = SMARTSENS2_LE2S16( callback_info->data_ptr );
data_val.y = SMARTSENS2_LE2S16( callback_info->data_ptr + 2 );
data_val.z = SMARTSENS2_LE2S16( callback_info->data_ptr + 4 );
data_val.w = SMARTSENS2_LE2S16( callback_info->data_ptr + 6 );
data_val.accuracy = SMARTSENS2_LE2U16( callback_info->data_ptr + 8 );
log_printf( &logger, "SID: %s; X: %.3f, Y: %.3f, Z: %.3f, W: %.3f; acc: %.2f; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
( float ) ( data_val.x / 16384.0f ),
( float ) ( data_val.y / 16384.0f ),
( float ) ( data_val.z / 16384.0f ),
( float ) ( data_val.w / 16384.0f ),
( float ) ( ( ( data_val.accuracy * 180.0f ) / 16384.0f ) / 3.141592653589793f ),
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
}
#elif VECTOR
static void parse_vector_s16 ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref )
{
struct smartsens2_data_xyz data_value;
if ( callback_ref )
{
struct parse_ref *parse_table = ( struct parse_ref* ) callback_ref;
float scaling_factor = parse_table->sensor[ callback_info->sensor_id ].scaling_factor;
data_value.x = SMARTSENS2_LE2S16( callback_info->data_ptr );
data_value.y = SMARTSENS2_LE2S16( callback_info->data_ptr + 2 );
data_value.z = SMARTSENS2_LE2S16( callback_info->data_ptr + 4 );
#if ACCELEROMETER
log_printf( &logger, "SID: %s; X: %.3f, Y: %.3f, Z: %.3f; acc: %u; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
( float ) ( data_value.x * scaling_factor ),
( float ) ( data_value.y * scaling_factor ),
( float ) ( data_value.z * scaling_factor ),
( uint16_t ) parse_table->sensor[ callback_info->sensor_id ].accuracy,
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
#elif GYROSCOPE
log_printf( &logger, "SID: %s; X: %d, Y: %d, Z: %d; acc: %u; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
( int16_t ) ( data_value.x * scaling_factor ),
( int16_t ) ( data_value.y * scaling_factor ),
( int16_t ) ( data_value.z * scaling_factor ),
( uint16_t ) parse_table->sensor[ callback_info->sensor_id ].accuracy,
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
#elif MAGNETOMETER
log_printf( &logger, "SID: %s; X: %d, Y: %d, Z: %d; acc: %u; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
( int16_t ) ( data_value.x * scaling_factor ),
( int16_t ) ( data_value.y * scaling_factor ),
( int16_t ) ( data_value.z * scaling_factor ),
( uint16_t ) parse_table->sensor[ callback_info->sensor_id ].accuracy,
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
#else
#error NO_VECTOR_EXAMPLE_DEFINED
#endif
}
else
{
log_error( &logger, "Null reference" );
}
}
#elif ENVIRONMENTAL
static void parse_temperature ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref )
{
if ( callback_info->data_size != 5 ) /* Check for a valid payload size. Includes sensor ID */
{
return;
}
log_printf( &logger, "SID: %s; T: %.2f C; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
( SMARTSENS2_LE2S16( callback_info->data_ptr ) / 100.0 ),
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
}
static void parse_barometer ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref )
{
if ( callback_info->data_size != 4 ) /* Check for a valid payload size. Includes sensor ID */
{
return;
}
log_printf( &logger, "SID: %s; P: %.1f mBar; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
( SMARTSENS2_LE2U24( callback_info->data_ptr ) / 128.0 ),
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
}
static void parse_humidity ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref )
{
if ( callback_info->data_size != 2 ) /* Check for a valid payload size. Includes sensor ID */
{
return;
}
log_printf( &logger, "SID: %s; H: %u %%; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
( uint16_t ) callback_info->data_ptr[ 0 ],
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
}
static void parse_gas ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref )
{
if ( callback_info->data_size != 5 ) /* Check for a valid payload size. Includes sensor ID */
{
return;
}
log_printf( &logger, "SID: %s; G: %lu Ohms; Time: %lus\r\n",
get_sensor_name( callback_info->sensor_id ),
SMARTSENS2_LE2U32( callback_info->data_ptr ),
SMARTSENS2_TIMESTAMP_TO_SEC( *callback_info->time_stamp ) );
}
#else
#error NO_EXAMPLE_DEFINED
#endif
static void parse_meta_event ( struct smartsens2_fifo_parse_data_info *callback_info, void *callback_ref )
{
uint8_t meta_event_type = callback_info->data_ptr[ 0 ];
uint8_t byte1 = callback_info->data_ptr[ 1 ];
uint8_t byte2 = callback_info->data_ptr[ 2 ];
uint8_t *accuracy = ( uint8_t* ) callback_ref;
char *event_text;
if ( SMARTSENS2_SYS_ID_META_EVENT == callback_info->sensor_id )
{
event_text = "[META EVENT]";
}
else if ( SMARTSENS2_SYS_ID_META_EVENT_WU == callback_info->sensor_id )
{
event_text = "[META EVENT WAKE UP]";
}
else
{
return;
}
switch ( meta_event_type )
{
case SMARTSENS2_META_EVENT_FLUSH_COMPLETE:
{
log_printf( &logger, "%s Flush complete for sensor id %s\r\n",
event_text, get_sensor_name( byte1 ) );
break;
}
case SMARTSENS2_META_EVENT_SAMPLE_RATE_CHANGED:
{
log_printf( &logger, "%s Sample rate changed for sensor id %s\r\n",
event_text, get_sensor_name( byte1 ) );
break;
}
case SMARTSENS2_META_EVENT_POWER_MODE_CHANGED:
{
log_printf( &logger, "%s Power mode changed for sensor id %s\r\n",
event_text, get_sensor_name( byte1 ) );
break;
}
case SMARTSENS2_META_EVENT_ALGORITHM_EVENTS:
{
log_printf( &logger, "%s Algorithm event\r\n", event_text );
break;
}
case SMARTSENS2_META_EVENT_SENSOR_STATUS:
{
log_printf( &logger, "%s Accuracy for sensor id %s changed to %s\r\n",
event_text, get_sensor_name( byte1 ), get_sensor_name( byte2 ) );
if ( accuracy )
{
*accuracy = byte2;
}
break;
}
case SMARTSENS2_META_EVENT_BSX_DO_STEPS_MAIN:
{
log_printf( &logger, "%s BSX event (do steps main)\r\n", event_text );
break;
}
case SMARTSENS2_META_EVENT_BSX_DO_STEPS_CALIB:
{
log_printf( &logger, "%s BSX event (do steps calib)\r\n", event_text );
break;
}
case SMARTSENS2_META_EVENT_BSX_GET_OUTPUT_SIGNAL:
{
log_printf( &logger, "%s BSX event (get output signal)\r\n", event_text );
break;
}
case SMARTSENS2_META_EVENT_SENSOR_ERROR:
{
log_printf( &logger, "%s Sensor id %u reported error 0x%02X\r\n",
event_text, byte1, byte2 );
break;
}
case SMARTSENS2_META_EVENT_FIFO_OVERFLOW:
{
log_printf( &logger, "%s FIFO overflow\r\n", event_text );
break;
}
case SMARTSENS2_META_EVENT_DYNAMIC_RANGE_CHANGED:
{
log_printf( &logger, "%s Dynamic range changed for sensor id %s\r\n",
event_text, get_sensor_name( byte1 ) );
break;
}
case SMARTSENS2_META_EVENT_FIFO_WATERMARK:
{
log_printf( &logger, "%s FIFO watermark reached\r\n", event_text );
break;
}
case SMARTSENS2_META_EVENT_INITIALIZED:
{
log_printf( &logger, "%s Firmware initialized. Firmware version %u\r\n",
event_text, ( ( uint16_t )byte2 << 8 ) | byte1 );
break;
}
case SMARTSENS2_META_TRANSFER_CAUSE:
{
log_printf( &logger, "%s Transfer cause for sensor id %s\r\n",
event_text, get_sensor_name( byte1 ) );
break;
}
case SMARTSENS2_META_EVENT_SENSOR_FRAMEWORK:
{
log_printf( &logger, "%s Sensor framework event for sensor id %s\r\n",
event_text, byte1 );
break;
}
case SMARTSENS2_META_EVENT_RESET:
{
log_printf( &logger, "%s Reset event\r\n", event_text );
break;
}
case SMARTSENS2_META_EVENT_SPACER:
{
break;
}
default:
{
log_printf( &logger, "%s Unknown meta event with id: %u\r\n",
event_text, meta_event_type );
break;
}
}
}
static char* get_sensor_name ( uint8_t sensor_id )
{
char *ret;
switch ( sensor_id )
{
case SMARTSENS2_SENSOR_ID_ACC_PASS:
{
ret = "Accelerometer passthrough";
break;
}
case SMARTSENS2_SENSOR_ID_ACC_RAW:
{
ret = "Accelerometer uncalibrated";
break;
}
case SMARTSENS2_SENSOR_ID_ACC:
ret = "Accelerometer corrected";
break;
case SMARTSENS2_SENSOR_ID_ACC_BIAS:
{
ret = "Accelerometer offset";
break;
}
case SMARTSENS2_SENSOR_ID_ACC_WU:
{
ret = "Accelerometer corrected wake up";
break;
}
case SMARTSENS2_SENSOR_ID_ACC_RAW_WU:
{
ret = "Accelerometer uncalibrated wake up";
break;
}
case SMARTSENS2_SENSOR_ID_GYRO_PASS:
{
ret = "Gyroscope passthrough";
break;
}
case SMARTSENS2_SENSOR_ID_GYRO_RAW:
{
ret = "Gyroscope uncalibrated";
break;
}
case SMARTSENS2_SENSOR_ID_GYRO:
{
ret = "Gyroscope corrected";
break;
}
case SMARTSENS2_SENSOR_ID_GYRO_BIAS:
{
ret = "Gyroscope offset";
break;
}
case SMARTSENS2_SENSOR_ID_GYRO_WU:
{
ret = "Gyroscope wake up";
break;
}
case SMARTSENS2_SENSOR_ID_GYRO_RAW_WU:
{
ret = "Gyroscope uncalibrated wake up";
break;
}
case SMARTSENS2_SENSOR_ID_MAG_PASS:
{
ret = "Magnetometer passthrough";
break;
}
case SMARTSENS2_SENSOR_ID_MAG_RAW:
{
ret = "Magnetometer uncalibrated";
break;
}
case SMARTSENS2_SENSOR_ID_MAG:
{
ret = "Magnetometer corrected";
break;
}
case SMARTSENS2_SENSOR_ID_MAG_BIAS:
{
ret = "Magnetometer offset";
break;
}
case SMARTSENS2_SENSOR_ID_MAG_WU:
{
ret = "Magnetometer wake up";
break;
}
case SMARTSENS2_SENSOR_ID_MAG_RAW_WU:
{
ret = "Magnetometer uncalibrated wake up";
break;
}
case SMARTSENS2_SENSOR_ID_GRA:
{
ret = "Gravity vector";
break;
}
case SMARTSENS2_SENSOR_ID_GRA_WU:
{
ret = "Gravity vector wake up";
break;
}
case SMARTSENS2_SENSOR_ID_LACC:
{
ret = "Linear acceleration";
break;
}
case SMARTSENS2_SENSOR_ID_LACC_WU:
{
ret = "Linear acceleration wake up";
break;
}
case SMARTSENS2_SENSOR_ID_RV:
{
ret = "Rotation vector";
break;
}
case SMARTSENS2_SENSOR_ID_RV_WU:
{
ret = "Rotation vector wake up";
break;
}
case SMARTSENS2_SENSOR_ID_GAMERV:
{
ret = "Game rotation vector";
break;
}
case SMARTSENS2_SENSOR_ID_GAMERV_WU:
{
ret = "Game rotation vector wake up";
break;
}
case SMARTSENS2_SENSOR_ID_GEORV:
{
ret = "Geo-magnetic rotation vector";
break;
}
case SMARTSENS2_SENSOR_ID_GEORV_WU:
{
ret = "Geo-magnetic rotation vector wake up";
break;
}
case SMARTSENS2_SENSOR_ID_ORI:
{
ret = "Orientation";
break;
}
case SMARTSENS2_SENSOR_ID_ORI_WU:
{
ret = "Orientation wake up";
break;
}
case SMARTSENS2_SENSOR_ID_TILT_DETECTOR:
{
ret = "Tilt detector";
break;
}
case SMARTSENS2_SENSOR_ID_STD:
{
ret = "Step detector";
break;
}
case SMARTSENS2_SENSOR_ID_STC:
{
ret = "Step counter";
break;
}
case SMARTSENS2_SENSOR_ID_STC_WU:
{
ret = "Step counter wake up";
break;
}
case SMARTSENS2_SENSOR_ID_SIG:
{
ret = "Significant motion";
break;
}
case SMARTSENS2_SENSOR_ID_WAKE_GESTURE:
{
ret = "Wake gesture";
break;
}
case SMARTSENS2_SENSOR_ID_GLANCE_GESTURE:
{
ret = "Glance gesture";
break;
}
case SMARTSENS2_SENSOR_ID_PICKUP_GESTURE:
{
ret = "Pickup gesture";
break;
}
case SMARTSENS2_SENSOR_ID_AR:
{
ret = "Activity recognition";
break;
}
case SMARTSENS2_SENSOR_ID_WRIST_TILT_GESTURE:
{
ret = "Wrist tilt gesture";
break;
}
case SMARTSENS2_SENSOR_ID_DEVICE_ORI:
{
ret = "Device orientation";
break;
}
case SMARTSENS2_SENSOR_ID_DEVICE_ORI_WU:
{
ret = "Device orientation wake up";
break;
}
case SMARTSENS2_SENSOR_ID_STATIONARY_DET:
{
ret = "Stationary detect";
break;
}
case SMARTSENS2_SENSOR_ID_MOTION_DET:
{
ret = "Motion detect";
break;
}
case SMARTSENS2_SENSOR_ID_ACC_BIAS_WU:
{
ret = "Accelerometer offset wake up";
break;
}
case SMARTSENS2_SENSOR_ID_GYRO_BIAS_WU:
{
ret = "Gyroscope offset wake up";
break;
}
case SMARTSENS2_SENSOR_ID_MAG_BIAS_WU:
{
ret = "Magnetometer offset wake up";
break;
}
case SMARTSENS2_SENSOR_ID_STD_WU:
{
ret = "Step detector wake up";
break;
}
case SMARTSENS2_SENSOR_ID_TEMP:
{
ret = "Temperature";
break;
}
case SMARTSENS2_SENSOR_ID_BARO:
{
ret = "Barometer";
break;
}
case SMARTSENS2_SENSOR_ID_HUM:
{
ret = "Humidity";
break;
}
case SMARTSENS2_SENSOR_ID_GAS:
{
ret = "Gas";
break;
}
case SMARTSENS2_SENSOR_ID_TEMP_WU:
{
ret = "Temperature wake up";
break;
}
case SMARTSENS2_SENSOR_ID_BARO_WU:
{
ret = "Barometer wake up";
break;
}
case SMARTSENS2_SENSOR_ID_HUM_WU:
{
ret = "Humidity wake up";
break;
}
case SMARTSENS2_SENSOR_ID_GAS_WU:
{
ret = "Gas wake up";
break;
}
case SMARTSENS2_SENSOR_ID_STC_HW:
{
ret = "Hardware Step counter";
break;
}
case SMARTSENS2_SENSOR_ID_STD_HW:
{
ret = "Hardware Step detector";
break;
}
case SMARTSENS2_SENSOR_ID_SIG_HW:
{
ret = "Hardware Significant motion";
break;
}
case SMARTSENS2_SENSOR_ID_STC_HW_WU:
{
ret = "Hardware Step counter wake up";
break;
}
case SMARTSENS2_SENSOR_ID_STD_HW_WU:
{
ret = "Hardware Step detector wake up";
break;
}
case SMARTSENS2_SENSOR_ID_SIG_HW_WU:
{
ret = "Hardware Significant motion wake up";
break;
}
case SMARTSENS2_SENSOR_ID_ANY_MOTION:
{
ret = "Any motion";
break;
}
case SMARTSENS2_SENSOR_ID_ANY_MOTION_WU:
{
ret = "Any motion wake up";
break;
}
case SMARTSENS2_SENSOR_ID_EXCAMERA:
{
ret = "External camera trigger";
break;
}
case SMARTSENS2_SENSOR_ID_GPS:
{
ret = "GPS";
break;
}
case SMARTSENS2_SENSOR_ID_LIGHT:
{
ret = "Light";
break;
}
case SMARTSENS2_SENSOR_ID_PROX:
{
ret = "Proximity";
break;
}
case SMARTSENS2_SENSOR_ID_LIGHT_WU:
{
ret = "Light wake up";
break;
}
case SMARTSENS2_SENSOR_ID_PROX_WU:
{
ret = "Proximity wake up";
break;
}
default:
{
if ( ( sensor_id >= SMARTSENS2_SENSOR_ID_CUSTOM_START ) && ( sensor_id <= SMARTSENS2_SENSOR_ID_CUSTOM_END ) )
{
ret = "Custom sensor ID ";
}
else
{
ret = "Undefined sensor ID ";
}
}
}
return ret;
}
// ------------------------------------------------------------------------ END
额外支持
资源
类别:环境