imob

Dependencies:   mbedtls mbed BLE_API nRF51822 AccelSensor

Committer:
osilvam
Date:
Tue Mar 20 14:31:59 2018 +0000
Revision:
0:5284859bb3e8
Child:
1:471d502617fe
imob

Who changed what in which revision?

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