Dependencies:   AccelSensor BLE_API mbed nRF51822

Committer:
fjaviercifuentes
Date:
Fri Jan 19 02:38:38 2018 +0000
Revision:
0:027b7829b46a

        

Who changed what in which revision?

UserRevisionLine numberNew 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 }