Skip to content

Commit

Permalink
Make duty-cycling runtime configurable with timers for sample period …
Browse files Browse the repository at this point in the history
…and warmup time
  • Loading branch information
posjodin committed Oct 10, 2017
1 parent 0e9b67c commit 250939c
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 33 deletions.
102 changes: 77 additions & 25 deletions dev/pms5003/pms5003.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ static uint32_t invalid_frames, valid_frames;

/* Sensor configured on? */
static uint8_t configured_on = 0;
/* When sensor entered current power save mode, in clock_seconds()*/
static unsigned long when_mode;

/* Last readings of sensor data */
static uint16_t PM1, PM2_5, PM10;
Expand All @@ -91,6 +89,11 @@ static uint8_t rxbuf_data[PMS_BUFSIZE];
static int uart_input_byte(unsigned char);
#endif /* PMS_SERIAL_UART */

static struct pms_config {
unsigned sample_period; /* Time between samples (sec) */
unsigned warmup_interval; /* Warmup time (sec) */
} pms_config;

/*---------------------------------------------------------------------------*/
#if PMS_SERIAL_UART
PROCESS(pms5003_uart_process, "PMS5003/UART dust sensor process");
Expand All @@ -105,6 +108,9 @@ PROCESS(pms5003_timer_process, "PMS5003 periodic dust sensor process");
void
pms5003_init()
{
pms5003_config_sample_period(PMS_SAMPLE_PERIOD);
pms5003_config_warmup_interval(PMS_WARMUP_INTERVAL);

pms5003_event = process_alloc_event();
process_start(&pms5003_timer_process, NULL);

Expand All @@ -117,8 +123,9 @@ pms5003_init()
configured_on = 1;

#ifdef DEBUG
printf("PMS5003: UART %d, I2C %d, sample period %d, startup interval %d\n",
PMS_SERIAL_UART, PMS_SERIAL_I2C, PMS_SAMPLE_PERIOD, PMS_STARTUP_INTERVAL);
printf("PMS5003: UART %d, I2C %d, sample period %d, warmup interval %d\n",
PMS_SERIAL_UART, PMS_SERIAL_I2C,
pms_config.sample_period, pms_config.warmup_interval);
#endif /* DEBUG */
}
/*---------------------------------------------------------------------------*/
Expand Down Expand Up @@ -207,6 +214,46 @@ pms5003_invalid_frames()
{
return invalid_frames;
}

void
pms5003_config_sample_period(unsigned int sample_period) {
pms_config.sample_period = sample_period;
}

void
pms5003_config_warmup_interval(unsigned int warmup_interval) {
pms_config.warmup_interval = warmup_interval;
}

unsigned
pms5003_get_sample_period(void) {
return pms_config.sample_period;
}

unsigned
pms5003_get_warmup_interval(void) {
return pms_config.warmup_interval;
}

/*---------------------------------------------------------------------------*/
/**
* Check if it is time to put sensor in standby mode.
* The condition is that the time from when last sample was taken until the
* next is due, is greater than the time it takes to wake up the sensor.
*/
static int
timetosleep(void) {
return (timestamp + pms_config.sample_period >
clock_seconds() + pms_config.warmup_interval);
}
/*---------------------------------------------------------------------------*/
/**
* Check if it is time to get the next sample.
*/
static int
timetoread(void) {
return (clock_seconds() - timestamp >= pms_config.sample_period);
}
/*---------------------------------------------------------------------------*/
/**
* Validate frame by checking preamble, length field and checksum.
Expand All @@ -218,7 +265,7 @@ check_pmsframe(uint8_t *buf)
int sum, pmssum;
int i;
int len;

if(buf[0] != PRE1 || buf[1] != PRE2) {
return 0;
}
Expand Down Expand Up @@ -308,7 +355,6 @@ static
PT_THREAD(pms5003_uart_fsm_pt(struct pt *pt, uint8_t data)) {
static uint8_t buf[PMSBUFFER], *bufp;
static int remain;
static unsigned long mode_secs;

PT_BEGIN(pt);
bufp = buf;
Expand Down Expand Up @@ -337,17 +383,16 @@ PT_THREAD(pms5003_uart_fsm_pt(struct pt *pt, uint8_t data)) {
*bufp++ = data;
}
/* We have a frame! */
mode_secs = clock_seconds() - when_mode;
/* Frames received while sensor is starting up are ignored */
if((pms5003_get_standby_mode() == STANDBY_MODE_OFF) &&
(mode_secs >= PMS_STARTUP_INTERVAL)) {
/* Is it time for next reading? Otherwise ignore. */
if(timetoread()) {
/* Check frame and update sensor readings */
if(pmsframe(buf)) {
/* Tell other processes there is new data */
(void)process_post(PROCESS_BROADCAST, pms5003_event, NULL);
/* Enter standby mode */
pms5003_set_standby_mode(STANDBY_MODE_ON);
when_mode = clock_seconds();
/* Put sensor in standby mode? */
if(timetosleep()) {
pms5003_set_standby_mode(STANDBY_MODE_ON);
}
}
}
}
Expand Down Expand Up @@ -399,13 +444,22 @@ PROCESS_THREAD(pms5003_uart_process, ev, data)
PROCESS_THREAD(pms5003_timer_process, ev, data)
{
static struct etimer pmstimer;
static unsigned long mode_secs;
static uint8_t standbymode;

PROCESS_BEGIN();
etimer_set(&pmstimer, CLOCK_SECOND * PMS_PROCESS_PERIOD);
pms5003_set_standby_mode(STANDBY_MODE_ON);
when_mode = clock_seconds();

/* Pretend there is a fresh reading, to postpone the first
* reading for one cycle
*/
timestamp = clock_seconds();

/* Put sensor in standby, if there is enough time */
if(timetosleep())
pms5003_set_standby_mode(STANDBY_MODE_ON);
else
pms5003_set_standby_mode(STANDBY_MODE_OFF);

pms5003_event = process_alloc_event();

/* Main loop */
Expand All @@ -416,13 +470,12 @@ PROCESS_THREAD(pms5003_timer_process, ev, data)
}

if((ev == PROCESS_EVENT_TIMER) && (data == &pmstimer)) {
mode_secs = clock_seconds() - when_mode;
standbymode = pms5003_get_standby_mode();
if(standbymode == STANDBY_MODE_OFF) {
#if PMS_SERIAL_I2C
static uint8_t buf[PMSBUFFER];
/* Read data over I2C if it is time */
if(mode_secs >= PMS_STARTUP_INTERVAL) {
if(timetoread()) {
if(pms5003_i2c_probe()) {
leds_on(LEDS_RED);
i2c_read_mem(I2C_PMS5003_ADDR, 0, buf, PMSBUFFER);
Expand All @@ -432,19 +485,18 @@ PROCESS_THREAD(pms5003_timer_process, ev, data)
if(process_post(PROCESS_BROADCAST, pms5003_event, NULL) == PROCESS_ERR_OK) {
PROCESS_WAIT_EVENT_UNTIL(ev == pms5003_event);
}
pms5003_set_standby_mode(STANDBY_MODE_ON);
when_mode = clock_seconds();
/* Put sensor in standby, if there is enough time */
if(timetosleep()) {
pms5003_set_standby_mode(STANDBY_MODE_ON);
}
}
}
}
#else
/* Do nothing -- UART process puts sensor in standby */
;
#endif /* PMS_SERIAL_I2C */
} else if(standbymode == STANDBY_MODE_ON) {
if(mode_secs >= (PMS_SAMPLE_PERIOD - PMS_STARTUP_INTERVAL)) {
/* Time to warm up sensor for next reading? */
if(!timetosleep()) {
pms5003_set_standby_mode(STANDBY_MODE_OFF);
when_mode = clock_seconds();
}
}
etimer_reset(&pmstimer);
Expand Down
20 changes: 12 additions & 8 deletions dev/pms5003/pms5003.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#ifndef PMS5003_H
#define PMS5003_H

/* How often sensor process runs (secs) -- defines resolution
/* How often sensor process runs (sec) -- defines resolution
* of warmup time and sample period
*/
#ifdef PMS5003_CONF_PROCESS_PERIOD
Expand All @@ -45,19 +45,19 @@
#define PMS_PROCESS_PERIOD 5
#endif /* PMS5003_CONF_PROCESS_PERIOD */

/* How often sensor data is collected (secs) */
/* Default sample period - how often sensor data is collected (sec) */
#ifdef PMS5003_CONF_SAMPLE_PERIOD
#define PMS_SAMPLE_PERIOD PMS5003_CONF_SAMPLE_PERIOD
#else
#define PMS_SAMPLE_PERIOD 30
#define PMS_SAMPLE_PERIOD 60
#endif /* PMS5003_CONF_SAMPLE_PERIOD */

/* Warmup time before sensor data can be read (secs) */
#ifdef PMS5003_CONF_STARTUP_INTERVAL
#define PMS_STARTUP_INTERVAL PMS5003_CONF_STARTUP_INTERVAL
/* Default warmup time before sensor data can be read (sec) */
#ifdef PMS5003_CONF_WARMUP_INTERVAL
#define PMS_WARMUP_INTERVAL PMS5003_CONF_WARMUP_INTERVAL
#else
#define PMS_STARTUP_INTERVAL 10
#endif /* PMS5003_STARTUP_INTERVAL */
#define PMS_WARMUP_INTERVAL 30
#endif /* PMS5003_WARMUP_INTERVAL */

/* Use I2C interface? */
#ifdef PMS5003_CONF_SERIAL_I2C
Expand Down Expand Up @@ -108,5 +108,9 @@ uint16_t pms5003_db2_5();
uint16_t pms5003_db5();
uint16_t pms5003_db10();
uint32_t pms5003_timestamp();
void pms5003_config_sample_period(unsigned int);
void pms5003_config_warmup_interval(unsigned int);
unsigned pms5003_get_sample_period(void);
unsigned pms5003_get_warmup_interval(void);

#endif /* PMS5003_H */

0 comments on commit 250939c

Please sign in to comment.