![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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
Diff: main.cpp
- Revision:
- 3:a155da1cbde3
- Parent:
- 2:e400fd4f501b
- Child:
- 4:cc164ecf6a36
--- a/main.cpp Thu Aug 21 07:48:18 2014 +0000 +++ b/main.cpp Thu Aug 21 11:26:26 2014 +0000 @@ -7,37 +7,32 @@ #define LOG_LEVEL_INFO #include "Puck.h" +#include "SampleChannel.h" Puck* puck = &Puck::getPuck(); // Gatt characteristic and service UUIDs const UUID SCORING_GATT_SERVICE = stringToUUID("nod.score1.serv "); -const UUID SAMPLES_GATT_CHARACTERISTIC = stringToUUID("nod.score1.samp1"); const UUID THRESHOLD_GATT_CHARACTERISTIC = stringToUUID("nod.score1.thres"); -const UUID OFFSET_GATT_CHARACTERISTIC = stringToUUID("nod.score1.offs "); const UUID DIVISOR_GATT_CHARACTERISTIC = stringToUUID("nod.score1.div "); const UUID INTERVAL_US_GATT_CHARACTERISTIC = stringToUUID("nod.score1.intus"); -const int SAMPLES_LEN = 20; -uint8_t SAMPLES_BUF[SAMPLES_LEN]; - -// Sample threshold -uint16_t sampleThreshold = 800; - -// Sample offset -uint16_t samplesOffset = 760; - -// Sample divisor -uint16_t samplesDivisor = 1; +const int NUM_SAMPLE_CHANNELS = 1; // Sample interval (uS) -uint32_t sampleIntervalUs = 10000; +uint32_t sampleIntervalUs = 100000; -// Setup ADC -AnalogIn ain(P0_1); +// Sample Channels +SampleChannel sampleChannels[] = +{ + SampleChannel(P0_1, stringToUUID("nod.score1.samp1"), &logger), + SampleChannel(P0_2, stringToUUID("nod.score1.samp2"), &logger), + SampleChannel(P0_3, stringToUUID("nod.score1.samp3"), &logger) +}; // Timer to avoid repeat sampling -Timer antiRepeatTimer; +Timer intervalTimer; +int lastTriggerTime = 0; int lastSampleTime = 0; const int MIN_MS_BETWEEN_SAMPLES = 2000; @@ -45,28 +40,24 @@ { uint16_t threshold = value[0] * 256 + value[1]; LOG_INFO("Threshold=%d\n", threshold); - sampleThreshold = threshold; -} - -void onOffsetSet(uint8_t* value) -{ - uint16_t offset = value[0] * 256 + value[1]; - LOG_INFO("Offset=%d\n", offset); - samplesOffset = offset; + for (int chanIdx = 0; chanIdx < NUM_SAMPLE_CHANNELS; chanIdx++) + sampleChannels[chanIdx].SetThreshold(threshold); } void onDivisorSet(uint8_t* value) { uint16_t divisor = value[0] * 256 + value[1]; LOG_INFO("Divisor=%d\n", divisor); - samplesDivisor = divisor; + for (int chanIdx = 0; chanIdx < NUM_SAMPLE_CHANNELS; chanIdx++) + sampleChannels[chanIdx].SetDivisor(divisor); } void onIntervalSet(uint8_t* value) { uint32_t intervalUs = (value[0] << 24) + (value[1] << 16) + (value[2] << 8) + value[3]; LOG_INFO("SampleInterval(uS)=%d\n", intervalUs); - sampleIntervalUs = intervalUs; + if (intervalUs <= 1000000) + sampleIntervalUs = intervalUs; } int main(void) @@ -76,33 +67,28 @@ logger.baud(115200); // Add the Gatt characteristic for samples - puck->addCharacteristic( + for (int chanIdx = 0; chanIdx < NUM_SAMPLE_CHANNELS; chanIdx++) + { + puck->addCharacteristic( SCORING_GATT_SERVICE, - SAMPLES_GATT_CHARACTERISTIC, - SAMPLES_LEN, + sampleChannels[chanIdx].GetUUID(), + sampleChannels[chanIdx].GetSamplesLen(), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); + } // Add the Gatt characteristic for threshold puck->addCharacteristic( SCORING_GATT_SERVICE, THRESHOLD_GATT_CHARACTERISTIC, - sizeof(sampleThreshold), + sizeof(uint16_t), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); puck->onCharacteristicWrite(&THRESHOLD_GATT_CHARACTERISTIC, onThresholdSet); - // Add the Gatt characteristic for offset - puck->addCharacteristic( - SCORING_GATT_SERVICE, - OFFSET_GATT_CHARACTERISTIC, - sizeof(samplesOffset), - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); - puck->onCharacteristicWrite(&OFFSET_GATT_CHARACTERISTIC, onOffsetSet); - // Add the Gatt characteristic for sample divisor puck->addCharacteristic( SCORING_GATT_SERVICE, DIVISOR_GATT_CHARACTERISTIC, - sizeof(samplesDivisor), + sizeof(uint16_t), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); puck->onCharacteristicWrite(&DIVISOR_GATT_CHARACTERISTIC, onDivisorSet); @@ -118,37 +104,67 @@ puck->init(0xCD01); // Start timer - antiRepeatTimer.start(); + intervalTimer.start(); // Wait for something to be found - while(puck->drive()) + while(true) { - int curTimerVal = antiRepeatTimer.read_ms(); - if ((lastSampleTime < curTimerVal) || (curTimerVal - lastSampleTime > MIN_MS_BETWEEN_SAMPLES)) + // service all channel's state machines + bool isAnyChannelSampling = false; + for (int chanIdx = 0; chanIdx < NUM_SAMPLE_CHANNELS; chanIdx++) { - // Check threshold - unsigned short val = ain.read_u16(); - if(val > sampleThreshold) + sampleChannels[chanIdx].Service(); + if (sampleChannels[chanIdx].AreSamplesReady()) { - for (int i = 0; i < SAMPLES_LEN; i++) + // Set the value of the characteristic + puck->updateCharacteristicValue(sampleChannels[chanIdx].GetUUID(), sampleChannels[chanIdx].GetSamples(), sampleChannels[chanIdx].GetSamplesLen()); + sampleChannels[chanIdx].StopSampling(); + LOG_INFO("StopSampling\n"); + } + if (sampleChannels[chanIdx].IsSampling()) + isAnyChannelSampling = true; + } + + if (!isAnyChannelSampling) + { + // Service the puck + puck->drive(); + + int curTimerVal = intervalTimer.read_ms(); + if ((lastTriggerTime < curTimerVal) || (curTimerVal - lastTriggerTime > MIN_MS_BETWEEN_SAMPLES)) + { + + // check each channel to see if it's been triggered + bool anythingTriggered = false; + for (int chanIdx = 0; chanIdx < NUM_SAMPLE_CHANNELS; chanIdx++) { - SAMPLES_BUF[i] = (ain.read_u16() - samplesOffset) / samplesDivisor; - wait_us(sampleIntervalUs); + if (sampleChannels[chanIdx].CheckTrigger()) + { + anythingTriggered = true; + LOG_INFO("Triggered\n"); + break; + } } - - // Set the value of the characteristic - puck->updateCharacteristicValue(SAMPLES_GATT_CHARACTERISTIC, SAMPLES_BUF, SAMPLES_LEN); - - // Display readings - for (int j = 0; j < SAMPLES_LEN; j++) + if(anythingTriggered) { - LOG_INFO("%02x ", SAMPLES_BUF[j]); + for (int chanIdx = 0; chanIdx < NUM_SAMPLE_CHANNELS; chanIdx++) + { + sampleChannels[chanIdx].StartSampling(); + } + // Set timer to disallow repeated readings + lastTriggerTime = curTimerVal; } - LOG_INFO("\n"); + } + } + else + { + wait_us(sampleIntervalUs); + } - // Set timer to disallow repeated readings - lastSampleTime = curTimerVal; - } - } + // Inter-sample interval + //while ((intervalTimer.read_us() - lastSampleTime < sampleIntervalUs) && (intervalTimer.read_us() - lastSampleTime > 0)) + // wait_us(100); +// lastSampleTime = intervalTimer.read_us(); +// LOG_INFO("Timer %d\n", intervalTimer.read_ms()); } }