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
Diff: SampleChannel.cpp
- Revision:
- 3:a155da1cbde3
- Child:
- 4:cc164ecf6a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SampleChannel.cpp Thu Aug 21 11:26:26 2014 +0000 @@ -0,0 +1,142 @@ +// Simple averaging filter +#include "mbed.h" +#include "UUID.h" +#include "SampleChannel.h" + +SampleChannel::SampleChannel(PinName pin, const UUID uuid, Serial* pLogger) : chanUuid(uuid), ain(pin) +{ + pLocalLogger = pLogger; + for (int i = 0; i < NUM_FILTER_VALS; i++) + filterBuf[i] = 0; + curFilterIdx = 0; + for (int i = 0; i < NUM_RETURN_SAMPLES; i++) + sampleBuf[i] = 0; + curSampleIdx = 0; + isCapturing = false; + sampleThreshold = 100; + sampleDivisor = 10; + testSampleCount = 0; + sampleBaseVal = 0; +} + +void SampleChannel::SetThreshold(uint16_t threshold) +{ + sampleThreshold = threshold; +} + +void SampleChannel::SetDivisor(uint16_t divisor) +{ + sampleDivisor = divisor; +} + +void SampleChannel::AddSample(uint16_t val) +{ + testSampleCount++; + if (testSampleCount == 100) + { + pLocalLogger->printf("%d AvgT %d, AvgW %d, low %d\n", val, GetAvgOfTriggerWindow(), GetAvgOutsideTriggerWindow(), GetLowest()); + testSampleCount = 0; + } + + // If capturing add to sample buf + if (isCapturing) + { + if (curSampleIdx < NUM_RETURN_SAMPLES) + { + int mungedVal = val - sampleBaseVal; + if (mungedVal < 0) + mungedVal = 0; + mungedVal = mungedVal / sampleDivisor; + if (mungedVal > 255) + mungedVal = 255; + sampleBuf[curSampleIdx++] = (uint8_t)mungedVal; + } + } + // Add to filter + filterBuf[curFilterIdx] = val; + curFilterIdx++; + curFilterIdx = curFilterIdx % NUM_FILTER_VALS; +} + +int SampleChannel::GetAvgOutsideTriggerWindow() +{ + int sum = 0; + for (int i = 0; i < NUM_FILTER_VALS-TRIGGER_WINDOW; i++) + sum += filterBuf[(i + curFilterIdx) % NUM_FILTER_VALS]; + return sum / (NUM_FILTER_VALS - TRIGGER_WINDOW); +} + +int SampleChannel::GetAvgOfTriggerWindow() +{ + int sum = 0; + for (int i = 0; i < TRIGGER_WINDOW; i++) + sum += filterBuf[(curFilterIdx + NUM_FILTER_VALS - 1 - i) % NUM_FILTER_VALS]; + return sum / TRIGGER_WINDOW; +} + +uint16_t SampleChannel::GetLowest() +{ + uint16_t lowVal = 0xffff; + for (int i = 0; i < NUM_FILTER_VALS; i++) + if (lowVal > filterBuf[i]) + lowVal = filterBuf[i]; + return lowVal; +} + +void SampleChannel::Service() +{ + // take a sample and add to trigger buffer + unsigned short val = ain.read_u16(); + AddSample(val); +} + +bool SampleChannel::IsSampling() +{ + return isCapturing; +} + +bool SampleChannel::AreSamplesReady() +{ + // Check if sample ready + return (isCapturing && (curSampleIdx == NUM_RETURN_SAMPLES)); +} + +void SampleChannel::StopSampling() +{ + isCapturing = false; +} + +void SampleChannel::StartSampling() +{ + curSampleIdx = 0; + isCapturing = true; + sampleBaseVal = GetLowest(); + + // Copy across values from trigger window + for (int i = TRIGGER_WINDOW; i > 0; i--) + AddSample(filterBuf[(curFilterIdx + NUM_FILTER_VALS - i) % NUM_FILTER_VALS]); +} + +bool SampleChannel::CheckTrigger() +{ + // Check if the samples in the trigger window are significantly different from the average + for (int i = 0; i < TRIGGER_WINDOW; i++) + { + int spike = GetAvgOfTriggerWindow() - GetAvgOutsideTriggerWindow(); + if (spike < 0) + spike = -spike; + return (spike > sampleThreshold); + } + return false; +} + +uint8_t *SampleChannel::GetSamples() +{ + return sampleBuf; +} + +int SampleChannel::GetSamplesLen() +{ + return NUM_RETURN_SAMPLES; +} + \ No newline at end of file