CSE477 / swimate_v2

Dependencies:   Adafruit_GFX_128x64 DS3231 PinDetect SDFileSystem USBDevice mbed RealtimeMath MODSERIAL

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?

UserRevisionLine numberNew 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 }