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

SampleChannel.cpp

Committer:
Bobty
Date:
2014-08-26
Revision:
10:a2ba0cef85aa
Parent:
8:87a3708dca9c

File content as of revision 10:a2ba0cef85aa:

// 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;
}