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

Revision:
3:a155da1cbde3
Child:
4:cc164ecf6a36
diff -r e400fd4f501b -r a155da1cbde3 SampleChannel.cpp
--- /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