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@8:8430a5c0914c, 2014-05-20 (annotated)
- Committer:
- ellingjp
- Date:
- Tue May 20 00:43:55 2014 +0000
- Revision:
- 8:8430a5c0914c
- Child:
- 9:a711b5b34d73
Working logging and split time detection
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 | 8:8430a5c0914c | 6 | int window = 0; |
ellingjp | 8:8430a5c0914c | 7 | int16_t *history; |
ellingjp | 8:8430a5c0914c | 8 | int16_t prev_data = 0; |
ellingjp | 8:8430a5c0914c | 9 | |
ellingjp | 8:8430a5c0914c | 10 | Timer split_timer; |
ellingjp | 8:8430a5c0914c | 11 | |
ellingjp | 8:8430a5c0914c | 12 | /* Initializes the moving average with a window size */ |
ellingjp | 8:8430a5c0914c | 13 | bool process_init() |
ellingjp | 8:8430a5c0914c | 14 | { |
ellingjp | 8:8430a5c0914c | 15 | window = WINDOW_SIZE; |
ellingjp | 8:8430a5c0914c | 16 | history = new int16_t[WINDOW_SIZE](); // initializes to 0 |
ellingjp | 8:8430a5c0914c | 17 | |
ellingjp | 8:8430a5c0914c | 18 | split_timer.start(); |
ellingjp | 8:8430a5c0914c | 19 | return true; |
ellingjp | 8:8430a5c0914c | 20 | } |
ellingjp | 8:8430a5c0914c | 21 | |
ellingjp | 8:8430a5c0914c | 22 | /* Will break for window size > 2^8 |
ellingjp | 8:8430a5c0914c | 23 | * Returns a moving average for data |
ellingjp | 8:8430a5c0914c | 24 | * Returns INT16_MAX until it has received a window |
ellingjp | 8:8430a5c0914c | 25 | * size worth of data. These values should be ignored. */ |
ellingjp | 8:8430a5c0914c | 26 | int16_t mov_avg(int16_t data) |
ellingjp | 8:8430a5c0914c | 27 | { |
ellingjp | 8:8430a5c0914c | 28 | static uint8_t front = 0, end_ = 0, count = 0; |
ellingjp | 8:8430a5c0914c | 29 | static int32_t total; |
ellingjp | 8:8430a5c0914c | 30 | |
ellingjp | 8:8430a5c0914c | 31 | if (count < window-1) { |
ellingjp | 8:8430a5c0914c | 32 | history[end_] = data; |
ellingjp | 8:8430a5c0914c | 33 | end_ = end_ + 1; |
ellingjp | 8:8430a5c0914c | 34 | count = count + 1; |
ellingjp | 8:8430a5c0914c | 35 | return INT16_MAX; |
ellingjp | 8:8430a5c0914c | 36 | } else if (count == window-1) { |
ellingjp | 8:8430a5c0914c | 37 | history[end_] = data; |
ellingjp | 8:8430a5c0914c | 38 | for (int i = 0; i <= count; i++) |
ellingjp | 8:8430a5c0914c | 39 | total = total + history[i]; |
ellingjp | 8:8430a5c0914c | 40 | count = count + 1; |
ellingjp | 8:8430a5c0914c | 41 | end_ = 0; |
ellingjp | 8:8430a5c0914c | 42 | front = 1; |
ellingjp | 8:8430a5c0914c | 43 | prev_data = history[0]; |
ellingjp | 8:8430a5c0914c | 44 | return INT16_MAX; |
ellingjp | 8:8430a5c0914c | 45 | } else { |
ellingjp | 8:8430a5c0914c | 46 | history[end_] = data; |
ellingjp | 8:8430a5c0914c | 47 | total = total - prev_data + data; |
ellingjp | 8:8430a5c0914c | 48 | end_ = end_ + 1; |
ellingjp | 8:8430a5c0914c | 49 | front = front + 1; |
ellingjp | 8:8430a5c0914c | 50 | |
ellingjp | 8:8430a5c0914c | 51 | if (end_ >= window) |
ellingjp | 8:8430a5c0914c | 52 | end_ = 0; |
ellingjp | 8:8430a5c0914c | 53 | |
ellingjp | 8:8430a5c0914c | 54 | if (front >= window) |
ellingjp | 8:8430a5c0914c | 55 | front = 0; |
ellingjp | 8:8430a5c0914c | 56 | |
ellingjp | 8:8430a5c0914c | 57 | if (front == 0) |
ellingjp | 8:8430a5c0914c | 58 | prev_data = history[window-1]; |
ellingjp | 8:8430a5c0914c | 59 | else { |
ellingjp | 8:8430a5c0914c | 60 | prev_data = history[front - 1]; |
ellingjp | 8:8430a5c0914c | 61 | } |
ellingjp | 8:8430a5c0914c | 62 | |
ellingjp | 8:8430a5c0914c | 63 | return total/window; |
ellingjp | 8:8430a5c0914c | 64 | } |
ellingjp | 8:8430a5c0914c | 65 | } |
ellingjp | 8:8430a5c0914c | 66 | |
ellingjp | 8:8430a5c0914c | 67 | /* Returns true if there is a peak (flip turn) */ |
ellingjp | 8:8430a5c0914c | 68 | bool peak_detect(int16_t data) |
ellingjp | 8:8430a5c0914c | 69 | { |
ellingjp | 8:8430a5c0914c | 70 | static uint8_t i = 0; |
ellingjp | 8:8430a5c0914c | 71 | static int16_t avg[3]; |
ellingjp | 8:8430a5c0914c | 72 | |
ellingjp | 8:8430a5c0914c | 73 | int16_t m = mov_avg(data); |
ellingjp | 8:8430a5c0914c | 74 | |
ellingjp | 8:8430a5c0914c | 75 | if (m == INT16_MAX) |
ellingjp | 8:8430a5c0914c | 76 | return false; |
ellingjp | 8:8430a5c0914c | 77 | |
ellingjp | 8:8430a5c0914c | 78 | if (i < 3) { |
ellingjp | 8:8430a5c0914c | 79 | avg[i++] = m; |
ellingjp | 8:8430a5c0914c | 80 | return false; |
ellingjp | 8:8430a5c0914c | 81 | } |
ellingjp | 8:8430a5c0914c | 82 | |
ellingjp | 8:8430a5c0914c | 83 | avg[0] = avg[1]; |
ellingjp | 8:8430a5c0914c | 84 | avg[1] = avg[2]; |
ellingjp | 8:8430a5c0914c | 85 | avg[2] = m; |
ellingjp | 8:8430a5c0914c | 86 | |
ellingjp | 8:8430a5c0914c | 87 | if ( (avg[0] > avg[1]) && (avg[2] > avg[1]) && (avg[2] < -2000) && (avg[1] < -2000) && (avg[0] < -2000) ) { |
ellingjp | 8:8430a5c0914c | 88 | PC_PRINTLNF("Peak detected @ %d", split_timer.read_ms()); |
ellingjp | 8:8430a5c0914c | 89 | return true; |
ellingjp | 8:8430a5c0914c | 90 | } |
ellingjp | 8:8430a5c0914c | 91 | |
ellingjp | 8:8430a5c0914c | 92 | return false; |
ellingjp | 8:8430a5c0914c | 93 | } |
ellingjp | 8:8430a5c0914c | 94 | |
ellingjp | 8:8430a5c0914c | 95 | enum length {ZERO, ONE, TWO}; |
ellingjp | 8:8430a5c0914c | 96 | |
ellingjp | 8:8430a5c0914c | 97 | /* Returns split time, or UINT16_MAX if not on a split */ |
ellingjp | 8:8430a5c0914c | 98 | uint16_t process_data(int16_t data) |
ellingjp | 8:8430a5c0914c | 99 | { |
ellingjp | 8:8430a5c0914c | 100 | static enum length Length = ZERO; |
ellingjp | 8:8430a5c0914c | 101 | static int l_zero, l_two; |
ellingjp | 8:8430a5c0914c | 102 | |
ellingjp | 8:8430a5c0914c | 103 | if (peak_detect(data)) { |
ellingjp | 8:8430a5c0914c | 104 | if (Length == ZERO) { |
ellingjp | 8:8430a5c0914c | 105 | l_zero = split_timer.read_ms(); |
ellingjp | 8:8430a5c0914c | 106 | Length = ONE; |
ellingjp | 8:8430a5c0914c | 107 | return UINT16_MAX; |
ellingjp | 8:8430a5c0914c | 108 | } else if (Length == ONE) { |
ellingjp | 8:8430a5c0914c | 109 | // l_one = SystemTime::read_ms(); |
ellingjp | 8:8430a5c0914c | 110 | Length = TWO; |
ellingjp | 8:8430a5c0914c | 111 | return UINT16_MAX; |
ellingjp | 8:8430a5c0914c | 112 | } else { |
ellingjp | 8:8430a5c0914c | 113 | l_two = split_timer.read_ms(); |
ellingjp | 8:8430a5c0914c | 114 | Length = ZERO; |
ellingjp | 8:8430a5c0914c | 115 | split_timer.reset(); |
ellingjp | 8:8430a5c0914c | 116 | return ( abs((l_two - l_zero))); |
ellingjp | 8:8430a5c0914c | 117 | } |
ellingjp | 8:8430a5c0914c | 118 | } |
ellingjp | 8:8430a5c0914c | 119 | |
ellingjp | 8:8430a5c0914c | 120 | return UINT16_MAX; |
ellingjp | 8:8430a5c0914c | 121 | } |
ellingjp | 8:8430a5c0914c | 122 | |
ellingjp | 8:8430a5c0914c | 123 | bool process_close() { |
ellingjp | 8:8430a5c0914c | 124 | delete(history); |
ellingjp | 8:8430a5c0914c | 125 | split_timer.reset(); |
ellingjp | 8:8430a5c0914c | 126 | split_timer.stop(); |
ellingjp | 8:8430a5c0914c | 127 | return true; |
ellingjp | 8:8430a5c0914c | 128 | } |