Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Adafruit_GFX_128x64 DS3231 PinDetect SDFileSystem USBDevice mbed RealtimeMath MODSERIAL
process_data.cpp@9:a711b5b34d73, 2014-05-28 (annotated)
- Committer:
- ellingjp
- Date:
- Wed May 28 00:04:08 2014 +0000
- Revision:
- 9:a711b5b34d73
- Parent:
- 8:8430a5c0914c
- Child:
- 15:002bac432234
5/27/14
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ellingjp | 8:8430a5c0914c | 1 | #include "mbed.h" |
ellingjp | 8:8430a5c0914c | 2 | #include "process_data.h" |
ellingjp | 8:8430a5c0914c | 3 | #include "SystemTime.h" |
ellingjp | 8:8430a5c0914c | 4 | #include "debug.h" |
ellingjp | 8:8430a5c0914c | 5 | |
ellingjp | 9:a711b5b34d73 | 6 | #define THRESH 10000 |
ellingjp | 9:a711b5b34d73 | 7 | |
ellingjp | 8:8430a5c0914c | 8 | int window = 0; |
ellingjp | 8:8430a5c0914c | 9 | int16_t *history; |
ellingjp | 8:8430a5c0914c | 10 | int16_t prev_data = 0; |
ellingjp | 8:8430a5c0914c | 11 | |
ellingjp | 8:8430a5c0914c | 12 | Timer split_timer; |
ellingjp | 8:8430a5c0914c | 13 | |
ellingjp | 8:8430a5c0914c | 14 | /* Initializes the moving average with a window size */ |
ellingjp | 8:8430a5c0914c | 15 | bool process_init() |
ellingjp | 8:8430a5c0914c | 16 | { |
ellingjp | 8:8430a5c0914c | 17 | window = WINDOW_SIZE; |
ellingjp | 8:8430a5c0914c | 18 | history = new int16_t[WINDOW_SIZE](); // initializes to 0 |
ellingjp | 8:8430a5c0914c | 19 | |
ellingjp | 8:8430a5c0914c | 20 | split_timer.start(); |
ellingjp | 8:8430a5c0914c | 21 | return true; |
ellingjp | 8:8430a5c0914c | 22 | } |
ellingjp | 8:8430a5c0914c | 23 | |
ellingjp | 8:8430a5c0914c | 24 | /* Will break for window size > 2^8 |
ellingjp | 8:8430a5c0914c | 25 | * Returns a moving average for data |
ellingjp | 8:8430a5c0914c | 26 | * Returns INT16_MAX until it has received a window |
ellingjp | 8:8430a5c0914c | 27 | * size worth of data. These values should be ignored. */ |
ellingjp | 8:8430a5c0914c | 28 | int16_t mov_avg(int16_t data) |
ellingjp | 8:8430a5c0914c | 29 | { |
ellingjp | 8:8430a5c0914c | 30 | static uint8_t front = 0, end_ = 0, count = 0; |
ellingjp | 8:8430a5c0914c | 31 | static int32_t total; |
ellingjp | 8:8430a5c0914c | 32 | |
ellingjp | 8:8430a5c0914c | 33 | if (count < window-1) { |
ellingjp | 8:8430a5c0914c | 34 | history[end_] = data; |
ellingjp | 8:8430a5c0914c | 35 | end_ = end_ + 1; |
ellingjp | 8:8430a5c0914c | 36 | count = count + 1; |
ellingjp | 8:8430a5c0914c | 37 | return INT16_MAX; |
ellingjp | 8:8430a5c0914c | 38 | } else if (count == window-1) { |
ellingjp | 8:8430a5c0914c | 39 | history[end_] = data; |
ellingjp | 8:8430a5c0914c | 40 | for (int i = 0; i <= count; i++) |
ellingjp | 8:8430a5c0914c | 41 | total = total + history[i]; |
ellingjp | 8:8430a5c0914c | 42 | count = count + 1; |
ellingjp | 8:8430a5c0914c | 43 | end_ = 0; |
ellingjp | 8:8430a5c0914c | 44 | front = 1; |
ellingjp | 8:8430a5c0914c | 45 | prev_data = history[0]; |
ellingjp | 8:8430a5c0914c | 46 | return INT16_MAX; |
ellingjp | 8:8430a5c0914c | 47 | } else { |
ellingjp | 8:8430a5c0914c | 48 | history[end_] = data; |
ellingjp | 8:8430a5c0914c | 49 | total = total - prev_data + data; |
ellingjp | 8:8430a5c0914c | 50 | end_ = end_ + 1; |
ellingjp | 8:8430a5c0914c | 51 | front = front + 1; |
ellingjp | 8:8430a5c0914c | 52 | |
ellingjp | 8:8430a5c0914c | 53 | if (end_ >= window) |
ellingjp | 8:8430a5c0914c | 54 | end_ = 0; |
ellingjp | 8:8430a5c0914c | 55 | |
ellingjp | 8:8430a5c0914c | 56 | if (front >= window) |
ellingjp | 8:8430a5c0914c | 57 | front = 0; |
ellingjp | 8:8430a5c0914c | 58 | |
ellingjp | 8:8430a5c0914c | 59 | if (front == 0) |
ellingjp | 8:8430a5c0914c | 60 | prev_data = history[window-1]; |
ellingjp | 8:8430a5c0914c | 61 | else { |
ellingjp | 8:8430a5c0914c | 62 | prev_data = history[front - 1]; |
ellingjp | 8:8430a5c0914c | 63 | } |
ellingjp | 8:8430a5c0914c | 64 | |
ellingjp | 8:8430a5c0914c | 65 | return total/window; |
ellingjp | 8:8430a5c0914c | 66 | } |
ellingjp | 8:8430a5c0914c | 67 | } |
ellingjp | 8:8430a5c0914c | 68 | |
ellingjp | 8:8430a5c0914c | 69 | /* Returns true if there is a peak (flip turn) */ |
ellingjp | 8:8430a5c0914c | 70 | bool peak_detect(int16_t data) |
ellingjp | 8:8430a5c0914c | 71 | { |
ellingjp | 8:8430a5c0914c | 72 | static uint8_t i = 0; |
ellingjp | 8:8430a5c0914c | 73 | static int16_t avg[3]; |
ellingjp | 8:8430a5c0914c | 74 | |
ellingjp | 8:8430a5c0914c | 75 | int16_t m = mov_avg(data); |
ellingjp | 8:8430a5c0914c | 76 | |
ellingjp | 8:8430a5c0914c | 77 | if (m == INT16_MAX) |
ellingjp | 8:8430a5c0914c | 78 | return false; |
ellingjp | 8:8430a5c0914c | 79 | |
ellingjp | 8:8430a5c0914c | 80 | if (i < 3) { |
ellingjp | 8:8430a5c0914c | 81 | avg[i++] = m; |
ellingjp | 8:8430a5c0914c | 82 | return false; |
ellingjp | 8:8430a5c0914c | 83 | } |
ellingjp | 8:8430a5c0914c | 84 | |
ellingjp | 8:8430a5c0914c | 85 | avg[0] = avg[1]; |
ellingjp | 8:8430a5c0914c | 86 | avg[1] = avg[2]; |
ellingjp | 8:8430a5c0914c | 87 | avg[2] = m; |
ellingjp | 8:8430a5c0914c | 88 | |
ellingjp | 9:a711b5b34d73 | 89 | if ( (avg[0] < avg[1]) && (avg[2] < avg[1]) && (avg[2] > THRESH) && (avg[1] > THRESH) && (avg[0] > THRESH) ) { |
ellingjp | 8:8430a5c0914c | 90 | PC_PRINTLNF("Peak detected @ %d", split_timer.read_ms()); |
ellingjp | 8:8430a5c0914c | 91 | return true; |
ellingjp | 8:8430a5c0914c | 92 | } |
ellingjp | 8:8430a5c0914c | 93 | |
ellingjp | 8:8430a5c0914c | 94 | return false; |
ellingjp | 8:8430a5c0914c | 95 | } |
ellingjp | 8:8430a5c0914c | 96 | |
ellingjp | 8:8430a5c0914c | 97 | enum length {ZERO, ONE, TWO}; |
ellingjp | 8:8430a5c0914c | 98 | |
ellingjp | 8:8430a5c0914c | 99 | /* Returns split time, or UINT16_MAX if not on a split */ |
ellingjp | 8:8430a5c0914c | 100 | uint16_t process_data(int16_t data) |
ellingjp | 8:8430a5c0914c | 101 | { |
ellingjp | 8:8430a5c0914c | 102 | static enum length Length = ZERO; |
ellingjp | 8:8430a5c0914c | 103 | static int l_zero, l_two; |
ellingjp | 8:8430a5c0914c | 104 | |
ellingjp | 8:8430a5c0914c | 105 | if (peak_detect(data)) { |
ellingjp | 8:8430a5c0914c | 106 | if (Length == ZERO) { |
ellingjp | 8:8430a5c0914c | 107 | l_zero = split_timer.read_ms(); |
ellingjp | 8:8430a5c0914c | 108 | Length = ONE; |
ellingjp | 8:8430a5c0914c | 109 | return UINT16_MAX; |
ellingjp | 8:8430a5c0914c | 110 | } else if (Length == ONE) { |
ellingjp | 8:8430a5c0914c | 111 | // l_one = SystemTime::read_ms(); |
ellingjp | 8:8430a5c0914c | 112 | Length = TWO; |
ellingjp | 8:8430a5c0914c | 113 | return UINT16_MAX; |
ellingjp | 8:8430a5c0914c | 114 | } else { |
ellingjp | 8:8430a5c0914c | 115 | l_two = split_timer.read_ms(); |
ellingjp | 8:8430a5c0914c | 116 | Length = ZERO; |
ellingjp | 8:8430a5c0914c | 117 | split_timer.reset(); |
ellingjp | 8:8430a5c0914c | 118 | return ( abs((l_two - l_zero))); |
ellingjp | 8:8430a5c0914c | 119 | } |
ellingjp | 8:8430a5c0914c | 120 | } |
ellingjp | 8:8430a5c0914c | 121 | |
ellingjp | 8:8430a5c0914c | 122 | return UINT16_MAX; |
ellingjp | 8:8430a5c0914c | 123 | } |
ellingjp | 8:8430a5c0914c | 124 | |
ellingjp | 8:8430a5c0914c | 125 | bool process_close() { |
ellingjp | 8:8430a5c0914c | 126 | delete(history); |
ellingjp | 8:8430a5c0914c | 127 | split_timer.reset(); |
ellingjp | 8:8430a5c0914c | 128 | split_timer.stop(); |
ellingjp | 8:8430a5c0914c | 129 | return true; |
ellingjp | 8:8430a5c0914c | 130 | } |