mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 04:52:59 +01:00
Merge pull request #16217 from fjmolinas/pr_driver_sm_pwm_01c
drivers/sm_pwm_01c: initial import
This commit is contained in:
commit
e7732d9a00
@ -121,6 +121,7 @@ rsource "shtc1/Kconfig"
|
||||
rsource "si70xx/Kconfig"
|
||||
rsource "si114x/Kconfig"
|
||||
rsource "si1133/Kconfig"
|
||||
rsource "sm_pwm_01c/Kconfig"
|
||||
rsource "sps30/Kconfig"
|
||||
rsource "srf02/Kconfig"
|
||||
rsource "srf04/Kconfig"
|
||||
|
207
drivers/include/sm_pwm_01c.h
Normal file
207
drivers/include/sm_pwm_01c.h
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* 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 */
|
||||
/** @} */
|
76
drivers/saul/init_devs/auto_init_sm_pwm_01c.c
Normal file
76
drivers/saul/init_devs/auto_init_sm_pwm_01c.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_auto_init_saul
|
||||
* @{
|
||||
* @file
|
||||
* @brief Auto initialization for SM_PWM_01C dust sensor
|
||||
*
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "assert.h"
|
||||
#include "log.h"
|
||||
#include "saul_reg.h"
|
||||
#include "sm_pwm_01c_params.h"
|
||||
#include "sm_pwm_01c.h"
|
||||
|
||||
/**
|
||||
* @brief Allocate memory for the device descriptors
|
||||
*/
|
||||
static sm_pwm_01c_t sm_pwm_01c_devs[SM_PWM_01C_NUMOF];
|
||||
|
||||
#if IS_ACTIVE(MODULE_SAUL)
|
||||
/**
|
||||
* @brief Memory for the SAUL registry entries
|
||||
*/
|
||||
static saul_reg_t saul_entries[SM_PWM_01C_NUMOF * 2];
|
||||
|
||||
/**
|
||||
* @brief Define the number of saul info
|
||||
*/
|
||||
#define SM_PWM_01C_INFO_NUM ARRAY_SIZE(sm_pwm_01c_saul_info)
|
||||
|
||||
/**
|
||||
* @name Import SAUL endpoints
|
||||
* @{
|
||||
*/
|
||||
extern const saul_driver_t sm_pwm_01c_saul_driver_mc_pm_2p5;
|
||||
extern const saul_driver_t sm_pwm_01c_saul_driver_mc_pm_10;
|
||||
/** @} */
|
||||
#endif
|
||||
|
||||
void auto_init_sm_pwm_01c(void)
|
||||
{
|
||||
#if IS_ACTIVE(MODULE_SAUL)
|
||||
assert(SM_PWM_01C_INFO_NUM == SM_PWM_01C_NUMOF);
|
||||
#endif
|
||||
|
||||
for (unsigned int i = 0; i < SM_PWM_01C_NUMOF; i++) {
|
||||
LOG_DEBUG("[auto_init_saul] initializing sm_pwm_01c #%u\n", i);
|
||||
|
||||
if (sm_pwm_01c_init(&sm_pwm_01c_devs[i], &sm_pwm_01c_params[i])) {
|
||||
LOG_ERROR("[auto_init_saul] error initializing sm_pwm_01c #%u\n",
|
||||
i);
|
||||
continue;
|
||||
}
|
||||
sm_pwm_01c_start(&sm_pwm_01c_devs[i]);
|
||||
#if IS_ACTIVE(MODULE_SAUL)
|
||||
saul_entries[(i * 2)].dev = &(sm_pwm_01c_devs[i]);
|
||||
saul_entries[(i * 2)].name = sm_pwm_01c_saul_info[i].name;
|
||||
saul_entries[(i * 2)].driver = &sm_pwm_01c_saul_driver_mc_pm_2p5;
|
||||
saul_entries[(i * 2) + 1].dev = &(sm_pwm_01c_devs[i]);
|
||||
saul_entries[(i * 2) + 1].name = sm_pwm_01c_saul_info[i].name;
|
||||
saul_entries[(i * 2) + 1].driver = &sm_pwm_01c_saul_driver_mc_pm_10;
|
||||
saul_reg_add(&(saul_entries[(i * 2)]));
|
||||
saul_reg_add(&(saul_entries[(i * 2) + 1]));
|
||||
#endif
|
||||
}
|
||||
}
|
@ -271,6 +271,10 @@ void saul_init_devs(void)
|
||||
extern void auto_init_si70xx(void);
|
||||
auto_init_si70xx();
|
||||
}
|
||||
if (IS_USED(MODULE_SM_PWM_01C)) {
|
||||
extern void auto_init_sm_pwm_01c(void);
|
||||
auto_init_sm_pwm_01c();
|
||||
}
|
||||
if (IS_USED(MODULE_SPS30)) {
|
||||
extern void auto_init_sps30(void);
|
||||
auto_init_sps30();
|
||||
|
60
drivers/sm_pwm_01c/Kconfig
Normal file
60
drivers/sm_pwm_01c/Kconfig
Normal file
@ -0,0 +1,60 @@
|
||||
# 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.
|
||||
#
|
||||
menuconfig MODULE_SM_PWM_01C
|
||||
bool "SM_PWM_01C Amphenol infrared dust sensor"
|
||||
depends on HAS_PERIPH_GPIO
|
||||
depends on HAS_PERIPH_GPIO_IRQ
|
||||
depends on TEST_KCONFIG
|
||||
select MODULE_CHECKSUM
|
||||
select MODULE_PERIPH_GPIO
|
||||
select MODULE_PERIPH_GPIO_IRQ
|
||||
select MODULE_ZTIMER
|
||||
select MODULE_ZTIMER_USEC
|
||||
select MODULE_ZTIMER_PERIPH_TIMER
|
||||
|
||||
config MODULE_SM_PWM_01C_MA
|
||||
bool "Use a moving average for sensor values"
|
||||
depends on MODULE_SM_PWM_01C
|
||||
default y
|
||||
|
||||
menuconfig KCONFIG_USEMODULE_SM_PWM_01C
|
||||
bool "Configure SM_PWM_01C driver"
|
||||
depends on USEMODULE_SM_PWM_01C
|
||||
help
|
||||
Configure the SM_PWM_01C driver using Kconfig.
|
||||
|
||||
if KCONFIG_USEMODULE_SM_PWM_01C
|
||||
|
||||
config SM_PWM_01C_WINDOW_TIME
|
||||
int "Measuring Window length"
|
||||
default 10000000
|
||||
help
|
||||
Length in time of the measuring window in microseconds,
|
||||
recommended 5-30s.
|
||||
|
||||
config SM_PWM_01C_SAMPLE_TIME
|
||||
int "PWM occupancy sampling period"
|
||||
default 100000
|
||||
help
|
||||
Time, expressed in microseconds, at witch LPO is occupancy is
|
||||
sampled and converted into particle matter concentration
|
||||
|
||||
if !USEMODULE_SM_PWM_01C_MA
|
||||
|
||||
config SM_PWM_01C_EXP_WEIGHT
|
||||
int "Weight of the exponential"
|
||||
default 100000
|
||||
help
|
||||
Weight of the exponential average filter where:
|
||||
SM_PWM_01C_EXP_WEIGHT = 1 / (1 - alpha).
|
||||
|
||||
Should be chosen wisely, it can be done my minimizing MSE
|
||||
or other algorithms as Marquardt procedure.
|
||||
|
||||
endif # USEMODULE_SM_PWM_01C_MA
|
||||
|
||||
endif # KCONFIG_USEMODULE_SM_PWM_01C
|
7
drivers/sm_pwm_01c/Makefile
Normal file
7
drivers/sm_pwm_01c/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
SRC := sm_pwm_01c.c
|
||||
|
||||
ifneq (,$(filter saul,$(USEMODULE)))
|
||||
SRC += sm_pwm_01c_saul.c
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
5
drivers/sm_pwm_01c/Makefile.dep
Normal file
5
drivers/sm_pwm_01c/Makefile.dep
Normal file
@ -0,0 +1,5 @@
|
||||
USEMODULE += ztimer_usec
|
||||
DEFAULT_MODULE += sm_pwm_01c_ma
|
||||
|
||||
FEATURES_REQUIRED += periph_gpio
|
||||
FEATURES_REQUIRED += periph_gpio_irq
|
4
drivers/sm_pwm_01c/Makefile.include
Normal file
4
drivers/sm_pwm_01c/Makefile.include
Normal file
@ -0,0 +1,4 @@
|
||||
USEMODULE_INCLUDES_sm_pwm_01c := $(LAST_MAKEFILEDIR)/include
|
||||
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_sm_pwm_01c)
|
||||
|
||||
PSEUDOMODULES += sm_pwm_01c_ma
|
80
drivers/sm_pwm_01c/include/sm_pwm_01c_params.h
Normal file
80
drivers/sm_pwm_01c/include/sm_pwm_01c_params.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_sm_pwm_01c
|
||||
* @{
|
||||
* @file
|
||||
* @brief Default configuration for SM_PWM_01C driver
|
||||
*
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SM_PWM_01C_PARAMS_H
|
||||
#define SM_PWM_01C_PARAMS_H
|
||||
|
||||
#include "board.h"
|
||||
#include "saul_reg.h"
|
||||
#include "sm_pwm_01c.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Set default configuration parameters for the SM_PWM_01C
|
||||
* @{
|
||||
*/
|
||||
#ifndef SM_PWM_01C_TSP_PIN
|
||||
#define SM_PWM_01C_TSP_PIN GPIO_PIN(0, 13)
|
||||
#endif
|
||||
#ifndef SM_PWM_01C_TLP_PIN
|
||||
#define SM_PWM_01C_TLP_PIN GPIO_PIN(0, 28)
|
||||
#endif
|
||||
#ifndef SM_PWM_01C_SAUL_INFO
|
||||
#define SM_PWM_01C_SAUL_INFO { .name = "sm-pwm-01c" }
|
||||
#endif
|
||||
|
||||
#ifndef SM_PWM_01C_PARAMS_DEFAULT
|
||||
#define SM_PWM_01C_PARAMS_DEFAULT { .tsp_pin = SM_PWM_01C_TSP_PIN, \
|
||||
.tlp_pin = SM_PWM_01C_TLP_PIN }
|
||||
#endif
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @brief Configure SM_PWM_01C
|
||||
*/
|
||||
static const sm_pwm_01c_params_t sm_pwm_01c_params[] =
|
||||
{
|
||||
#ifdef SM_PWM_01C_PARAMS_BOARD
|
||||
SM_PWM_01C_PARAMS_BOARD,
|
||||
#else
|
||||
SM_PWM_01C_PARAMS_DEFAULT
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Additional meta information to keep in the SAUL registry
|
||||
*/
|
||||
static const saul_reg_info_t sm_pwm_01c_saul_info[] =
|
||||
{
|
||||
SM_PWM_01C_SAUL_INFO
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The number of configured sensors
|
||||
*/
|
||||
#define SM_PWM_01C_NUMOF ARRAY_SIZE(sm_pwm_01c_params)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SM_PWM_01C_PARAMS_H */
|
||||
/** @} */
|
206
drivers/sm_pwm_01c/sm_pwm_01c.c
Normal file
206
drivers/sm_pwm_01c/sm_pwm_01c.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_sm_pwm_01c
|
||||
* @{
|
||||
* @file
|
||||
* @brief Implementation of SM_PWM_01C dust sensor
|
||||
*
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#include "sm_pwm_01c.h"
|
||||
#include "sm_pwm_01c_params.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
/* Scaling value to get 1/100 of a % resolution for lpo values */
|
||||
#define LPO_SCALING (100)
|
||||
|
||||
/* Circular average for moving average calculation, this is always
|
||||
called in irq context */
|
||||
#ifdef MODULE_SM_PWM_01C_MA
|
||||
static void _circ_buf_push(circ_buf_t *buf, uint16_t data)
|
||||
{
|
||||
buf->buf[buf->head] = data;
|
||||
buf->head = (buf->head + 1) % (SM_PWM_01C_BUFFER_LEN);
|
||||
}
|
||||
|
||||
static uint16_t _circ_buf_avg(circ_buf_t *buf)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (size_t i = 0; i < SM_PWM_01C_BUFFER_LEN; i++) {
|
||||
sum += buf->buf[i];
|
||||
}
|
||||
return (uint16_t)(sum / SM_PWM_01C_BUFFER_LEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Interval approximation of theoretical Dust Concentration / LPO % curve
|
||||
https://www.sgbotic.com/products/datasheets/sensors/app-SM-PWM-01C.pdf */
|
||||
static uint16_t _lpo_to_dust_cons(uint16_t lpo)
|
||||
{
|
||||
if (lpo <= (2 * LPO_SCALING)) {
|
||||
return (143 * lpo) / (2 * LPO_SCALING);
|
||||
}
|
||||
else if (lpo <= (4 * LPO_SCALING)) {
|
||||
return (208 * lpo + 130) / (3 * LPO_SCALING);
|
||||
}
|
||||
else if (lpo <= (15 * LPO_SCALING)) {
|
||||
return (1155 * lpo - 1572) / (10 * LPO_SCALING);
|
||||
}
|
||||
else {
|
||||
return (2354 * lpo - 19560) / (10 * LPO_SCALING);
|
||||
}
|
||||
}
|
||||
|
||||
static void _sample_timer_cb(void *arg)
|
||||
{
|
||||
sm_pwm_01c_t *dev = (sm_pwm_01c_t *)arg;
|
||||
|
||||
/* schedule next sample */
|
||||
ztimer_set(ZTIMER_USEC, &dev->_sampler, CONFIG_SM_PWM_01C_SAMPLE_TIME);
|
||||
DEBUG("[sm_pwm_01c] tsp_lpo %" PRIu32 "\n", dev->_values.tsp_lpo);
|
||||
DEBUG("[sm_pwm_01c] tlp_lpo %" PRIu32 "\n", dev->_values.tlp_lpo);
|
||||
|
||||
/* calculate low Pulse Output Occupancy in (% * LPO_SCALING),
|
||||
e.g. 1% -> 100 */
|
||||
uint16_t tsp_ratio =
|
||||
(uint16_t)((uint64_t)(100 * LPO_SCALING * dev->_values.tsp_lpo) /
|
||||
CONFIG_SM_PWM_01C_SAMPLE_TIME);
|
||||
uint16_t tlp_ratio =
|
||||
(uint16_t)((uint64_t)(100 * LPO_SCALING * dev->_values.tlp_lpo) /
|
||||
CONFIG_SM_PWM_01C_SAMPLE_TIME);
|
||||
DEBUG("[sm_pwm_01c] tsp_ratio %" PRIu16 "/%d %%\n", tsp_ratio, LPO_SCALING);
|
||||
DEBUG("[sm_pwm_01c] tlp_ratio %" PRIu16 "/%d %%\n", tlp_ratio, LPO_SCALING);
|
||||
|
||||
/* convert lpo to particle concentration */
|
||||
uint16_t tsp = _lpo_to_dust_cons(tsp_ratio);
|
||||
uint16_t tlp = _lpo_to_dust_cons(tlp_ratio);
|
||||
DEBUG("[sm_pwm_01c] new sample tsp conc: %" PRIu16 " ug/m3\n", tsp);
|
||||
DEBUG("[sm_pwm_01c] new sample tlp conc: %" PRIu16 " ug/m3\n", tlp);
|
||||
|
||||
/* update concentration values*/
|
||||
#ifdef MODULE_SM_PWM_01C_MA
|
||||
_circ_buf_push(&dev->_values.tsp_circ_buf, tsp);
|
||||
_circ_buf_push(&dev->_values.tlp_circ_buf, tlp);
|
||||
#else
|
||||
dev->_values.data.mc_pm_10 =
|
||||
(uint16_t)((tlp + (uint32_t)(CONFIG_SM_PWM_01C_EXP_WEIGHT - 1) *
|
||||
dev->_values.data.mc_pm_10) / CONFIG_SM_PWM_01C_EXP_WEIGHT);
|
||||
dev->_values.data.mc_pm_2p5 =
|
||||
(uint16_t)((tsp + (uint32_t)(CONFIG_SM_PWM_01C_EXP_WEIGHT - 1) *
|
||||
dev->_values.data.mc_pm_2p5) / CONFIG_SM_PWM_01C_EXP_WEIGHT);
|
||||
#endif
|
||||
|
||||
/* reset lpo */
|
||||
dev->_values.tlp_lpo = 0;
|
||||
dev->_values.tsp_lpo = 0;
|
||||
}
|
||||
|
||||
static void _tsp_pin_cb(void *arg)
|
||||
{
|
||||
sm_pwm_01c_t *dev = (sm_pwm_01c_t *)arg;
|
||||
uint32_t now = ztimer_now(ZTIMER_USEC);
|
||||
|
||||
if (gpio_read(dev->params.tsp_pin) == 0) {
|
||||
dev->_values.tsp_start_time = now;
|
||||
}
|
||||
else {
|
||||
dev->_values.tsp_lpo += (now - dev->_values.tsp_start_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void _tlp_pin_cb(void *arg)
|
||||
{
|
||||
sm_pwm_01c_t *dev = (sm_pwm_01c_t *)arg;
|
||||
uint32_t now = ztimer_now(ZTIMER_USEC);
|
||||
|
||||
if (gpio_read(dev->params.tlp_pin) == 0) {
|
||||
dev->_values.tlp_start_time = now;
|
||||
}
|
||||
else {
|
||||
dev->_values.tlp_lpo += (now - dev->_values.tlp_start_time);
|
||||
}
|
||||
}
|
||||
|
||||
int sm_pwm_01c_init(sm_pwm_01c_t *dev, const sm_pwm_01c_params_t *params)
|
||||
{
|
||||
dev->params = *params;
|
||||
|
||||
/* set up irq */
|
||||
if (gpio_init_int(dev->params.tsp_pin, GPIO_IN_PU, GPIO_BOTH, _tsp_pin_cb,
|
||||
dev) < 0) {
|
||||
DEBUG("[sm_pwm_01c] init_int of tsp_pin failed [ERROR]\n");
|
||||
return -EIO;
|
||||
}
|
||||
if (gpio_init_int(dev->params.tlp_pin, GPIO_IN_PU, GPIO_BOTH, _tlp_pin_cb,
|
||||
dev) < 0) {
|
||||
DEBUG("[sm_pwm_01c] init_int of tlp_pin failed [ERROR]\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* setup timer */
|
||||
dev->_sampler.callback = _sample_timer_cb;
|
||||
dev->_sampler.arg = dev;
|
||||
|
||||
#ifdef MODULE_SM_PWM_01C_MA
|
||||
memset(&dev->_values.tsp_circ_buf, 0, sizeof(circ_buf_t));
|
||||
memset(&dev->_values.tlp_circ_buf, 0, sizeof(circ_buf_t));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sm_pwm_01c_start(sm_pwm_01c_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
/* reset old values */
|
||||
memset((void *)&dev->_values, 0, sizeof(sm_pwm_01c_values_t));
|
||||
/* enable irq and set timer */
|
||||
ztimer_set(ZTIMER_USEC, &dev->_sampler, CONFIG_SM_PWM_01C_SAMPLE_TIME);
|
||||
gpio_irq_enable(dev->params.tsp_pin);
|
||||
gpio_irq_enable(dev->params.tlp_pin);
|
||||
DEBUG("[sm_pwm_01c] started average measurements\n");
|
||||
}
|
||||
|
||||
void sm_pwm_01c_stop(sm_pwm_01c_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
/* disable irq and remove timer */
|
||||
ztimer_remove(ZTIMER_USEC, &dev->_sampler);
|
||||
gpio_irq_disable(dev->params.tsp_pin);
|
||||
gpio_irq_disable(dev->params.tlp_pin);
|
||||
DEBUG("[sm_pwm_01c] stopped average measurements\n");
|
||||
}
|
||||
|
||||
void sm_pwm_01c_read_data(sm_pwm_01c_t *dev, sm_pwm_01c_data_t *data)
|
||||
{
|
||||
assert(dev);
|
||||
unsigned int state = irq_disable();
|
||||
#ifdef MODULE_SM_PWM_01C_MA
|
||||
data->mc_pm_10 = _circ_buf_avg(&dev->_values.tlp_circ_buf);
|
||||
data->mc_pm_2p5 = _circ_buf_avg(&dev->_values.tsp_circ_buf);
|
||||
#else
|
||||
data->mc_pm_10 = dev->_values.data.mc_pm_10;
|
||||
data->mc_pm_2p5 = dev->_values.data.mc_pm_2p5;
|
||||
#endif
|
||||
irq_restore(state);
|
||||
}
|
66
drivers/sm_pwm_01c/sm_pwm_01c_saul.c
Normal file
66
drivers/sm_pwm_01c/sm_pwm_01c_saul.c
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_sm_pwm_01c
|
||||
* @{
|
||||
* @file
|
||||
* @brief SAUL adaption of the SM_PWM_01C dust sensor driver
|
||||
*
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "phydat.h"
|
||||
#include "saul.h"
|
||||
#include "sm_pwm_01c.h"
|
||||
#include "sm_pwm_01c_params.h"
|
||||
|
||||
static int read_mc_pm_2p5(const void *_dev, phydat_t *data)
|
||||
{
|
||||
sm_pwm_01c_data_t values;
|
||||
sm_pwm_01c_t *dev = (sm_pwm_01c_t *)_dev;
|
||||
|
||||
sm_pwm_01c_read_data(dev, &values);
|
||||
data->unit = UNIT_GPM3;
|
||||
data->scale = -6;
|
||||
uint32_t value = values.mc_pm_2p5;
|
||||
phydat_fit(data, (int32_t *)&value, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_mc_pm_10(const void *_dev, phydat_t *data)
|
||||
{
|
||||
sm_pwm_01c_data_t values;
|
||||
sm_pwm_01c_t *dev = (sm_pwm_01c_t *)_dev;
|
||||
|
||||
sm_pwm_01c_read_data(dev, &values);
|
||||
data->unit = UNIT_GPM3;
|
||||
data->scale = -6;
|
||||
uint32_t value = values.mc_pm_10;
|
||||
phydat_fit(data, (int32_t *)&value, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const saul_driver_t sm_pwm_01c_saul_driver_mc_pm_10 = {
|
||||
.read = read_mc_pm_10,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_PM,
|
||||
.subtype = SAUL_SENSE_PM_10,
|
||||
};
|
||||
|
||||
const saul_driver_t sm_pwm_01c_saul_driver_mc_pm_2p5 = {
|
||||
.read = read_mc_pm_2p5,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_PM,
|
||||
.subtype = SAUL_SENSE_PM_2p5,
|
||||
};
|
@ -42,6 +42,7 @@ rsource "posix/Kconfig"
|
||||
rsource "oneway-malloc/Kconfig"
|
||||
rsource "phydat/Kconfig"
|
||||
rsource "pm_layered/Kconfig"
|
||||
rsource "progress_bar/Kconfig"
|
||||
rsource "ps/Kconfig"
|
||||
rsource "random/Kconfig"
|
||||
rsource "saul_reg/Kconfig"
|
||||
|
@ -29,50 +29,50 @@ extern "C" {
|
||||
/**
|
||||
* @brief Progress bar maximum characters length
|
||||
*/
|
||||
#ifndef PROGRESS_BAR_LENGTH
|
||||
#define PROGRESS_BAR_LENGTH (25U)
|
||||
#ifndef CONFIG_PROGRESS_BAR_LENGTH
|
||||
#define CONFIG_PROGRESS_BAR_LENGTH (25U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Progress bar character
|
||||
*/
|
||||
#ifndef PROGRESS_BAR_FULL_CHARACTER
|
||||
#define PROGRESS_BAR_FULL_CHARACTER "█"
|
||||
#ifndef CONFIG_PROGRESS_BAR_FULL_CHARACTER
|
||||
#define CONFIG_PROGRESS_BAR_FULL_CHARACTER "█"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Progress bar empty character
|
||||
*/
|
||||
#ifndef PROGRESS_BAR_EMPTY_CHARACTER
|
||||
#define PROGRESS_BAR_EMPTY_CHARACTER " "
|
||||
#ifndef CONFIG_PROGRESS_BAR_EMPTY_CHARACTER
|
||||
#define CONFIG_PROGRESS_BAR_EMPTY_CHARACTER " "
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Character displayed on the left of the progress bar
|
||||
*/
|
||||
#ifndef PROGRESS_BAR_PREFIX_CHARACTER
|
||||
#define PROGRESS_BAR_PREFIX_CHARACTER "|"
|
||||
#ifndef CONFIG_PROGRESS_BAR_PREFIX_CHARACTER
|
||||
#define CONFIG_PROGRESS_BAR_PREFIX_CHARACTER "|"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Character displayed on the left of the progress bar
|
||||
*/
|
||||
#ifndef PROGRESS_BAR_SUFFIX_CHARACTER
|
||||
#define PROGRESS_BAR_SUFFIX_CHARACTER "|"
|
||||
#ifndef CONFIG_PROGRESS_BAR_SUFFIX_CHARACTER
|
||||
#define CONFIG_PROGRESS_BAR_SUFFIX_CHARACTER "|"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Progress bar prefix max length
|
||||
*/
|
||||
#ifndef PROGRESS_BAR_PREFIX_MAX_LENGTH
|
||||
#define PROGRESS_BAR_PREFIX_MAX_LENGTH (32U)
|
||||
#ifndef CONFIG_PROGRESS_BAR_PREFIX_MAX_LENGTH
|
||||
#define CONFIG_PROGRESS_BAR_PREFIX_MAX_LENGTH (32U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Progress bar suffix max length
|
||||
*/
|
||||
#ifndef PROGRESS_BAR_SUFFIX_MAX_LENGTH
|
||||
#define PROGRESS_BAR_SUFFIX_MAX_LENGTH (32U)
|
||||
#ifndef CONFIG_PROGRESS_BAR_SUFFIX_MAX_LENGTH
|
||||
#define CONFIG_PROGRESS_BAR_SUFFIX_MAX_LENGTH (32U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -82,9 +82,9 @@ typedef struct {
|
||||
/** Current value of the progress bar. Must be between 0 and 100 (included) */
|
||||
uint8_t value;
|
||||
/** Prefix displayed on the left of the progress bar */
|
||||
char prefix[PROGRESS_BAR_PREFIX_MAX_LENGTH];
|
||||
char prefix[CONFIG_PROGRESS_BAR_PREFIX_MAX_LENGTH];
|
||||
/** Suffix displayed on the right of the progress bar */
|
||||
char suffix[PROGRESS_BAR_SUFFIX_MAX_LENGTH];
|
||||
char suffix[CONFIG_PROGRESS_BAR_SUFFIX_MAX_LENGTH];
|
||||
} progress_bar_t;
|
||||
|
||||
/**
|
||||
|
58
sys/progress_bar/Kconfig
Normal file
58
sys/progress_bar/Kconfig
Normal file
@ -0,0 +1,58 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
config MODULE_PROGRESS_BAR
|
||||
bool "A simple CLI progress bar"
|
||||
depends on TEST_KCONFIG
|
||||
|
||||
menuconfig KCONFIG_USEMODULE_PROGRESS_BAR
|
||||
bool "Configure progress bar module"
|
||||
depends on USEMODULE_PROGRESS_BAR
|
||||
help
|
||||
Configure the progress bar module using Kconfig.
|
||||
|
||||
if KCONFIG_USEMODULE_PROGRESS_BAR
|
||||
|
||||
config PROGRESS_BAR_LENGTH
|
||||
int "Progress bar length"
|
||||
default 25
|
||||
help
|
||||
Progress bar maximum characters length
|
||||
|
||||
config PROGRESS_BAR_FULL_CHARACTER
|
||||
string "Progress bar character"
|
||||
default "█"
|
||||
help
|
||||
The character that will be printed when the progress bar fills up.
|
||||
|
||||
config PROGRESS_BAR_EMPTY_CHARACTER
|
||||
string "Progress bar empty character"
|
||||
default " "
|
||||
help
|
||||
The character that will be printed when the progress bar empties.
|
||||
|
||||
config PROGRESS_BAR_PREFIX_CHARACTER
|
||||
string "Progress bar prefix"
|
||||
default "|"
|
||||
help
|
||||
Character displayed on the left of the progress bar
|
||||
|
||||
config PROGRESS_BAR_SUFFIX_CHARACTER
|
||||
string "Progress bar suffix"
|
||||
default "|"
|
||||
help
|
||||
Character displayed on the left of the progress bar
|
||||
|
||||
config PROGRESS_BAR_PREFIX_MAX_LENGTH
|
||||
int "Progress bar prefix max length"
|
||||
default 32
|
||||
|
||||
config PROGRESS_BAR_SUFFIX_MAX_LENGTH
|
||||
int "Progress bar suffix max length"
|
||||
default 32
|
||||
|
||||
endif # KCONFIG_USEMODULE_PROGRESS_BAR
|
@ -44,19 +44,19 @@ void progress_bar_print(char *prefix, char *suffix, uint8_t value)
|
||||
printf("%s", prefix);
|
||||
}
|
||||
|
||||
printf(PROGRESS_BAR_PREFIX_CHARACTER);
|
||||
printf(CONFIG_PROGRESS_BAR_PREFIX_CHARACTER);
|
||||
|
||||
/* Fully reprint the progress bar */
|
||||
for (unsigned i = 0; i < PROGRESS_BAR_LENGTH; ++i) {
|
||||
if (100 * i < (uint16_t)(value * PROGRESS_BAR_LENGTH)) {
|
||||
printf(PROGRESS_BAR_FULL_CHARACTER);
|
||||
for (unsigned i = 0; i < CONFIG_PROGRESS_BAR_LENGTH; ++i) {
|
||||
if (100 * i < (uint16_t)(value * CONFIG_PROGRESS_BAR_LENGTH)) {
|
||||
printf(CONFIG_PROGRESS_BAR_FULL_CHARACTER);
|
||||
}
|
||||
else {
|
||||
printf(PROGRESS_BAR_EMPTY_CHARACTER);
|
||||
printf(CONFIG_PROGRESS_BAR_EMPTY_CHARACTER);
|
||||
}
|
||||
}
|
||||
|
||||
printf(PROGRESS_BAR_SUFFIX_CHARACTER);
|
||||
printf(CONFIG_PROGRESS_BAR_SUFFIX_CHARACTER);
|
||||
|
||||
/* Display progress bar suffix if any */
|
||||
if (suffix) {
|
||||
|
8
tests/driver_sm_pwm_01c/Makefile
Normal file
8
tests/driver_sm_pwm_01c/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
BOARD ?= samr21-xpro
|
||||
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEMODULE += progress_bar
|
||||
USEMODULE += sm_pwm_01c
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
3
tests/driver_sm_pwm_01c/Makefile.ci
Normal file
3
tests/driver_sm_pwm_01c/Makefile.ci
Normal file
@ -0,0 +1,3 @@
|
||||
BOARD_INSUFFICIENT_MEMORY := \
|
||||
nucleo-l011k4
|
||||
#
|
27
tests/driver_sm_pwm_01c/README.md
Normal file
27
tests/driver_sm_pwm_01c/README.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Test Application for the Amphenol SM_PWM_01C infrared dust sensor
|
||||
|
||||
## About
|
||||
|
||||
This is a simple test application for the SM_PWM_01C driver.
|
||||
|
||||
## Expected result
|
||||
|
||||
If everything works then you should see the progress bar vary if dust
|
||||
concentration changes in the room, or manually block the infrared inputs
|
||||
to force a change.
|
||||
|
||||
Overly exaggerated values (blocked infrared sensor) can be seen here:
|
||||
|
||||
```
|
||||
# main(): This is RIOT! (Version: 2021.04-devel-1044-gfd36c-HEAD)
|
||||
# sm_pwm_01c driver test application
|
||||
# starting weighted average PM2.5 and PM10 measurements
|
||||
#
|
||||
# PM2.5 level: 1272 ug/m3|███████████ |
|
||||
# PM10 level: 490 ug/m3|████ |
|
||||
````
|
||||
|
||||
## Details
|
||||
|
||||
By default a moving average over a 30s window is returned ad the
|
||||
read value. The progress bar is updated every 200ms.
|
6
tests/driver_sm_pwm_01c/app.config.test
Normal file
6
tests/driver_sm_pwm_01c/app.config.test
Normal file
@ -0,0 +1,6 @@
|
||||
# this file enables modules defined in Kconfig. Do not use this file for
|
||||
# application configuration. This is only needed during migration.
|
||||
CONFIG_MODULE_SM_PWM_01C=y
|
||||
CONFIG_MODULE_ZTIMER=y
|
||||
CONFIG_MODULE_ZTIMER_USEC=y
|
||||
CONFIG_MODULE_PROGRESS_BAR=y
|
61
tests/driver_sm_pwm_01c/main.c
Normal file
61
tests/driver_sm_pwm_01c/main.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
* @file
|
||||
* @brief Test application for SM_PWM_01C driver
|
||||
*
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ztimer.h"
|
||||
|
||||
#include "sm_pwm_01c.h"
|
||||
#include "sm_pwm_01c_params.h"
|
||||
|
||||
#include "progress_bar.h"
|
||||
|
||||
static progress_bar_t progress_bar_list[2];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
sm_pwm_01c_t dev;
|
||||
|
||||
puts("sm_pwm_01c driver test application");
|
||||
if (sm_pwm_01c_init(&dev, &sm_pwm_01c_params[0]) != 0) {
|
||||
puts("init device [ERROR]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
puts("starting weighted average PM2.5 and PM10 measurements\n");
|
||||
sm_pwm_01c_start(&dev);
|
||||
progress_bar_prepare_multi(2);
|
||||
|
||||
while (1) {
|
||||
ztimer_sleep(ZTIMER_USEC, 200 * US_PER_MS);
|
||||
sm_pwm_01c_data_t data;
|
||||
sm_pwm_01c_read_data(&dev, &data);
|
||||
sprintf(progress_bar_list[0].prefix,
|
||||
"%s %4d ug/m3", "PM2.5 level:",
|
||||
data.mc_pm_2p5);
|
||||
sprintf(progress_bar_list[1].prefix, "%s %4d ug/m3", "PM10 level:",
|
||||
data.mc_pm_10);
|
||||
progress_bar_list[0].value = data.mc_pm_2p5 >
|
||||
3000 ? 100 : (data.mc_pm_2p5 * 100) / 3000;
|
||||
progress_bar_list[1].value = data.mc_pm_10 >
|
||||
3000 ? 100 : (data.mc_pm_10 * 100) / 3000;
|
||||
progress_bar_update_multi(progress_bar_list, 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -3,24 +3,24 @@ include ../Makefile.tests_common
|
||||
USEMODULE += xtimer
|
||||
USEMODULE += progress_bar
|
||||
|
||||
PROGRESS_BAR_LENGTH ?= 50
|
||||
PROGRESS_BAR_FULL_CHARACTER ?= "█"
|
||||
PROGRESS_BAR_EMPTY_CHARACTER ?= " "
|
||||
CONFIG_PROGRESS_BAR_LENGTH ?= 50
|
||||
CONFIG_PROGRESS_BAR_FULL_CHARACTER ?= "█"
|
||||
CONFIG_PROGRESS_BAR_EMPTY_CHARACTER ?= " "
|
||||
|
||||
# Other nice progress bar characters:
|
||||
#PROGRESS_BAR_FULL_CHARACTER ?= "◉"
|
||||
#PROGRESS_BAR_EMPTY_CHARACTER ?= "◯"
|
||||
#PROGRESS_BAR_FULL_CHARACTER ?= "▣"
|
||||
#PROGRESS_BAR_EMPTY_CHARACTER ?= "▢"
|
||||
#CONFIG_PROGRESS_BAR_FULL_CHARACTER ?= "◉"
|
||||
#CONFIG_PROGRESS_BAR_EMPTY_CHARACTER ?= "◯"
|
||||
#CONFIG_PROGRESS_BAR_FULL_CHARACTER ?= "▣"
|
||||
#CONFIG_PROGRESS_BAR_EMPTY_CHARACTER ?= "▢"
|
||||
|
||||
CFLAGS += -DPROGRESS_BAR_FULL_CHARACTER=\"$(PROGRESS_BAR_FULL_CHARACTER)\"
|
||||
CFLAGS += -DPROGRESS_BAR_EMPTY_CHARACTER=\"$(PROGRESS_BAR_EMPTY_CHARACTER)\"
|
||||
CFLAGS += -DPROGRESS_BAR_LENGTH=$(PROGRESS_BAR_LENGTH)
|
||||
CFLAGS += -DCONFIG_PROGRESS_BAR_FULL_CHARACTER=\"$(CONFIG_PROGRESS_BAR_FULL_CHARACTER)\"
|
||||
CFLAGS += -DCONFIG_PROGRESS_BAR_EMPTY_CHARACTER=\"$(CONFIG_PROGRESS_BAR_EMPTY_CHARACTER)\"
|
||||
CFLAGS += -DCONFIG_PROGRESS_BAR_LENGTH=$(CONFIG_PROGRESS_BAR_LENGTH)
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
||||
# Make custom progress bar characters available in Python test script via
|
||||
# environment variables
|
||||
export PROGRESS_BAR_FULL_CHARACTER
|
||||
export PROGRESS_BAR_EMPTY_CHARACTER
|
||||
export PROGRESS_BAR_LENGTH
|
||||
export CONFIG_PROGRESS_BAR_FULL_CHARACTER
|
||||
export CONFIG_PROGRESS_BAR_EMPTY_CHARACTER
|
||||
export CONFIG_PROGRESS_BAR_LENGTH
|
||||
|
@ -12,9 +12,9 @@ from testrunner import run
|
||||
|
||||
|
||||
TIMEOUT = 60
|
||||
LENGTH = int(os.getenv('PROGRESS_BAR_LENGTH'))
|
||||
FULL_CHARACTER = os.getenv('PROGRESS_BAR_FULL_CHARACTER')[1:-1]
|
||||
EMPTY_CHARACTER = os.getenv('PROGRESS_BAR_EMPTY_CHARACTER')[1:-1]
|
||||
LENGTH = int(os.getenv('CONFIG_PROGRESS_BAR_LENGTH'))
|
||||
FULL_CHARACTER = os.getenv('CONFIG_PROGRESS_BAR_FULL_CHARACTER')[1:-1]
|
||||
EMPTY_CHARACTER = os.getenv('CONFIG_PROGRESS_BAR_EMPTY_CHARACTER')[1:-1]
|
||||
|
||||
|
||||
def testfunc(child):
|
||||
|
Loading…
Reference in New Issue
Block a user