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.

Dependencies:   Puck mbed

Fork of Example_Puck_BLE by Nordic Semiconductor

Committer:
Bobty
Date:
Sat Aug 23 09:31:01 2014 +0000
Revision:
4:cc164ecf6a36
Parent:
3:a155da1cbde3
Child:
8:87a3708dca9c
Ticker working on 100ms intervals with BLE enabled but no analog activity

Who changed what in which revision?

UserRevisionLine numberNew 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 testSampleCount = 0;
Bobty 3:a155da1cbde3 19 sampleBaseVal = 0;
Bobty 3:a155da1cbde3 20 }
Bobty 3:a155da1cbde3 21
Bobty 3:a155da1cbde3 22 void SampleChannel::SetThreshold(uint16_t threshold)
Bobty 3:a155da1cbde3 23 {
Bobty 3:a155da1cbde3 24 sampleThreshold = threshold;
Bobty 3:a155da1cbde3 25 }
Bobty 3:a155da1cbde3 26
Bobty 3:a155da1cbde3 27 void SampleChannel::SetDivisor(uint16_t divisor)
Bobty 3:a155da1cbde3 28 {
Bobty 3:a155da1cbde3 29 sampleDivisor = divisor;
Bobty 3:a155da1cbde3 30 }
Bobty 3:a155da1cbde3 31
Bobty 3:a155da1cbde3 32 void SampleChannel::AddSample(uint16_t val)
Bobty 3:a155da1cbde3 33 {
Bobty 3:a155da1cbde3 34 testSampleCount++;
Bobty 4:cc164ecf6a36 35 if (testSampleCount == 1000)
Bobty 3:a155da1cbde3 36 {
Bobty 4:cc164ecf6a36 37 // pLocalLogger->printf("%d AvgT %d, AvgW %d, low %d\n", val, GetAvgOfTriggerWindow(), GetAvgOutsideTriggerWindow(), GetLowest());
Bobty 3:a155da1cbde3 38 testSampleCount = 0;
Bobty 3:a155da1cbde3 39 }
Bobty 3:a155da1cbde3 40
Bobty 3:a155da1cbde3 41 // If capturing add to sample buf
Bobty 3:a155da1cbde3 42 if (isCapturing)
Bobty 3:a155da1cbde3 43 {
Bobty 3:a155da1cbde3 44 if (curSampleIdx < NUM_RETURN_SAMPLES)
Bobty 3:a155da1cbde3 45 {
Bobty 3:a155da1cbde3 46 int mungedVal = val - sampleBaseVal;
Bobty 3:a155da1cbde3 47 if (mungedVal < 0)
Bobty 3:a155da1cbde3 48 mungedVal = 0;
Bobty 3:a155da1cbde3 49 mungedVal = mungedVal / sampleDivisor;
Bobty 3:a155da1cbde3 50 if (mungedVal > 255)
Bobty 3:a155da1cbde3 51 mungedVal = 255;
Bobty 3:a155da1cbde3 52 sampleBuf[curSampleIdx++] = (uint8_t)mungedVal;
Bobty 3:a155da1cbde3 53 }
Bobty 3:a155da1cbde3 54 }
Bobty 3:a155da1cbde3 55 // Add to filter
Bobty 3:a155da1cbde3 56 filterBuf[curFilterIdx] = val;
Bobty 3:a155da1cbde3 57 curFilterIdx++;
Bobty 3:a155da1cbde3 58 curFilterIdx = curFilterIdx % NUM_FILTER_VALS;
Bobty 3:a155da1cbde3 59 }
Bobty 3:a155da1cbde3 60
Bobty 3:a155da1cbde3 61 int SampleChannel::GetAvgOutsideTriggerWindow()
Bobty 3:a155da1cbde3 62 {
Bobty 3:a155da1cbde3 63 int sum = 0;
Bobty 3:a155da1cbde3 64 for (int i = 0; i < NUM_FILTER_VALS-TRIGGER_WINDOW; i++)
Bobty 3:a155da1cbde3 65 sum += filterBuf[(i + curFilterIdx) % NUM_FILTER_VALS];
Bobty 3:a155da1cbde3 66 return sum / (NUM_FILTER_VALS - TRIGGER_WINDOW);
Bobty 3:a155da1cbde3 67 }
Bobty 3:a155da1cbde3 68
Bobty 3:a155da1cbde3 69 int SampleChannel::GetAvgOfTriggerWindow()
Bobty 3:a155da1cbde3 70 {
Bobty 3:a155da1cbde3 71 int sum = 0;
Bobty 3:a155da1cbde3 72 for (int i = 0; i < TRIGGER_WINDOW; i++)
Bobty 3:a155da1cbde3 73 sum += filterBuf[(curFilterIdx + NUM_FILTER_VALS - 1 - i) % NUM_FILTER_VALS];
Bobty 3:a155da1cbde3 74 return sum / TRIGGER_WINDOW;
Bobty 3:a155da1cbde3 75 }
Bobty 3:a155da1cbde3 76
Bobty 3:a155da1cbde3 77 uint16_t SampleChannel::GetLowest()
Bobty 3:a155da1cbde3 78 {
Bobty 3:a155da1cbde3 79 uint16_t lowVal = 0xffff;
Bobty 3:a155da1cbde3 80 for (int i = 0; i < NUM_FILTER_VALS; i++)
Bobty 3:a155da1cbde3 81 if (lowVal > filterBuf[i])
Bobty 3:a155da1cbde3 82 lowVal = filterBuf[i];
Bobty 3:a155da1cbde3 83 return lowVal;
Bobty 3:a155da1cbde3 84 }
Bobty 3:a155da1cbde3 85
Bobty 3:a155da1cbde3 86 void SampleChannel::Service()
Bobty 3:a155da1cbde3 87 {
Bobty 3:a155da1cbde3 88 // take a sample and add to trigger buffer
Bobty 3:a155da1cbde3 89 unsigned short val = ain.read_u16();
Bobty 3:a155da1cbde3 90 AddSample(val);
Bobty 3:a155da1cbde3 91 }
Bobty 3:a155da1cbde3 92
Bobty 3:a155da1cbde3 93 bool SampleChannel::IsSampling()
Bobty 3:a155da1cbde3 94 {
Bobty 3:a155da1cbde3 95 return isCapturing;
Bobty 3:a155da1cbde3 96 }
Bobty 3:a155da1cbde3 97
Bobty 3:a155da1cbde3 98 bool SampleChannel::AreSamplesReady()
Bobty 3:a155da1cbde3 99 {
Bobty 3:a155da1cbde3 100 // Check if sample ready
Bobty 3:a155da1cbde3 101 return (isCapturing && (curSampleIdx == NUM_RETURN_SAMPLES));
Bobty 3:a155da1cbde3 102 }
Bobty 3:a155da1cbde3 103
Bobty 3:a155da1cbde3 104 void SampleChannel::StopSampling()
Bobty 3:a155da1cbde3 105 {
Bobty 3:a155da1cbde3 106 isCapturing = false;
Bobty 3:a155da1cbde3 107 }
Bobty 3:a155da1cbde3 108
Bobty 3:a155da1cbde3 109 void SampleChannel::StartSampling()
Bobty 3:a155da1cbde3 110 {
Bobty 3:a155da1cbde3 111 curSampleIdx = 0;
Bobty 3:a155da1cbde3 112 isCapturing = true;
Bobty 3:a155da1cbde3 113 sampleBaseVal = GetLowest();
Bobty 3:a155da1cbde3 114
Bobty 3:a155da1cbde3 115 // Copy across values from trigger window
Bobty 3:a155da1cbde3 116 for (int i = TRIGGER_WINDOW; i > 0; i--)
Bobty 3:a155da1cbde3 117 AddSample(filterBuf[(curFilterIdx + NUM_FILTER_VALS - i) % NUM_FILTER_VALS]);
Bobty 3:a155da1cbde3 118 }
Bobty 3:a155da1cbde3 119
Bobty 3:a155da1cbde3 120 bool SampleChannel::CheckTrigger()
Bobty 3:a155da1cbde3 121 {
Bobty 3:a155da1cbde3 122 // Check if the samples in the trigger window are significantly different from the average
Bobty 4:cc164ecf6a36 123 int spike = GetAvgOfTriggerWindow() - GetAvgOutsideTriggerWindow();
Bobty 4:cc164ecf6a36 124 if (spike < 0)
Bobty 4:cc164ecf6a36 125 spike = -spike;
Bobty 4:cc164ecf6a36 126 return spike > sampleThreshold;
Bobty 3:a155da1cbde3 127 }
Bobty 3:a155da1cbde3 128
Bobty 3:a155da1cbde3 129 uint8_t *SampleChannel::GetSamples()
Bobty 3:a155da1cbde3 130 {
Bobty 3:a155da1cbde3 131 return sampleBuf;
Bobty 3:a155da1cbde3 132 }
Bobty 3:a155da1cbde3 133
Bobty 3:a155da1cbde3 134 int SampleChannel::GetSamplesLen()
Bobty 3:a155da1cbde3 135 {
Bobty 3:a155da1cbde3 136 return NUM_RETURN_SAMPLES;
Bobty 3:a155da1cbde3 137 }
Bobty 3:a155da1cbde3 138