Skip to content

Commit b72913b

Browse files
committed
Added accelerometer-triggered sleep
-switchable at compile time with CONFIG_ACCEL_SLEEP flag - maintain ring buffer of 3d acceleration readings (10 samples) - compute RMS difference between last acceleration sample and buffered readings (10 samples, 10 seconds) - if difference is below a preset threshold for more than 5 minutes, send the tag to sleep - sleep is like hibernation, except we keep reading accelerometer - if RMS difference exceeds threshold, wake up tag - added sleep status to the flags field of the status packet
1 parent ca4739c commit b72913b

File tree

7 files changed

+113
-10
lines changed

7 files changed

+113
-10
lines changed

firmware/nRF51/tag-proximity/inc/acc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,6 @@ extern uint8_t acc_init(void);
7474
extern void acc_write(uint8_t cmd, uint8_t data);
7575
extern void acc_read(uint8_t cmd, uint8_t len, uint8_t *data);
7676
extern void acc_sample(void);
77-
extern int16_t tag_acc(uint8_t axis);
77+
extern int16_t acc_get(uint8_t axis);
7878

7979
#endif/*__ACC_H__*/

firmware/nRF51/tag-proximity/inc/config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
/* log to flash */
2929
#define CONFIG_FLASH_LOGGING 1
3030

31+
/* accelerometer-based sleep */
32+
#define CONFIG_ACCEL_SLEEP 1
33+
3134
/* blink on receiving a proximity packet */
3235
#define CONFIG_PROXIMITY_BLINK 0
3336

firmware/nRF51/tag-proximity/inc/main.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ extern uint8_t status_flags;
3131
extern uint8_t boot_count;
3232
extern uint32_t reset_reason;
3333

34+
#if CONFIG_ACCEL_SLEEP
35+
extern uint8_t sleep;
36+
#endif
37+
3438
extern void blink(uint8_t times);
3539
extern void blink_fast(uint8_t times);
3640
extern uint16_t blink_wait_release(void);

firmware/nRF51/tag-proximity/inc/openbeacon-proto.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
#define FLAG_BOOT (1 << 0)
4343
#define FLAG_TIME_RESET (1 << 1)
44-
#define FLAG_HIBERNATE (1 << 2)
44+
#define FLAG_SLEEP (1 << 2)
4545
#define FLAG_LOG_STOPPED (1 << 3)
4646
#define ERROR_FLASH_WRITE (1 << 4)
4747
#define ERROR_LOG_BUF_OVERRUN (1 << 5)

firmware/nRF51/tag-proximity/src/acc.c

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
2525
*/
2626
#include <openbeacon.h>
27+
#include <main.h>
2728
#include <acc.h>
2829
#include <timer.h>
2930

@@ -40,6 +41,19 @@ static const uint8_t g_acc_init[][2] = {
4041
/* most recent acceleration measurement */
4142
static int16_t acc[3];
4243

44+
#if CONFIG_ACCEL_SLEEP
45+
#define ACC_BUFFER_LEN 10
46+
#define ACC_DELTA_THRES 100000L
47+
#define ACC_SLEEP_THRES 300
48+
49+
static int16_t acc_buffer[ACC_BUFFER_LEN][3];
50+
static int32_t acc_avg[3];
51+
static uint8_t acc_buffer_index;
52+
static uint8_t acc_buffer_full;
53+
static uint16_t sleep_counter;
54+
static uint8_t moving;
55+
#endif /* CONFIG_ACCEL_SLEEP */
56+
4357

4458
void acc_write(uint8_t cmd, uint8_t data)
4559
{
@@ -88,17 +102,70 @@ void acc_read(uint8_t cmd, uint8_t len, uint8_t *data)
88102
}
89103

90104

105+
#if CONFIG_ACCEL_SLEEP
106+
static void acc_process_sample(void)
107+
{
108+
int16_t acc_delta;
109+
uint32_t acc_delta_norm = 0;
110+
uint8_t i, j;
111+
112+
if (acc_buffer_full)
113+
{
114+
acc_delta_norm = 0;
115+
116+
for (i=0; i<3; i++)
117+
{
118+
acc_avg[i] = 0;
119+
for (j=0; j<ACC_BUFFER_LEN; j++)
120+
acc_avg[i] += acc_buffer[j][i];
121+
acc_avg[i] /= ACC_BUFFER_LEN;
122+
123+
acc_delta = acc[i] - acc_avg[i];
124+
acc_delta_norm += acc_delta * acc_delta;
125+
}
126+
127+
if (acc_delta_norm < ACC_DELTA_THRES)
128+
{
129+
moving = 0;
130+
if (!sleep && ++sleep_counter > ACC_SLEEP_THRES)
131+
sleep = 1;
132+
} else {
133+
moving = 1;
134+
sleep = 0;
135+
sleep_counter = 0;
136+
acc_buffer_index = 0;
137+
acc_buffer_full = 0;
138+
}
139+
}
140+
141+
for (i=0; i<3; i++)
142+
acc_buffer[acc_buffer_index][i] = acc[i];
143+
144+
acc_buffer_index++;
145+
if (acc_buffer_index == ACC_BUFFER_LEN)
146+
acc_buffer_index = 0;
147+
148+
if (!acc_buffer_full && !acc_buffer_index)
149+
acc_buffer_full = 1;
150+
}
151+
#endif /* CONFIG_ACCEL_SLEEP */
152+
153+
91154
void acc_sample(void)
92155
{
93156
/* briefly turn on accelerometer */
94157
acc_write(ACC_REG_CTRL_REG1, 0x97);
95158
timer_wait(MILLISECONDS(2));
96159
acc_read(ACC_REG_OUT_X, sizeof(acc), (uint8_t*)&acc);
97160
acc_write(ACC_REG_CTRL_REG1, 0x00);
161+
162+
#if CONFIG_ACCEL_SLEEP
163+
acc_process_sample();
164+
#endif
98165
}
99166

100167

101-
inline int16_t tag_acc(uint8_t axis)
168+
inline int16_t acc_get(uint8_t axis)
102169
{
103170
return acc[axis];
104171
}
@@ -147,6 +214,14 @@ uint8_t acc_init(void)
147214
for(i=0; i<ACC_INIT_COUNT; i++)
148215
acc_write(g_acc_init[i][0], g_acc_init[i][1]);
149216

217+
#if CONFIG_ACCEL_SLEEP
218+
acc_buffer_index = 0;
219+
acc_buffer_full = 0;
220+
moving = 1;
221+
sleep = 0;
222+
sleep_counter = 0;
223+
#endif /* CONFIG_ACCEL_SLEEP */
224+
150225
/* make first measurement */
151226
acc_sample();
152227

firmware/nRF51/tag-proximity/src/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
#include <log.h>
3535
#endif
3636

37+
#if CONFIG_ACCEL_SLEEP
38+
uint8_t sleep = 0;
39+
#endif
40+
3741
uint8_t hibernate = 0;
3842
uint8_t status_flags = 0;
3943
uint8_t boot_count;

firmware/nRF51/tag-proximity/src/radio.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ void RTC0_IRQ_Handler(void)
133133
/* increment time */
134134
g_time++;
135135

136+
#if !CONFIG_ACCEL_SLEEP
136137
if (!hibernate)
138+
#else
139+
if (!hibernate && !sleep)
140+
#endif
137141
{
138142
/* schedule tracker TX */
139143
if(!g_request_tx)
@@ -157,7 +161,11 @@ void RTC0_IRQ_Handler(void)
157161
rng(CONFIG_PROX_SPACING_RNG_BITS);
158162
NRF_RTC0->CC[1] = NRF_RTC0->COUNTER + delta_t;
159163

164+
#if !CONFIG_ACCEL_SLEEP
160165
if (!hibernate)
166+
#else
167+
if (!hibernate && !sleep)
168+
#endif
161169
{
162170
/* start HF crystal oscillator */
163171
NRF_CLOCK->TASKS_HFCLKSTART = 1;
@@ -391,25 +399,34 @@ void RADIO_IRQ_Handler(void)
391399
g_pkt_tracker.p.status.rx_loss = (int16_t)((RX_LOSS*100)+0.5);
392400
g_pkt_tracker.p.status.tx_loss = (int16_t)((TX_LOSS*100)+0.5);
393401
g_pkt_tracker.p.status.ticks = NRF_RTC0->COUNTER + g_ticks_offset + g_pkt_tracker_ticks;
394-
g_pkt_tracker.p.status.acc_x = tag_acc(0);
395-
g_pkt_tracker.p.status.acc_y = tag_acc(1);
396-
g_pkt_tracker.p.status.acc_z = tag_acc(2);
402+
g_pkt_tracker.p.status.acc_x = acc_get(0);
403+
g_pkt_tracker.p.status.acc_y = acc_get(1);
404+
g_pkt_tracker.p.status.acc_z = acc_get(2);
397405
g_pkt_tracker.p.status.voltage = adc_bat();
398406
g_pkt_tracker.p.status.boot_count = boot_count;
399407

400408
g_pkt_tracker.p.status.info = 0;
401409
if (status_flags & FLAG_BOOT)
402410
g_pkt_tracker.p.status.info = (uint8_t) ( (reset_reason & 0x0F) | ((reset_reason >> 12) & 0x07) );
403411

412+
g_pkt_tracker.p.status.flags = status_flags;
413+
404414
#if CONFIG_FLASH_LOGGING
405415
g_pkt_tracker.p.status.flash_log_free_blocks = flash_log_free_blocks();
406-
g_pkt_tracker.p.status.flags = status_flags | (flash_log_running() ? 0 : FLAG_LOG_STOPPED);
407-
#else /* CONFIG_FLASH_LOGGING */
416+
if (!flash_log_running())
417+
g_pkt_tracker.p.status.flags |= FLAG_LOG_STOPPED;
418+
#endif /* CONFIG_FLASH_LOGGING */
419+
420+
#if CONFIG_ACCEL_SLEEP
421+
if (sleep)
422+
g_pkt_tracker.p.status.flags |= FLAG_SLEEP;
423+
#endif /* CONFIG_ACCEL_SLEEP */
424+
425+
#if !CONFIG_FLASH_LOGGING
408426
/* if we do not log to flash, reset status flags here.
409427
otherwise only reset when we log a status packet to flash */
410-
g_pkt_tracker.p.status.flags = status_flags;
411428
status_flags = 0;
412-
#endif /* CONFIG_FLASH_LOGGING */
429+
#endif /* !CONFIG_FLASH_LOGGING */
413430

414431
g_time_status_reported = g_time;
415432
}

0 commit comments

Comments
 (0)