SunTracker_BLE_Remote
Dependencies: BLE_API X_NUCLEO_IDB0XA1 X_NUCLEO_IKS01A1 mbed
Fork of SunTracker_BLE_Remote by
This application is the BLE Remote Control for the SunTracker demo application that you can find
here.
Please refer to that page for further information.
main.cpp
- Committer:
- fabiombed
- Date:
- 2016-03-21
- Revision:
- 5:5e62f661a7ab
- Parent:
- 4:17f96ffc073a
- Child:
- 6:ce0e5024e3fa
File content as of revision 5:5e62f661a7ab:
/** ****************************************************************************** * @file main.cpp * @author Fabio Brembilla * @version V2.0.0 * @date March, 2016 * @brief SunTracker + BLE (Client) Vertical Application * This application use IKS01A1, IDB0XA1 expansion boards ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Define --------------------------------------------------------------------*/ #define Sensors //IKS01A1 Option /* Includes ------------------------------------------------------------------*/ #include "mbed.h" #include "ble/BLE.h" #include "ble/DiscoveredCharacteristic.h" #include "ble/DiscoveredService.h" #ifdef Sensors #include "DevI2C.h" #include "x_nucleo_iks01a1.h" #endif /* BlueTooth -----------------------------------------------------------------*/ #include "Utils.h" // Need for STORE_LE_16 and STORE_LE_32 #define SCAN_INT 0x30 // 30 ms = 48 * 0.625 ms #define SCAN_WIND 0x30 // 30 ms = 48 * 0.625 ms const Gap::Address_t BLE_address_BE = {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA}; // CLIENT address const Gap::Address_t BLE_peer_address_BE = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; // SERVER address (must be the same of SERVER) //const Gap::Address_t BLE_address_BE = {0xCC, 0x00, 0x00, 0xE1, 0x80, 0x02}; // CLIENT address //const Gap::Address_t BLE_peer_address_BE = {0xFD, 0x66, 0x05, 0x13, 0xBE, 0xBA}; // SERVER address (must be the same of SERVER) DiscoveredCharacteristic userbutton_bleCharacteristic; DiscoveredCharacteristic difference_bleCharacteristic; DiscoveredCharacteristic position_bleCharacteristic; DiscoveredCharacteristic sunpanel_bleCharacteristic; #define SIZEOF_CONTROL_DATA_LEN 2 #define DIFFERENCE_DATA_LEN 2 // 1 byte 0xFF 8 bit int8 // 2 byte 0xFFFF 16 bit int16 uint8_t value_write[SIZEOF_CONTROL_DATA_LEN]; int16_t value_read = 0; uint8_t value_write_diff[DIFFERENCE_DATA_LEN]; /* Variables ------------------------------------------------------------------*/ enum { IDLE = 0, READ_BUT = 1, READ_DIF = 2, READ_POS = 3, READ_SUN = 4, WRITE_BUT = 5, WRITE_DIF = 6 }; int trigger_Op = IDLE; bool trigger_button = false; int8_t display=0; // Shown on Display: 0 = Motor Speed, 1 = Solar Panel Value, 2 = Manual Control [--> Receive BLE] int16_t diff=0; // Babybear or Accelerometer difference [--> Receive BLE] int16_t pos=0; // Motor Position [--> Receive BLE] int16_t measure=0; // ADC Value from SunPanel [--> Receive BLE] /* Initializations ------------------------------------------------------------*/ #ifdef Sensors // Initializing I2C bus DevI2C dev_i2c(D14, D15); // Initializing Sensors Component IKS01A1 static X_NUCLEO_IKS01A1 *mems; MotionSensor *accelerometer; int32_t acc_data[3]; // Accelerometer difference int16_t acc_diff=0; // Accelerometer difference #endif InterruptIn mybutton(USER_BUTTON); /* User_Button_Pressed -------------------------------------------------------*/ void User_Button_Pressed(void) { trigger_button = true; } /* Bluetooth CallBack ---------------------------------------------------------*/ void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { if (params->peerAddr[0] != BLE_peer_address_BE[0]) // return if miss the server MAC address { printf("Missing Expected MAC Address"); return; // exit from advertisementCallback } // printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", // params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0], // params->rssi, params->isScanResponse, params->type); printf("Found Expected MAC Address: isScanResponse %u, AdvertisementType %u\r\n",params->isScanResponse, params->type); if(!params->isScanResponse) { BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL); } } void serviceDiscoveryCallback(const DiscoveredService *service) { printf("Start Service Discovery\r\n"); /* if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); } else { printf("S UUID-"); const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { printf("%02X", longUUIDBytes[i]); } printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); } */ } void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { if (characteristicP->getUUID().getShortUUID() == 0xA001) { userbutton_bleCharacteristic = *characteristicP; printf("Found 0xA001 Characteristic\r\n"); } if (characteristicP->getUUID().getShortUUID() == 0xB001) { difference_bleCharacteristic = *characteristicP; printf("Found 0xB001 Characteristic\r\n"); } if (characteristicP->getUUID().getShortUUID() == 0xB002) { position_bleCharacteristic = *characteristicP; printf("Found 0xB002 Characteristic\r\n"); } if (characteristicP->getUUID().getShortUUID() == 0xB003) { sunpanel_bleCharacteristic = *characteristicP; printf("Found 0xB003 Characteristic\r\n"); } } void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { //printf("discoveryTerminationCallback for handle %u\r\n", connectionHandle); printf("Stop Service Discovery\r\n\r\n"); trigger_Op = READ_BUT; } void onDataReadCallback(const GattReadCallbackParams *response) { // Read SERVER --> CLIENT /* printf("response Handle %d\r\n", response->handle); printf("userbutton Handle %d\r\n", userbutton_bleCharacteristic.getValueHandle()); printf("difference Handle %d\r\n", difference_bleCharacteristic.getValueHandle()); printf("position Handle %d\r\n", position_bleCharacteristic.getValueHandle()); printf("sunpanel Handle %d\r\n", sunpanel_bleCharacteristic.getValueHandle()); printf("onDataRead (data[0] %x)\r\n", response->data[0]); printf("onDataRead (data[1] %x)\r\n\r\n", response->data[1]); */ // Return original value after inverted with STORE_LE_16 to send by BLE value_read = response->data[0] + (response->data[1]<<8); if (response->handle == userbutton_bleCharacteristic.getValueHandle()) { display = value_read; printf("\n\rReceive BLE Display %d\n\r", display); trigger_Op = READ_DIF; } if (response->handle == difference_bleCharacteristic.getValueHandle()) { diff = value_read; printf("Receive BLE Difference %d lux/mems\n\r", diff); trigger_Op = READ_POS; } if (response->handle == position_bleCharacteristic.getValueHandle()) { pos = value_read; printf("Receive BLE Position %d\n\r", pos); trigger_Op = READ_SUN; } if (response->handle == sunpanel_bleCharacteristic.getValueHandle()) { measure = value_read; printf("Receive BLE Sunpanel %d mV\n\r", measure); trigger_Op = WRITE_BUT; } } void myonDataWriteCallback(const GattWriteCallbackParams *response) { // Write CLIENT --> SERVER //printf("myonDataWrite (data[0] %x)\n\r", response->data[0]); //printf("myonDataWrite (data[1] %x)\n\r\n\r", response->data[1]); // Return original value after inverted with STORE_LE_16 to send by BLE value_read = response->data[0] + (response->data[1]<<8); if (response->handle == userbutton_bleCharacteristic.getValueHandle()) { printf("\r\n\r\nonDataWrite BUTTON (data %d)\r\n", value_read); trigger_Op = READ_BUT; } if (response->handle == difference_bleCharacteristic.getValueHandle()) { //printf("onDataWrite DIFF (data %d)\r\n", value_read); trigger_Op = READ_BUT; } } /** * This function is called when the ble initialization process has failled */ void onBleInitError(BLE &ble, ble_error_t error) { /* Initialization error handling should go here */ printf("Inizialization Error\n\r"); } void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { //uint16_t CONTROL_SERVICE_UUID = 0xA000; //uint16_t USERBUTTON_CHARACTERISTIC_UUID = 0xA001; //uint16_t SENSORS_SERVICE_UUID = 0xB000; //uint16_t DIFFERENCE_CHARACTERISTIC_UUID = 0xB001; //uint16_t POSITION_CHARACTERISTIC_UUID = 0xB002; //uint16_t SUNPANEL_CHARACTERISTIC_UUID = 0xB003; if (params->role == Gap::CENTRAL) { BLE &ble = BLE::Instance(); ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); // Discover all SERVICES and CHARACTERISTICS ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback); // Works only for one characteristic, if you need to discover all characteristic, use the above command //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, CONTROL_SERVICE_UUID, USERBUTTON_CHARACTERISTIC_UUID); //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, DIFFERENCE_CHARACTERISTIC_UUID); //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, POSITION_CHARACTERISTIC_UUID); //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, SUNPANEL_CHARACTERISTIC_UUID); } printf("Remote Connected\n\r"); } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { (void)params; printf("Remote Disconnected\n\r"); } /** * Callback triggered when the ble initialization process has finished */ void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { BLE& ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { /* In case of error, forward the error handling to onBleInitError */ onBleInitError(ble, error); return; } /* Ensure that it is the default instance of BLE */ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } // Set BT Address ble.gap().setAddress(BLEProtocol::AddressType::PUBLIC, BLE_address_BE); ble.gap().onConnection(connectionCallback); ble.onDisconnection(disconnectionCallback); ble.gattClient().onDataRead(onDataReadCallback); ble.gattClient().onDataWrite(myonDataWriteCallback); ble.gap().setScanParams(SCAN_INT, SCAN_WIND); ble.gap().startScan(advertisementCallback); // Main Loop while (true) { //if (!ble.gattClient().isServiceDiscoveryActive()) if (trigger_Op!=IDLE) // Wait until discoveryTerminationCallback { // At present ARM BLE_API don't support Enable/Disable Notify from Client //userbutton_bleCharacteristic.notify(); //difference_bleCharacteristic.notify(); //position_bleCharacteristic.notify(); //sunpanel_bleCharacteristic.notify(); // Don't run more ble .read or .write in the same loop // because the callback is an interrupt and it doesn't work correctly if overloaded if (display == 0 || display == 1) { if (trigger_Op == WRITE_DIF) trigger_Op = READ_BUT; } // if Display 0 or 1, skip WRITE_DIF if (display == 2) { if (trigger_Op == READ_DIF) trigger_Op = WRITE_BUT; } // if Display 2, skip READ_DIF, READ_POS, READ_SUN switch(trigger_Op) { case READ_BUT: userbutton_bleCharacteristic.read(); trigger_Op = IDLE; break; case READ_DIF: difference_bleCharacteristic.read(); trigger_Op = IDLE; break; case READ_POS: position_bleCharacteristic.read(); trigger_Op = IDLE; break; case READ_SUN: sunpanel_bleCharacteristic.read(); trigger_Op = IDLE; break; case WRITE_BUT: if (trigger_button == true) { memset (value_write, 0, SIZEOF_CONTROL_DATA_LEN); STORE_LE_16(value_write, 1234); userbutton_bleCharacteristic.write(SIZEOF_CONTROL_DATA_LEN, value_write); trigger_Op = IDLE; trigger_button = false; } else { #ifdef Sensors trigger_Op = WRITE_DIF; #else trigger_Op = READ_BUT; #endif } break; case WRITE_DIF: #ifdef Sensors accelerometer->Get_X_Axes(acc_data); acc_diff = acc_data[0]; //printf("Send BLE Difference %d lux/mems\n\r", acc_diff); memset (value_write_diff, 0, DIFFERENCE_DATA_LEN); STORE_LE_16(value_write_diff, acc_diff); difference_bleCharacteristic.write(DIFFERENCE_DATA_LEN, value_write_diff); trigger_Op = IDLE; #else trigger_Op = READ_BUT; #endif break; default: break; } } ble.waitForEvent(); } } /* Ticker --------------------------------------------------------------------*/ /* void ticker_Callback(void) { } */ /* Main ----------------------------------------------------------------------*/ int main(void) { printf("\r\n\r\nSunTracker Remote Control\r\n\r\n"); #ifdef Sensors // Initializing Sensors Component mems=X_NUCLEO_IKS01A1::Instance(&dev_i2c); accelerometer = mems->GetAccelerometer(); printf("Init Sensors OK\r\n"); #endif //Ticker ticker; //ticker.attach(ticker_Callback, 1); // every 1 second mybutton.fall(&User_Button_Pressed); BLE::Instance().init(bleInitComplete); }