Using the MBED BLE library and Nordic Puck library this is a simple scoring application using Bluetooth LE. It monitors three analog inputs and triggers on reception of a pulse on any one recording data for a short period on all three. This is then published via BLE characteristics. It's a demonstrator for a new UI dev toolkit that is under development.
Fork of Example_Puck_BLE by
SampleChannel.cpp@10:a2ba0cef85aa, 2014-08-26 (annotated)
- Committer:
- Bobty
- Date:
- Tue Aug 26 14:13:31 2014 +0000
- Revision:
- 10:a2ba0cef85aa
- Parent:
- 8:87a3708dca9c
Working with 3 channels
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Bobty | 3:a155da1cbde3 | 1 | // Simple averaging filter |
Bobty | 3:a155da1cbde3 | 2 | #include "mbed.h" |
Bobty | 3:a155da1cbde3 | 3 | #include "UUID.h" |
Bobty | 3:a155da1cbde3 | 4 | #include "SampleChannel.h" |
Bobty | 3:a155da1cbde3 | 5 | |
Bobty | 3:a155da1cbde3 | 6 | SampleChannel::SampleChannel(PinName pin, const UUID uuid, Serial* pLogger) : chanUuid(uuid), ain(pin) |
Bobty | 3:a155da1cbde3 | 7 | { |
Bobty | 3:a155da1cbde3 | 8 | pLocalLogger = pLogger; |
Bobty | 3:a155da1cbde3 | 9 | for (int i = 0; i < NUM_FILTER_VALS; i++) |
Bobty | 3:a155da1cbde3 | 10 | filterBuf[i] = 0; |
Bobty | 3:a155da1cbde3 | 11 | curFilterIdx = 0; |
Bobty | 3:a155da1cbde3 | 12 | for (int i = 0; i < NUM_RETURN_SAMPLES; i++) |
Bobty | 3:a155da1cbde3 | 13 | sampleBuf[i] = 0; |
Bobty | 3:a155da1cbde3 | 14 | curSampleIdx = 0; |
Bobty | 3:a155da1cbde3 | 15 | isCapturing = false; |
Bobty | 3:a155da1cbde3 | 16 | sampleThreshold = 100; |
Bobty | 3:a155da1cbde3 | 17 | sampleDivisor = 10; |
Bobty | 3:a155da1cbde3 | 18 | sampleBaseVal = 0; |
Bobty | 3:a155da1cbde3 | 19 | } |
Bobty | 3:a155da1cbde3 | 20 | |
Bobty | 3:a155da1cbde3 | 21 | void SampleChannel::SetThreshold(uint16_t threshold) |
Bobty | 3:a155da1cbde3 | 22 | { |
Bobty | 3:a155da1cbde3 | 23 | sampleThreshold = threshold; |
Bobty | 3:a155da1cbde3 | 24 | } |
Bobty | 3:a155da1cbde3 | 25 | |
Bobty | 3:a155da1cbde3 | 26 | void SampleChannel::SetDivisor(uint16_t divisor) |
Bobty | 3:a155da1cbde3 | 27 | { |
Bobty | 3:a155da1cbde3 | 28 | sampleDivisor = divisor; |
Bobty | 3:a155da1cbde3 | 29 | } |
Bobty | 3:a155da1cbde3 | 30 | |
Bobty | 3:a155da1cbde3 | 31 | void SampleChannel::AddSample(uint16_t val) |
Bobty | 3:a155da1cbde3 | 32 | { |
Bobty | 3:a155da1cbde3 | 33 | // If capturing add to sample buf |
Bobty | 3:a155da1cbde3 | 34 | if (isCapturing) |
Bobty | 3:a155da1cbde3 | 35 | { |
Bobty | 3:a155da1cbde3 | 36 | if (curSampleIdx < NUM_RETURN_SAMPLES) |
Bobty | 3:a155da1cbde3 | 37 | { |
Bobty | 3:a155da1cbde3 | 38 | int mungedVal = val - sampleBaseVal; |
Bobty | 3:a155da1cbde3 | 39 | if (mungedVal < 0) |
Bobty | 3:a155da1cbde3 | 40 | mungedVal = 0; |
Bobty | 3:a155da1cbde3 | 41 | mungedVal = mungedVal / sampleDivisor; |
Bobty | 3:a155da1cbde3 | 42 | if (mungedVal > 255) |
Bobty | 3:a155da1cbde3 | 43 | mungedVal = 255; |
Bobty | 3:a155da1cbde3 | 44 | sampleBuf[curSampleIdx++] = (uint8_t)mungedVal; |
Bobty | 3:a155da1cbde3 | 45 | } |
Bobty | 3:a155da1cbde3 | 46 | } |
Bobty | 3:a155da1cbde3 | 47 | // Add to filter |
Bobty | 3:a155da1cbde3 | 48 | filterBuf[curFilterIdx] = val; |
Bobty | 3:a155da1cbde3 | 49 | curFilterIdx++; |
Bobty | 3:a155da1cbde3 | 50 | curFilterIdx = curFilterIdx % NUM_FILTER_VALS; |
Bobty | 3:a155da1cbde3 | 51 | } |
Bobty | 3:a155da1cbde3 | 52 | |
Bobty | 3:a155da1cbde3 | 53 | int SampleChannel::GetAvgOutsideTriggerWindow() |
Bobty | 3:a155da1cbde3 | 54 | { |
Bobty | 3:a155da1cbde3 | 55 | int sum = 0; |
Bobty | 3:a155da1cbde3 | 56 | for (int i = 0; i < NUM_FILTER_VALS-TRIGGER_WINDOW; i++) |
Bobty | 3:a155da1cbde3 | 57 | sum += filterBuf[(i + curFilterIdx) % NUM_FILTER_VALS]; |
Bobty | 3:a155da1cbde3 | 58 | return sum / (NUM_FILTER_VALS - TRIGGER_WINDOW); |
Bobty | 3:a155da1cbde3 | 59 | } |
Bobty | 3:a155da1cbde3 | 60 | |
Bobty | 3:a155da1cbde3 | 61 | int SampleChannel::GetAvgOfTriggerWindow() |
Bobty | 3:a155da1cbde3 | 62 | { |
Bobty | 3:a155da1cbde3 | 63 | int sum = 0; |
Bobty | 3:a155da1cbde3 | 64 | for (int i = 0; i < TRIGGER_WINDOW; i++) |
Bobty | 3:a155da1cbde3 | 65 | sum += filterBuf[(curFilterIdx + NUM_FILTER_VALS - 1 - i) % NUM_FILTER_VALS]; |
Bobty | 3:a155da1cbde3 | 66 | return sum / TRIGGER_WINDOW; |
Bobty | 3:a155da1cbde3 | 67 | } |
Bobty | 3:a155da1cbde3 | 68 | |
Bobty | 3:a155da1cbde3 | 69 | uint16_t SampleChannel::GetLowest() |
Bobty | 3:a155da1cbde3 | 70 | { |
Bobty | 3:a155da1cbde3 | 71 | uint16_t lowVal = 0xffff; |
Bobty | 3:a155da1cbde3 | 72 | for (int i = 0; i < NUM_FILTER_VALS; i++) |
Bobty | 3:a155da1cbde3 | 73 | if (lowVal > filterBuf[i]) |
Bobty | 3:a155da1cbde3 | 74 | lowVal = filterBuf[i]; |
Bobty | 3:a155da1cbde3 | 75 | return lowVal; |
Bobty | 3:a155da1cbde3 | 76 | } |
Bobty | 3:a155da1cbde3 | 77 | |
Bobty | 3:a155da1cbde3 | 78 | void SampleChannel::Service() |
Bobty | 3:a155da1cbde3 | 79 | { |
Bobty | 3:a155da1cbde3 | 80 | // take a sample and add to trigger buffer |
Bobty | 3:a155da1cbde3 | 81 | unsigned short val = ain.read_u16(); |
Bobty | 3:a155da1cbde3 | 82 | AddSample(val); |
Bobty | 3:a155da1cbde3 | 83 | } |
Bobty | 3:a155da1cbde3 | 84 | |
Bobty | 3:a155da1cbde3 | 85 | bool SampleChannel::IsSampling() |
Bobty | 3:a155da1cbde3 | 86 | { |
Bobty | 3:a155da1cbde3 | 87 | return isCapturing; |
Bobty | 3:a155da1cbde3 | 88 | } |
Bobty | 3:a155da1cbde3 | 89 | |
Bobty | 3:a155da1cbde3 | 90 | bool SampleChannel::AreSamplesReady() |
Bobty | 3:a155da1cbde3 | 91 | { |
Bobty | 3:a155da1cbde3 | 92 | // Check if sample ready |
Bobty | 3:a155da1cbde3 | 93 | return (isCapturing && (curSampleIdx == NUM_RETURN_SAMPLES)); |
Bobty | 3:a155da1cbde3 | 94 | } |
Bobty | 3:a155da1cbde3 | 95 | |
Bobty | 3:a155da1cbde3 | 96 | void SampleChannel::StopSampling() |
Bobty | 3:a155da1cbde3 | 97 | { |
Bobty | 3:a155da1cbde3 | 98 | isCapturing = false; |
Bobty | 3:a155da1cbde3 | 99 | } |
Bobty | 3:a155da1cbde3 | 100 | |
Bobty | 3:a155da1cbde3 | 101 | void SampleChannel::StartSampling() |
Bobty | 3:a155da1cbde3 | 102 | { |
Bobty | 3:a155da1cbde3 | 103 | curSampleIdx = 0; |
Bobty | 3:a155da1cbde3 | 104 | isCapturing = true; |
Bobty | 3:a155da1cbde3 | 105 | sampleBaseVal = GetLowest(); |
Bobty | 3:a155da1cbde3 | 106 | |
Bobty | 3:a155da1cbde3 | 107 | // Copy across values from trigger window |
Bobty | 3:a155da1cbde3 | 108 | for (int i = TRIGGER_WINDOW; i > 0; i--) |
Bobty | 3:a155da1cbde3 | 109 | AddSample(filterBuf[(curFilterIdx + NUM_FILTER_VALS - i) % NUM_FILTER_VALS]); |
Bobty | 3:a155da1cbde3 | 110 | } |
Bobty | 3:a155da1cbde3 | 111 | |
Bobty | 3:a155da1cbde3 | 112 | bool SampleChannel::CheckTrigger() |
Bobty | 3:a155da1cbde3 | 113 | { |
Bobty | 3:a155da1cbde3 | 114 | // Check if the samples in the trigger window are significantly different from the average |
Bobty | 4:cc164ecf6a36 | 115 | int spike = GetAvgOfTriggerWindow() - GetAvgOutsideTriggerWindow(); |
Bobty | 4:cc164ecf6a36 | 116 | if (spike < 0) |
Bobty | 4:cc164ecf6a36 | 117 | spike = -spike; |
Bobty | 4:cc164ecf6a36 | 118 | return spike > sampleThreshold; |
Bobty | 3:a155da1cbde3 | 119 | } |
Bobty | 3:a155da1cbde3 | 120 | |
Bobty | 3:a155da1cbde3 | 121 | uint8_t *SampleChannel::GetSamples() |
Bobty | 3:a155da1cbde3 | 122 | { |
Bobty | 3:a155da1cbde3 | 123 | return sampleBuf; |
Bobty | 3:a155da1cbde3 | 124 | } |
Bobty | 3:a155da1cbde3 | 125 | |
Bobty | 3:a155da1cbde3 | 126 | int SampleChannel::GetSamplesLen() |
Bobty | 3:a155da1cbde3 | 127 | { |
Bobty | 3:a155da1cbde3 | 128 | return NUM_RETURN_SAMPLES; |
Bobty | 3:a155da1cbde3 | 129 | } |
Bobty | 3:a155da1cbde3 | 130 |