EEP fORK
Dependencies: BLE_API mbed nRF51822
Fork of MCS_LRF by
main.cpp
- Committer:
- Farshad
- Date:
- 2015-12-22
- Revision:
- 10:d37cd13dd529
- Parent:
- 8:ed66e7ef8243
- Child:
- 12:cf8af0b4e0d2
File content as of revision 10:d37cd13dd529:
/* mbed Microcontroller Library * Copyright (c) 2006-2013 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mbed.h" #include "Serial.h" #include "BLE.h" #include "DeviceInformationService.h" #include "UARTService.h" #include "bleHelper.h" #include "laser.h" #undef BLE_DEBUG_OUTPUT /* Set this if you need debug messages on the console; * it will have an impact on code-size and power consumption. */ #define NEED_CONSOLE_OUTPUT 0 // only used for parsing tag data- will not work if parse function is called from within serial interrupt #define NEED_PARSE_TRACE 0 Serial pc(USBTX, USBRX); #if NEED_CONSOLE_OUTPUT #define DEBUG(...) { pc.printf(__VA_ARGS__); } #else #define DEBUG(...) /* nothing */ #endif /* #if NEED_CONSOLE_OUTPUT */ #if NEED_PARSE_TRACE #define TRACE(...) { pc.printf(__VA_ARGS__); } #else #define TRACE(...) #endif /* #if NEED_TRACE */ #define SET_PARAM_CMD_MASK 0x8000 // commands with MSB set to 0 are to get the parameter and MSB of 1 to set the parameter #define READER_BAUD_RATE 115200 #define PB_DEBUNCE_TIME 100 #define PB_HOLD_TIME 1000 // ms- Holding the push button longer than this will turn the laser dot off if it is on #undef NORDIC // is board nordic DK? #ifdef NORDIC DigitalOut connectionLed(p21); DigitalOut triggerLed(p22); Serial serial(p13, p17); // tx, rx === NOTE tx port pin needs to be wired and verified (for nordic DK) Laser laser(serial); InterruptIn triggerButton(p18); // Button 2 #else DigitalOut connectionLed(p23); Serial serial(p27, p26); // tx, rx === for adafruit BLE UART board (small blue board with red BLE module) Laser laser(serial); InterruptIn triggerButton(p22); #endif BLEDevice ble; UARTService *uartServicePtr; BLEHelper* bleHelper; static uint8_t isConnected = 0; Timer timer; const static char DEVICE_NAME[] = "MCS_LRF"; const static char MANUFACTURER[] = "MCS"; const static char MODEL[] = "Model 1"; const static char SERIAL_NO[] = "SN 1234"; const static char HARDWARE_REV[] = "hw-rev 1"; const static char FIRMWARE_REV[] = "fw-rev 1"; const static char SOFTWARE_REV[] = "soft-rev 1"; // these values must macth definitions in the XML file accompanying this device const static uint16_t distanceCmd = 0x0001; const static uint16_t triggerCmd = 0x0002; const static uint16_t redDotCmd = 0x0003; void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { DEBUG("Disconnected!\n\r"); DEBUG("Restarting the advertising process\n\r"); ble.startAdvertising(); isConnected = 0; connectionLed = isConnected; } void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { DEBUG("Connected!\n\r"); isConnected = 1; connectionLed = isConnected; } static void processData(const GattWriteCallbackParams *params) { if(params->len >= 2) { uint16_t command = params->data[0] + (params->data[1] << 8); bool isSetCmd = (command & SET_PARAM_CMD_MASK) == SET_PARAM_CMD_MASK; DEBUG("command: %d \r\n", command); switch(command & ~SET_PARAM_CMD_MASK) { case distanceCmd: if(!isSetCmd && params->len == 2) { // form the reply to send DEBUG("CMD is GET distance\n\r"); laser.triggerDistanceMeasurement(); } break; // TODO not needed really- can just use the distance command case triggerCmd: if(isSetCmd && params->len == 3) { // form the reply to send DEBUG("CMD is SET trigger\n\r"); laser.triggerDistanceMeasurement(); } break; case redDotCmd: if(isSetCmd && params->len == 3) { DEBUG("CMD is SET redDot\n\r"); laser.setRedDot(params->data[2]); } break; default: break; } } } void onDataWritten(const GattWriteCallbackParams *params) { if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) { uint16_t bytesRead = params->len; DEBUG("received %u bytes\n\r", bytesRead); for(int i = 0; i < bytesRead; i++) { DEBUG("0x%X ", params->data[i]); } DEBUG("\n\r", bytesRead); // echo? // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead); processData(params); } } // this is an ISR, so do not spend too much time here and be careful with printing debug info void readerCallback() { //if(serial.readable()) { // laser.processRxData(serial.getc()); // } } /* This method is called when a distance measurement is ready to be sent to the client. send distance measurement to the connected BLE client */ void distanceCallcack(float distance, float elapsedTime) { uint8_t buf[10]; uint16_t arrayLen = 2; memcpy(&buf[0], &arrayLen, sizeof(uint16_t)); memcpy(&buf[2], &distance, sizeof(float)); memcpy(&buf[6], &elapsedTime, sizeof(float)); bleHelper->sendPacketOverBLE(distanceCmd, buf, sizeof(buf)); } /* processor for the hardware trigger button */ void triggerFall() { timer.reset(); timer.start(); } /* interrupt processor for when the button is released. If it has been pushed and held, turn the red dot off on release, otherwise debunce and make a measurement */ void triggerRise() { int elapsed = timer.read_ms(); timer.stop(); if(elapsed > PB_HOLD_TIME) { laser.setRedDot(0); } else if(elapsed > PB_DEBUNCE_TIME) { laser.triggerDistanceMeasurement(); } } int main(void) { // default state is unknown connectionLed = 0; DEBUG("Initialising the nRF51822\n\r"); ble.init(); ble.onDisconnection(disconnectionCallback); ble.onConnection(connectionCallback); ble.onDataWritten(onDataWritten); /* setup advertising */ ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME) - 1); ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)GattService::UUID_DEVICE_INFORMATION_SERVICE, sizeof(GattService::UUID_DEVICE_INFORMATION_SERVICE)); ble.setAdvertisingInterval(GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); ble.startAdvertising(); /* Setup uart service */ UARTService uartService(ble); uartServicePtr = &uartService; /* Setup auxiliary service. */ DeviceInformationService deviceInfo(ble, MANUFACTURER, MODEL, SERIAL_NO,HARDWARE_REV, FIRMWARE_REV, SOFTWARE_REV); /* Setup bleHelper */ BLEHelper helper(&ble, uartServicePtr); bleHelper = &helper; // setup serial port to LRF serial.baud(READER_BAUD_RATE); // serial.attach(&readerCallback); // processors for the trigger button triggerButton.fall(&triggerFall); triggerButton.rise(&triggerRise); // setup laser laser.enableMeasurement(true); laser.setDistaceCallback(&distanceCallcack); while (true) { ble.waitForEvent(); } }