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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SampleChannel.cpp Source File

SampleChannel.cpp

00001 // Simple averaging filter
00002 #include "mbed.h"
00003 #include "UUID.h"
00004 #include "SampleChannel.h"
00005 
00006 SampleChannel::SampleChannel(PinName pin, const UUID uuid, Serial* pLogger) : chanUuid(uuid), ain(pin)
00007 {
00008     pLocalLogger = pLogger;
00009     for (int i = 0; i < NUM_FILTER_VALS; i++)
00010         filterBuf[i] = 0;
00011     curFilterIdx = 0;
00012     for (int i = 0; i < NUM_RETURN_SAMPLES; i++)
00013         sampleBuf[i] = 0;
00014     curSampleIdx = 0;
00015     isCapturing = false;
00016     sampleThreshold = 100;
00017     sampleDivisor = 10;
00018     sampleBaseVal = 0;
00019 }
00020 
00021 void SampleChannel::SetThreshold(uint16_t threshold)
00022 {
00023     sampleThreshold = threshold;
00024 }
00025 
00026 void SampleChannel::SetDivisor(uint16_t divisor)
00027 {
00028     sampleDivisor = divisor;
00029 }
00030 
00031 void SampleChannel::AddSample(uint16_t val)
00032 {
00033     // If capturing add to sample buf
00034     if (isCapturing)
00035     {
00036         if (curSampleIdx < NUM_RETURN_SAMPLES)
00037         {
00038             int mungedVal = val - sampleBaseVal;
00039             if (mungedVal < 0)
00040                 mungedVal = 0;
00041             mungedVal = mungedVal / sampleDivisor;
00042             if (mungedVal > 255)
00043                 mungedVal = 255;
00044             sampleBuf[curSampleIdx++] = (uint8_t)mungedVal;
00045         }
00046     }
00047     // Add to filter
00048     filterBuf[curFilterIdx] = val;
00049     curFilterIdx++;
00050     curFilterIdx = curFilterIdx % NUM_FILTER_VALS;
00051 }
00052 
00053 int SampleChannel::GetAvgOutsideTriggerWindow()
00054 {
00055     int sum = 0;
00056     for (int i = 0; i < NUM_FILTER_VALS-TRIGGER_WINDOW; i++)
00057         sum += filterBuf[(i + curFilterIdx) % NUM_FILTER_VALS];
00058     return sum / (NUM_FILTER_VALS - TRIGGER_WINDOW);    
00059 }
00060 
00061 int SampleChannel::GetAvgOfTriggerWindow()
00062 {
00063     int sum = 0;
00064     for (int i = 0; i < TRIGGER_WINDOW; i++)
00065         sum += filterBuf[(curFilterIdx + NUM_FILTER_VALS - 1 - i) % NUM_FILTER_VALS];
00066     return sum / TRIGGER_WINDOW;    
00067 }
00068 
00069 uint16_t SampleChannel::GetLowest()
00070 {
00071     uint16_t lowVal = 0xffff;
00072     for (int i = 0; i < NUM_FILTER_VALS; i++)
00073         if (lowVal > filterBuf[i])
00074             lowVal = filterBuf[i];
00075     return lowVal;
00076 }
00077 
00078 void SampleChannel::Service()
00079 {
00080     // take a sample and add to trigger buffer
00081      unsigned short val = ain.read_u16();
00082      AddSample(val);
00083 }
00084 
00085 bool SampleChannel::IsSampling()
00086 {
00087     return isCapturing;
00088 }
00089     
00090 bool SampleChannel::AreSamplesReady()
00091 {
00092     // Check if sample ready
00093     return (isCapturing && (curSampleIdx == NUM_RETURN_SAMPLES));
00094 }
00095 
00096 void SampleChannel::StopSampling()
00097 {
00098     isCapturing = false;
00099 }
00100     
00101 void SampleChannel::StartSampling()
00102 {
00103     curSampleIdx = 0;
00104     isCapturing = true;
00105     sampleBaseVal = GetLowest();
00106     
00107     // Copy across values from trigger window
00108     for (int i = TRIGGER_WINDOW; i > 0; i--)
00109         AddSample(filterBuf[(curFilterIdx + NUM_FILTER_VALS - i) % NUM_FILTER_VALS]);        
00110 }
00111     
00112 bool SampleChannel::CheckTrigger()
00113 {
00114     // Check if the samples in the trigger window are significantly different from the average
00115     int spike = GetAvgOfTriggerWindow() - GetAvgOutsideTriggerWindow();
00116     if (spike < 0)
00117         spike = -spike;
00118     return spike > sampleThreshold;
00119 }
00120     
00121 uint8_t *SampleChannel::GetSamples()
00122 {
00123     return sampleBuf;
00124 }
00125     
00126 int SampleChannel::GetSamplesLen()
00127 {
00128     return NUM_RETURN_SAMPLES;
00129 }
00130