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
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
Generated on Wed Jul 13 2022 12:34:33 by 1.7.2