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
- Committer:
- Bobty
- Date:
- 2014-08-23
- Revision:
- 8:87a3708dca9c
- Parent:
- 4:cc164ecf6a36
File content as of revision 8:87a3708dca9c:
// 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; sampleBaseVal = 0; } void SampleChannel::SetThreshold(uint16_t threshold) { sampleThreshold = threshold; } void SampleChannel::SetDivisor(uint16_t divisor) { sampleDivisor = divisor; } void SampleChannel::AddSample(uint16_t val) { // 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 int spike = GetAvgOfTriggerWindow() - GetAvgOutsideTriggerWindow(); if (spike < 0) spike = -spike; return spike > sampleThreshold; } uint8_t *SampleChannel::GetSamples() { return sampleBuf; } int SampleChannel::GetSamplesLen() { return NUM_RETURN_SAMPLES; }