mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
208 lines
6.2 KiB
C
208 lines
6.2 KiB
C
/*
|
|
* Copyright (C) 2021 Inria
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup drivers_sm_pwm_01c SM_PWM_01C dust sensor
|
|
* @ingroup drivers_sensors
|
|
* @brief Driver for Amphenol SM_PWM_01C infrared dust sensor
|
|
* @{
|
|
*
|
|
*
|
|
* * About
|
|
* =====
|
|
*
|
|
* This driver provides an interface for the Amphenol SM-PWM-Sensor.
|
|
* The Datasheet can be found [here](https://www.cdiweb.com/datasheets/telaire-amphenol/01c%20dust%20sensor%20datasheet.pdf).
|
|
* and the more complete application note [here](https://www.sgbotic.com/products/datasheets/sensors/app-SM-PWM-01C.pdf)
|
|
*
|
|
* The device can measure small particles (1~ 2μm) and large particle (3 ~10μm),
|
|
* so similar to PM2.5 and PM10. The dust sensor cannot count particles only
|
|
* measure estimated concentrations.
|
|
*
|
|
* It is recommended to compute values over a 30s moving average. By default
|
|
* a moving average is used since the module MODULE_SM_PWM_01C_MA is
|
|
* activated by default. To save memory an exponential average can be used
|
|
* by disabling this module.
|
|
*
|
|
* @file
|
|
* @brief SM_PWM_01C Device Driver
|
|
*
|
|
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
|
*/
|
|
|
|
#ifndef SM_PWM_01C_H
|
|
#define SM_PWM_01C_H
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include "timex.h"
|
|
#include "ztimer.h"
|
|
#include "periph/gpio.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @defgroup drivers_sm_pwm_01c_conf SM_PWM_01C compile configurations
|
|
* @ingroup drivers_sm_pwm_01c
|
|
* @ingroup config
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @def CONFIG_SM_PWM_01C_SAMPLE_TIME
|
|
*
|
|
* @brief Frequency at witch LPO % is calculated
|
|
*/
|
|
#ifndef CONFIG_SM_PWM_01C_SAMPLE_TIME
|
|
#define CONFIG_SM_PWM_01C_SAMPLE_TIME (100 * US_PER_MS)
|
|
#endif
|
|
|
|
/**
|
|
* @def CONFIG_SM_PWM_01C_WINDOW_TIME
|
|
*
|
|
* @brief Length in time of the measuring window, recommended 5-30s
|
|
*/
|
|
#ifndef CONFIG_SM_PWM_01C_WINDOW_TIME
|
|
#define CONFIG_SM_PWM_01C_WINDOW_TIME (10 * US_PER_SEC)
|
|
#endif
|
|
|
|
#if defined(MODULE_SM_PWM_01C_MA) || defined(DOXYGEN)
|
|
/**
|
|
* @def SM_PWM_01C_BUFFER_LEN
|
|
*
|
|
* @brief Length in time of the measuring window
|
|
*/
|
|
#define SM_PWM_01C_BUFFER_LEN (CONFIG_SM_PWM_01C_WINDOW_TIME / \
|
|
CONFIG_SM_PWM_01C_SAMPLE_TIME)
|
|
#else
|
|
|
|
/**
|
|
* @def CONFIG_SM_PWM_01C_EXP_WEIGHT
|
|
*
|
|
* @brief Weight of the exponential average filter where:
|
|
* CONFIG_SM_PWM_01C_EXP_WEIGHT = 1 / (1 - alpha).
|
|
*
|
|
* @note Should be chosen wisely, it can be done my minimizing MSE
|
|
* or other algorithms as Marquardt procedure.
|
|
*/
|
|
#ifndef CONFIG_SM_PWM_01C_EXP_WEIGHT
|
|
#define CONFIG_SM_PWM_01C_EXP_WEIGHT (5)
|
|
#endif
|
|
#endif
|
|
|
|
/** @} */
|
|
|
|
#if defined(MODULE_SM_PWM_01C_MA) || defined(DOXYGEN)
|
|
/**
|
|
* @brief Circular buffer holding moving average values
|
|
* @internal
|
|
*
|
|
*/
|
|
typedef struct {
|
|
uint16_t buf[SM_PWM_01C_BUFFER_LEN]; /**< circular buffer memory */
|
|
size_t head; /**< current buffer head */
|
|
} circ_buf_t;
|
|
#endif
|
|
|
|
/**
|
|
* @brief Parameters for the SM_PWM_01c sensor
|
|
*
|
|
* These parameters are needed to configure the device at startup.
|
|
*/
|
|
typedef struct {
|
|
gpio_t tsp_pin; /**< Low Pulse Signal Output (P1) of small Particle,
|
|
active low, PM2.5 equivalent */
|
|
gpio_t tlp_pin; /**< Low Pulse Signal Output (P2) of large Particle,
|
|
active low, PM10 equivalent */
|
|
} sm_pwm_01c_params_t;
|
|
|
|
/**
|
|
* @brief LPO and concentration (ug/m3) values for small and large particles
|
|
*
|
|
* @note Actual measured particle size are: 1~ 2μm for small particles and 3 ~10μm,
|
|
* for large particles, but this values are exposed as standard PM2.5 and
|
|
* PM10 measurements.
|
|
*/
|
|
typedef struct {
|
|
uint16_t mc_pm_2p5; /**< Small particle concentration ug/m3 */
|
|
uint16_t mc_pm_10; /**< Large particle concentration ug/m3 */
|
|
} sm_pwm_01c_data_t;
|
|
|
|
/**
|
|
* @brief LPO and concentration (ug/m3) values for small and large particles
|
|
* @internal
|
|
*/
|
|
typedef struct {
|
|
uint32_t tsp_lpo; /**< Small particle low Pulse active time us */
|
|
uint32_t tlp_lpo; /**< Large Particle low Pulse active time us */
|
|
uint32_t tlp_start_time; /**< Last time tlp pin went low */
|
|
uint32_t tsp_start_time; /**< Last time tsp pin went low */
|
|
#ifdef MODULE_SM_PWM_01C_MA
|
|
circ_buf_t tsp_circ_buf; /**< Small particle moving average values */
|
|
circ_buf_t tlp_circ_buf; /**< Large particle moving average values */
|
|
#else
|
|
sm_pwm_01c_data_t data; /**< Current value for the exponentially averaged
|
|
particle concentration values */
|
|
#endif
|
|
} sm_pwm_01c_values_t;
|
|
|
|
/**
|
|
* @brief Device descriptor for the SM_PWM_01c sensor
|
|
*/
|
|
typedef struct {
|
|
sm_pwm_01c_params_t params; /**< Device driver parameters */
|
|
sm_pwm_01c_values_t _values; /**< Internal data to calculate concentration
|
|
from tsl/tsp low Pulse Output Occupancy */
|
|
ztimer_t _sampler; /**< internal sampling timer */
|
|
} sm_pwm_01c_t;
|
|
|
|
/**
|
|
* @brief Initialize the given SM_PWM_01C device
|
|
*
|
|
* @param[out] dev Initialized device descriptor of SM_PWM_01C device
|
|
* @param[in] params The parameters for the SM_PWM_01C device
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EIO GPIO error
|
|
*/
|
|
int sm_pwm_01c_init(sm_pwm_01c_t *dev, const sm_pwm_01c_params_t *params);
|
|
|
|
/**
|
|
* @brief Start continuous measurement of Large and Small particle
|
|
* concentrations
|
|
*
|
|
* @param[in] dev Device descriptor of SM_PWM_01C device
|
|
*/
|
|
void sm_pwm_01c_start(sm_pwm_01c_t *dev);
|
|
|
|
/**
|
|
* @brief Stops continuous measurement of Large and Small particle
|
|
* concentration
|
|
*
|
|
* @param[in] dev Device descriptor of SM_PWM_01C device
|
|
*/
|
|
void sm_pwm_01c_stop(sm_pwm_01c_t *dev);
|
|
|
|
/**
|
|
* @brief Reads particle concentration values
|
|
*
|
|
* @param[in] dev Device descriptor of SM_PWM_01C device
|
|
* @param[out] data Pre-allocated memory to hold measured concentrations
|
|
*
|
|
*/
|
|
void sm_pwm_01c_read_data(sm_pwm_01c_t *dev, sm_pwm_01c_data_t *data);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* SM_PWM_01C_H */
|
|
/** @} */
|