![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Dependencies: AccelSensor BLE_API mbed nRF51822
main.cpp@0:027b7829b46a, 2018-01-19 (annotated)
- Committer:
- fjaviercifuentes
- Date:
- Fri Jan 19 02:38:38 2018 +0000
- Revision:
- 0:027b7829b46a
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fjaviercifuentes | 0:027b7829b46a | 1 | #include "mbed.h" |
fjaviercifuentes | 0:027b7829b46a | 2 | #include "ble/BLE.h" |
fjaviercifuentes | 0:027b7829b46a | 3 | #include "RELAYService.h" |
fjaviercifuentes | 0:027b7829b46a | 4 | #include "ALARMService.h" |
fjaviercifuentes | 0:027b7829b46a | 5 | #include "BatteryService.h" |
fjaviercifuentes | 0:027b7829b46a | 6 | #include "InternalValuesService.h" |
fjaviercifuentes | 0:027b7829b46a | 7 | #include "ImobStateService.h" |
fjaviercifuentes | 0:027b7829b46a | 8 | #include "AccelSensorService.h" |
fjaviercifuentes | 0:027b7829b46a | 9 | |
fjaviercifuentes | 0:027b7829b46a | 10 | #define TIME_CICLE 80.0 //ms |
fjaviercifuentes | 0:027b7829b46a | 11 | #define ANALOGIN 3 |
fjaviercifuentes | 0:027b7829b46a | 12 | #define DISCONNECTION_TIME (1000.0/TIME_CICLE)*10.0 // seg |
fjaviercifuentes | 0:027b7829b46a | 13 | #define AUTHENTICATION_TIME (1000.0/TIME_CICLE)*25.0 // seg |
fjaviercifuentes | 0:027b7829b46a | 14 | |
fjaviercifuentes | 0:027b7829b46a | 15 | |
fjaviercifuentes | 0:027b7829b46a | 16 | /* LED aliveness indicator system */ |
fjaviercifuentes | 0:027b7829b46a | 17 | DigitalOut alivenessLED(P0_18, 0); // P0_25 |
fjaviercifuentes | 0:027b7829b46a | 18 | |
fjaviercifuentes | 0:027b7829b46a | 19 | /* battery charge level, Pin P0_1 */ |
fjaviercifuentes | 0:027b7829b46a | 20 | AnalogIn batteryCharge(P0_1); |
fjaviercifuentes | 0:027b7829b46a | 21 | /* lipo charger Status, Pin P0_2 */ |
fjaviercifuentes | 0:027b7829b46a | 22 | AnalogIn lcStat(P0_2); |
fjaviercifuentes | 0:027b7829b46a | 23 | /* Chack contact, Pin P0_6 */ |
fjaviercifuentes | 0:027b7829b46a | 24 | AnalogIn contact(P0_6); |
fjaviercifuentes | 0:027b7829b46a | 25 | |
fjaviercifuentes | 0:027b7829b46a | 26 | |
fjaviercifuentes | 0:027b7829b46a | 27 | /* Device name setting to identifying your device */ |
fjaviercifuentes | 0:027b7829b46a | 28 | const static char DEVICE_NAME[] = "I-Mob"; |
fjaviercifuentes | 0:027b7829b46a | 29 | static const uint16_t uuid16_list[] = {ImobStateService::IMOB_STATE_SERVICE_UUID, RELAYService::RELAY_SERVICE_UUID, ALARMService::ALARM_SERVICE_UUID, InternalValuesService::INTERNAL_VALUES_SERVICE_UUID, AccelSensorService::ACCEL_SENSOR_SERVICE_UUID, GattService::UUID_BATTERY_SERVICE}; |
fjaviercifuentes | 0:027b7829b46a | 30 | |
fjaviercifuentes | 0:027b7829b46a | 31 | |
fjaviercifuentes | 0:027b7829b46a | 32 | ImobStateService * imobStateServicePtr; |
fjaviercifuentes | 0:027b7829b46a | 33 | |
fjaviercifuentes | 0:027b7829b46a | 34 | InternalValuesService * internalValuesServicePtr; |
fjaviercifuentes | 0:027b7829b46a | 35 | RELAYService * relayServicePtr; |
fjaviercifuentes | 0:027b7829b46a | 36 | ALARMService * alarmServicePtr; |
fjaviercifuentes | 0:027b7829b46a | 37 | AccelSensorService * accelSensorServicePtr; |
fjaviercifuentes | 0:027b7829b46a | 38 | BatteryService * batteryServicePtr; |
fjaviercifuentes | 0:027b7829b46a | 39 | |
fjaviercifuentes | 0:027b7829b46a | 40 | float lipochargerState = 0; |
fjaviercifuentes | 0:027b7829b46a | 41 | float contactState = -1; |
fjaviercifuentes | 0:027b7829b46a | 42 | uint8_t batteryLevel = 0; |
fjaviercifuentes | 0:027b7829b46a | 43 | |
fjaviercifuentes | 0:027b7829b46a | 44 | uint8_t selectedAnalogIn = 0; |
fjaviercifuentes | 0:027b7829b46a | 45 | |
fjaviercifuentes | 0:027b7829b46a | 46 | uint32_t forceDisconnectionCounter = 0; |
fjaviercifuentes | 0:027b7829b46a | 47 | uint32_t forceActivationCounter = 0; |
fjaviercifuentes | 0:027b7829b46a | 48 | |
fjaviercifuentes | 0:027b7829b46a | 49 | /* Calibration variables */ |
fjaviercifuentes | 0:027b7829b46a | 50 | bool batteryLevelCalibration = false; |
fjaviercifuentes | 0:027b7829b46a | 51 | float batteryLevelConstant = 100.0f; |
fjaviercifuentes | 0:027b7829b46a | 52 | float contactStateThreshold = 0.21f; |
fjaviercifuentes | 0:027b7829b46a | 53 | /* ----- */ |
fjaviercifuentes | 0:027b7829b46a | 54 | |
fjaviercifuentes | 0:027b7829b46a | 55 | Ticker ticker; |
fjaviercifuentes | 0:027b7829b46a | 56 | |
fjaviercifuentes | 0:027b7829b46a | 57 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) |
fjaviercifuentes | 0:027b7829b46a | 58 | { |
fjaviercifuentes | 0:027b7829b46a | 59 | /* Re-enable advertisements after a connection teardown */ |
fjaviercifuentes | 0:027b7829b46a | 60 | BLE::Instance().gap().startAdvertising(); |
fjaviercifuentes | 0:027b7829b46a | 61 | } |
fjaviercifuentes | 0:027b7829b46a | 62 | |
fjaviercifuentes | 0:027b7829b46a | 63 | void periodicCallback(void) |
fjaviercifuentes | 0:027b7829b46a | 64 | { |
fjaviercifuentes | 0:027b7829b46a | 65 | /* Do blinky on LED1 to indicate system aliveness. */ |
fjaviercifuentes | 0:027b7829b46a | 66 | alivenessLED = !alivenessLED; |
fjaviercifuentes | 0:027b7829b46a | 67 | } |
fjaviercifuentes | 0:027b7829b46a | 68 | |
fjaviercifuentes | 0:027b7829b46a | 69 | /** |
fjaviercifuentes | 0:027b7829b46a | 70 | * This function is called when the ble initialization process has failed |
fjaviercifuentes | 0:027b7829b46a | 71 | */ |
fjaviercifuentes | 0:027b7829b46a | 72 | void onBleInitError(BLE &ble, ble_error_t error) |
fjaviercifuentes | 0:027b7829b46a | 73 | { |
fjaviercifuentes | 0:027b7829b46a | 74 | /* Initialization error handling should go here */ |
fjaviercifuentes | 0:027b7829b46a | 75 | } |
fjaviercifuentes | 0:027b7829b46a | 76 | |
fjaviercifuentes | 0:027b7829b46a | 77 | /** |
fjaviercifuentes | 0:027b7829b46a | 78 | * Callback triggered when the ble initialization process has finished |
fjaviercifuentes | 0:027b7829b46a | 79 | */ |
fjaviercifuentes | 0:027b7829b46a | 80 | void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) |
fjaviercifuentes | 0:027b7829b46a | 81 | { |
fjaviercifuentes | 0:027b7829b46a | 82 | BLE& ble = params->ble; |
fjaviercifuentes | 0:027b7829b46a | 83 | ble_error_t error = params->error; |
fjaviercifuentes | 0:027b7829b46a | 84 | |
fjaviercifuentes | 0:027b7829b46a | 85 | if (error != BLE_ERROR_NONE) |
fjaviercifuentes | 0:027b7829b46a | 86 | { |
fjaviercifuentes | 0:027b7829b46a | 87 | /* In case of error, forward the error handling to onBleInitError */ |
fjaviercifuentes | 0:027b7829b46a | 88 | onBleInitError(ble, error); |
fjaviercifuentes | 0:027b7829b46a | 89 | return; |
fjaviercifuentes | 0:027b7829b46a | 90 | } |
fjaviercifuentes | 0:027b7829b46a | 91 | |
fjaviercifuentes | 0:027b7829b46a | 92 | /* Ensure that it is the default instance of BLE */ |
fjaviercifuentes | 0:027b7829b46a | 93 | if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) |
fjaviercifuentes | 0:027b7829b46a | 94 | { |
fjaviercifuentes | 0:027b7829b46a | 95 | return; |
fjaviercifuentes | 0:027b7829b46a | 96 | } |
fjaviercifuentes | 0:027b7829b46a | 97 | |
fjaviercifuentes | 0:027b7829b46a | 98 | ble.gap().onDisconnection(disconnectionCallback); |
fjaviercifuentes | 0:027b7829b46a | 99 | |
fjaviercifuentes | 0:027b7829b46a | 100 | imobStateServicePtr = new ImobStateService(ble); |
fjaviercifuentes | 0:027b7829b46a | 101 | |
fjaviercifuentes | 0:027b7829b46a | 102 | internalValuesServicePtr = new InternalValuesService(ble, imobStateServicePtr); |
fjaviercifuentes | 0:027b7829b46a | 103 | relayServicePtr = new RELAYService(ble, imobStateServicePtr); |
fjaviercifuentes | 0:027b7829b46a | 104 | alarmServicePtr = new ALARMService(ble); |
fjaviercifuentes | 0:027b7829b46a | 105 | accelSensorServicePtr = new AccelSensorService(ble); |
fjaviercifuentes | 0:027b7829b46a | 106 | batteryServicePtr = new BatteryService(ble, batteryLevel); |
fjaviercifuentes | 0:027b7829b46a | 107 | |
fjaviercifuentes | 0:027b7829b46a | 108 | /* setup advertising */ |
fjaviercifuentes | 0:027b7829b46a | 109 | |
fjaviercifuentes | 0:027b7829b46a | 110 | /* BREDR_NOT_SUPPORTED means classic bluetooth not supported; |
fjaviercifuentes | 0:027b7829b46a | 111 | * LE_GENERAL_DISCOVERABLE means that this peripheral can be discovered by any BLE scanner--i.e. any phone. |
fjaviercifuentes | 0:027b7829b46a | 112 | */ |
fjaviercifuentes | 0:027b7829b46a | 113 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
fjaviercifuentes | 0:027b7829b46a | 114 | /* Adding the RELAY service UUID to the advertising payload*/ |
fjaviercifuentes | 0:027b7829b46a | 115 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); |
fjaviercifuentes | 0:027b7829b46a | 116 | /* This is where we're collecting the device name into the advertisement payload. */ |
fjaviercifuentes | 0:027b7829b46a | 117 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
fjaviercifuentes | 0:027b7829b46a | 118 | /* We'd like for this BLE peripheral to be connectable. */ |
fjaviercifuentes | 0:027b7829b46a | 119 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
fjaviercifuentes | 0:027b7829b46a | 120 | /* set the interval at which advertisements are sent out, 1000ms. */ |
fjaviercifuentes | 0:027b7829b46a | 121 | ble.gap().setAdvertisingInterval(TIME_CICLE); |
fjaviercifuentes | 0:027b7829b46a | 122 | /* we're finally good to go with advertisements. */ |
fjaviercifuentes | 0:027b7829b46a | 123 | ble.gap().startAdvertising(); |
fjaviercifuentes | 0:027b7829b46a | 124 | } |
fjaviercifuentes | 0:027b7829b46a | 125 | |
fjaviercifuentes | 0:027b7829b46a | 126 | int main(void) |
fjaviercifuentes | 0:027b7829b46a | 127 | { |
fjaviercifuentes | 0:027b7829b46a | 128 | /* Setting up a callback to go at an interval of 1s. */ |
fjaviercifuentes | 0:027b7829b46a | 129 | ticker.attach(periodicCallback, TIME_CICLE/1000.0); |
fjaviercifuentes | 0:027b7829b46a | 130 | |
fjaviercifuentes | 0:027b7829b46a | 131 | /* initialize the BLE stack and controller. */ |
fjaviercifuentes | 0:027b7829b46a | 132 | BLE &ble = BLE::Instance(); |
fjaviercifuentes | 0:027b7829b46a | 133 | ble.init(bleInitComplete); |
fjaviercifuentes | 0:027b7829b46a | 134 | |
fjaviercifuentes | 0:027b7829b46a | 135 | /* Accelerometer functions |
fjaviercifuentes | 0:027b7829b46a | 136 | accelerometer.init(); |
fjaviercifuentes | 0:027b7829b46a | 137 | accelerometer.standby(); |
fjaviercifuentes | 0:027b7829b46a | 138 | accelerometer.active(); |
fjaviercifuentes | 0:027b7829b46a | 139 | int accel[3]; |
fjaviercifuentes | 0:027b7829b46a | 140 | accelerometer.readData(accel); |
fjaviercifuentes | 0:027b7829b46a | 141 | accelerometer.standby(); |
fjaviercifuentes | 0:027b7829b46a | 142 | */ |
fjaviercifuentes | 0:027b7829b46a | 143 | |
fjaviercifuentes | 0:027b7829b46a | 144 | /* SpinWait for initialization to complete. This is necessary because the |
fjaviercifuentes | 0:027b7829b46a | 145 | * BLE object is used in the main loop below. */ |
fjaviercifuentes | 0:027b7829b46a | 146 | while (ble.hasInitialized() == false) { /* spin loop */ } |
fjaviercifuentes | 0:027b7829b46a | 147 | |
fjaviercifuentes | 0:027b7829b46a | 148 | while (true) |
fjaviercifuentes | 0:027b7829b46a | 149 | { |
fjaviercifuentes | 0:027b7829b46a | 150 | /* this will return upon any system event (such as an interrupt or a ticker wakeup) */ |
fjaviercifuentes | 0:027b7829b46a | 151 | ble.waitForEvent(); |
fjaviercifuentes | 0:027b7829b46a | 152 | bool accel = accelSensorServicePtr->updateAccelDetection(); |
fjaviercifuentes | 0:027b7829b46a | 153 | |
fjaviercifuentes | 0:027b7829b46a | 154 | /* Update battery charge level */ |
fjaviercifuentes | 0:027b7829b46a | 155 | if (selectedAnalogIn == 0) |
fjaviercifuentes | 0:027b7829b46a | 156 | { |
fjaviercifuentes | 0:027b7829b46a | 157 | batteryLevel = (uint8_t)(batteryCharge.read()*batteryLevelConstant); |
fjaviercifuentes | 0:027b7829b46a | 158 | batteryServicePtr->updateBatteryLevel(batteryLevel); |
fjaviercifuentes | 0:027b7829b46a | 159 | } |
fjaviercifuentes | 0:027b7829b46a | 160 | /* Update lipo charger state */ |
fjaviercifuentes | 0:027b7829b46a | 161 | if (selectedAnalogIn == 1) |
fjaviercifuentes | 0:027b7829b46a | 162 | { |
fjaviercifuentes | 0:027b7829b46a | 163 | lipochargerState = lcStat.read(); |
fjaviercifuentes | 0:027b7829b46a | 164 | uint8_t aux_lipochargerState; |
fjaviercifuentes | 0:027b7829b46a | 165 | |
fjaviercifuentes | 0:027b7829b46a | 166 | uint8_t pass_lipochargerState = internalValuesServicePtr->getLipoChargerState(); |
fjaviercifuentes | 0:027b7829b46a | 167 | |
fjaviercifuentes | 0:027b7829b46a | 168 | if (lipochargerState > 0.4) |
fjaviercifuentes | 0:027b7829b46a | 169 | { |
fjaviercifuentes | 0:027b7829b46a | 170 | if (lipochargerState > 0.9) |
fjaviercifuentes | 0:027b7829b46a | 171 | { |
fjaviercifuentes | 0:027b7829b46a | 172 | aux_lipochargerState = 1; |
fjaviercifuentes | 0:027b7829b46a | 173 | if (pass_lipochargerState == 0) internalValuesServicePtr->updateChargeProgramCyclesCharacteristic(); |
fjaviercifuentes | 0:027b7829b46a | 174 | } |
fjaviercifuentes | 0:027b7829b46a | 175 | else |
fjaviercifuentes | 0:027b7829b46a | 176 | { |
fjaviercifuentes | 0:027b7829b46a | 177 | aux_lipochargerState = 2; |
fjaviercifuentes | 0:027b7829b46a | 178 | if (activated && accel) alarmServicePtr->updateAlarmState(1); |
fjaviercifuentes | 0:027b7829b46a | 179 | } |
fjaviercifuentes | 0:027b7829b46a | 180 | } |
fjaviercifuentes | 0:027b7829b46a | 181 | else |
fjaviercifuentes | 0:027b7829b46a | 182 | { |
fjaviercifuentes | 0:027b7829b46a | 183 | aux_lipochargerState = 0; |
fjaviercifuentes | 0:027b7829b46a | 184 | if (pass_lipochargerState == 1) internalValuesServicePtr->updateDischargeProgramCyclesCharacteristic(); |
fjaviercifuentes | 0:027b7829b46a | 185 | } |
fjaviercifuentes | 0:027b7829b46a | 186 | |
fjaviercifuentes | 0:027b7829b46a | 187 | if(!batteryLevelCalibration && aux_lipochargerState == 1) |
fjaviercifuentes | 0:027b7829b46a | 188 | { |
fjaviercifuentes | 0:027b7829b46a | 189 | batteryLevelConstant *= 100.0f/batteryLevel; |
fjaviercifuentes | 0:027b7829b46a | 190 | batteryLevelCalibration = true; |
fjaviercifuentes | 0:027b7829b46a | 191 | } |
fjaviercifuentes | 0:027b7829b46a | 192 | |
fjaviercifuentes | 0:027b7829b46a | 193 | internalValuesServicePtr->updateLipoChargerState(aux_lipochargerState); |
fjaviercifuentes | 0:027b7829b46a | 194 | } |
fjaviercifuentes | 0:027b7829b46a | 195 | |
fjaviercifuentes | 0:027b7829b46a | 196 | if (internalValuesServicePtr->getLipoChargerState() == 0) internalValuesServicePtr->incrementChargeProgramCycles(); |
fjaviercifuentes | 0:027b7829b46a | 197 | else if (internalValuesServicePtr->getLipoChargerState() == 1) internalValuesServicePtr->incrementDischargeProgramCycles(); |
fjaviercifuentes | 0:027b7829b46a | 198 | |
fjaviercifuentes | 0:027b7829b46a | 199 | /* Update contact state */ |
fjaviercifuentes | 0:027b7829b46a | 200 | if (selectedAnalogIn == 2) |
fjaviercifuentes | 0:027b7829b46a | 201 | { |
fjaviercifuentes | 0:027b7829b46a | 202 | contactState = contact.read(); |
fjaviercifuentes | 0:027b7829b46a | 203 | uint8_t aux_contactState; |
fjaviercifuentes | 0:027b7829b46a | 204 | |
fjaviercifuentes | 0:027b7829b46a | 205 | if (contactState > contactStateThreshold) |
fjaviercifuentes | 0:027b7829b46a | 206 | { |
fjaviercifuentes | 0:027b7829b46a | 207 | aux_contactState = 1; |
fjaviercifuentes | 0:027b7829b46a | 208 | |
fjaviercifuentes | 0:027b7829b46a | 209 | if (!authenticated && activated) |
fjaviercifuentes | 0:027b7829b46a | 210 | relayServicePtr->activate(); |
fjaviercifuentes | 0:027b7829b46a | 211 | } |
fjaviercifuentes | 0:027b7829b46a | 212 | else |
fjaviercifuentes | 0:027b7829b46a | 213 | aux_contactState = 0; |
fjaviercifuentes | 0:027b7829b46a | 214 | |
fjaviercifuentes | 0:027b7829b46a | 215 | internalValuesServicePtr->updateContactState(aux_contactState); |
fjaviercifuentes | 0:027b7829b46a | 216 | } |
fjaviercifuentes | 0:027b7829b46a | 217 | |
fjaviercifuentes | 0:027b7829b46a | 218 | selectedAnalogIn++; |
fjaviercifuentes | 0:027b7829b46a | 219 | |
fjaviercifuentes | 0:027b7829b46a | 220 | if (selectedAnalogIn == ANALOGIN) selectedAnalogIn = 0; |
fjaviercifuentes | 0:027b7829b46a | 221 | |
fjaviercifuentes | 0:027b7829b46a | 222 | if (!authenticated && userIsConnected) |
fjaviercifuentes | 0:027b7829b46a | 223 | { |
fjaviercifuentes | 0:027b7829b46a | 224 | if (forceDisconnectionCounter > DISCONNECTION_TIME) |
fjaviercifuentes | 0:027b7829b46a | 225 | { |
fjaviercifuentes | 0:027b7829b46a | 226 | forceDisconnectionCounter = 0; |
fjaviercifuentes | 0:027b7829b46a | 227 | Gap::DisconnectionReason_t res=Gap::LOCAL_HOST_TERMINATED_CONNECTION; |
fjaviercifuentes | 0:027b7829b46a | 228 | ble.disconnect(res); |
fjaviercifuentes | 0:027b7829b46a | 229 | } |
fjaviercifuentes | 0:027b7829b46a | 230 | else |
fjaviercifuentes | 0:027b7829b46a | 231 | forceDisconnectionCounter++; |
fjaviercifuentes | 0:027b7829b46a | 232 | } |
fjaviercifuentes | 0:027b7829b46a | 233 | else |
fjaviercifuentes | 0:027b7829b46a | 234 | forceDisconnectionCounter = 0; |
fjaviercifuentes | 0:027b7829b46a | 235 | |
fjaviercifuentes | 0:027b7829b46a | 236 | if ( !initial_activation && !userIsConnected) |
fjaviercifuentes | 0:027b7829b46a | 237 | if (forceActivationCounter > AUTHENTICATION_TIME) |
fjaviercifuentes | 0:027b7829b46a | 238 | { |
fjaviercifuentes | 0:027b7829b46a | 239 | imobStateServicePtr->updateActivationValue(1); |
fjaviercifuentes | 0:027b7829b46a | 240 | initial_activation = true; |
fjaviercifuentes | 0:027b7829b46a | 241 | } |
fjaviercifuentes | 0:027b7829b46a | 242 | else |
fjaviercifuentes | 0:027b7829b46a | 243 | forceActivationCounter++; |
fjaviercifuentes | 0:027b7829b46a | 244 | |
fjaviercifuentes | 0:027b7829b46a | 245 | |
fjaviercifuentes | 0:027b7829b46a | 246 | } |
fjaviercifuentes | 0:027b7829b46a | 247 | } |