Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed nRF51822 MPU6050_lib
main.cpp
00001 /** Includes */ 00002 00003 #include "common.h" 00004 #include "mbed.h" 00005 #include "BLE.h" 00006 #include "MPU6050Service.h" 00007 #include "PowerService.h" 00008 #include "services/DeviceInformationService.h" 00009 00010 /** Constants */ 00011 00012 static const char deviceName[] = "nano bear"; 00013 static const char deviceManufacturers[] = "???"; 00014 static const char deviceModelNumber[] = ""; 00015 static const char deviceSerialNumber[] = XSTRING_(MBED_BUILD_TIMESTAMP); 00016 static const char deviceHardwareRev[] = "0.1"; 00017 static const char deviceFirmwareRev[] = "0.1"; 00018 static const char deviceSoftwareRev[] = ""; 00019 00020 static const uint16_t minimumConnectionInterval = Gap::MSEC_TO_GAP_DURATION_UNITS(20); // 20ms 00021 static const uint16_t maximumConnectionInterval = Gap::MSEC_TO_GAP_DURATION_UNITS(40); // 40ms; 00022 static const uint16_t slaveLatency = 0; 00023 00024 static const float ledTimeout = 0.05f; 00025 static const float batteryCritBlinkSequ[] = { 0.000f, 0.146f, 0.500f, 0.854f, 1.000f, 0.854f, 0.500f, 0.146f }; 00026 static const float connectedBlinkSequ[] = { 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 00027 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 00028 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 00029 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 00030 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 00031 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 1.000f, 00032 1.000f, 0.962f, 0.854f, 0.691f, 0.500f, 0.309f, 0.146f, 0.038f, 00033 0.000f, 0.038f, 0.146f, 0.309f, 0.500f, 0.691f, 0.854f, 0.962f }; 00034 static const float disconnectedBlinkSequ[] = { 0.000f, 0.038f, 0.146f, 0.309f, 0.500f, 0.691f, 0.854f, 0.962f, 00035 1.000f, 0.962f, 0.854f, 0.691f, 0.500f, 0.309f, 0.146f, 0.038f, 00036 0.000f, 0.038f, 0.146f, 0.309f, 0.500f, 0.691f, 0.854f, 0.962f, 00037 1.000f, 0.962f, 0.854f, 0.691f, 0.500f, 0.309f, 0.146f, 0.038f, 00038 0.000f, 0.038f, 0.146f, 0.309f, 0.500f, 0.691f, 0.854f, 0.962f, 00039 1.000f, 0.962f, 0.854f, 0.691f, 0.500f, 0.309f, 0.146f, 0.038f, 00040 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 00041 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 00042 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f }; 00043 00044 /** Power determination stuff: 00045 * 00046 * The following is the schematic circuit ... 00047 * 00048 * I0-> ____ 00049 * --------*-|____|-*----------- ... where ... 00050 * | | R3 | | 00051 * | | | _____|_____ | 00052 * | | | | | | | | | ____ 00053 * | R1 | | R4 | | | BLE nano | | | and -|____|- are resistors ... 00054 * | |_| |_| | |--... |_| 00055 * | |~0-> | | | | 00056 * | Uref1 *--------|----| P0_4 |--... 00057 * + __|__ | |~0->| | ... and ... 00058 * U0 ___ | Uref2 *----| P0_5 |--... 00059 * | | | | | + __|__ 00060 * | | | | | | |--... ___ is the constant voltage source 00061 * | R2 | | R5 | | | | | (a battery in this case) 00062 * | |_| |_| |___________| 00063 * | | | | 00064 * | | | | 00065 * *-------*--------*----------*--------... 00066 * _|_ 00067 * 00068 * 00069 * Therefore the input values are 00070 * 00071 * U0 = (R1 / R2 + 1) * Uref1 00072 * 00073 * I0 = ((R1 + R3) / R2 + 1) / R3 * Uref1 - (R4 / R5 + 1) / R3 * Uref2 00074 * 00075 */ 00076 00077 #define R1 1000.0f 00078 #define R2 1000.0f 00079 #define R3 10.0f 00080 #define R4 1000.0f 00081 #define R5 1000.0f 00082 #define NANO_OP_VOLT 3.3f 00083 00084 static const float powerAccumulationTimeout = 0.005f; 00085 00086 static const float voltFac = ((R1 / R2) + 1.0f) * NANO_OP_VOLT; 00087 static const float currFac1 = ((((R1 + R3) / R2) + 1.0f) / R3) * NANO_OP_VOLT; 00088 static const float currFac2 = (((R4 / R5) + 1.0f) / R3) * NANO_OP_VOLT; 00089 00090 static const float powerServiceUpdateTimeout = 0.1f; 00091 00092 00093 00094 /** Global variables */ 00095 00096 BLE ble; 00097 Gap::ConnectionParams_t fast; 00098 00099 MPU6050 mpu(I2C_SDA0, I2C_SCL0, MPU6050::ADDRESS_0); 00100 00101 PwmOut btLed(P0_28); 00102 PwmOut pwrLed(P0_29); 00103 DigitalOut aliveLed(LED); 00104 00105 AnalogIn uRef1(P0_4); 00106 AnalogIn uRef2(P0_5); 00107 00108 InterruptIn intIn(P0_9); 00109 00110 Ticker powerAccumulationTicker; 00111 Ticker powerServiceUpdateTicker; 00112 Ticker ledTicker; 00113 00114 00115 00116 /** Callback and handler functions */ 00117 00118 // Accumulate discharge 00119 00120 static float U0 = 0.0f; 00121 static float I0 = 0.0f; 00122 static float Q = 0.0f; 00123 00124 void powerAccumulationPeriodicCallback() 00125 { 00126 // we have to do it in here, since we want a good approximation of the dt-timestep 00127 // since these are simple calculations this won't take much time 00128 00129 register float u1 = uRef1.read(); 00130 00131 U0 = u1 * voltFac; 00132 I0 = (u1 * currFac1) - (uRef2.read() * currFac2); 00133 Q += I0 * powerAccumulationTimeout; 00134 } 00135 00136 00137 00138 // Update the power service characteristics 00139 00140 static bool powerServiceUpdateTrigger = false; 00141 00142 void powerServiceUpdateHandler(PowerService* powerService) 00143 { 00144 powerServiceUpdateTrigger = false; 00145 00146 powerService->updateVoltage(U0); 00147 powerService->updateCurrent(I0 * 1000); // mA 00148 powerService->updateDischarge(Q * 0.277777777f); // mAh 00149 } 00150 00151 void powerServiceUpdatePeriodicCallback() 00152 { 00153 powerServiceUpdateTrigger = true; 00154 } 00155 00156 00157 // Update the bluetooth connection state LED 00158 00159 static bool ledTrigger = false; 00160 static bool batteryCritical = false; 00161 00162 void ledHandler(Gap &gap) 00163 { 00164 ledTrigger = false; 00165 00166 static uint32_t cnt = 0; 00167 static const int batteryCritBlinkSequSize = sizeof(batteryCritBlinkSequ) / sizeof(float); 00168 static const int connectedBlinkSequSize = sizeof(connectedBlinkSequ) / sizeof(float); 00169 static const int disconnectedBlinkSequSize = sizeof(disconnectedBlinkSequ) / sizeof(float); 00170 00171 aliveLed = !aliveLed; 00172 00173 if (gap.getState().connected) 00174 btLed = connectedBlinkSequ[cnt % connectedBlinkSequSize]; 00175 else 00176 btLed = disconnectedBlinkSequ[cnt % disconnectedBlinkSequSize]; 00177 00178 if (batteryCritical) 00179 pwrLed = batteryCritBlinkSequ[cnt % batteryCritBlinkSequSize]; 00180 else 00181 pwrLed = 1; 00182 00183 cnt++; 00184 } 00185 00186 void ledPeriodicCallback() 00187 { 00188 ledTrigger = true; 00189 } 00190 00191 00192 00193 // Connection timeout 00194 00195 static bool timeoutTrigger = false; 00196 00197 void timeoutHandler(Gap &gap, MPU6050Service *mpu) 00198 { 00199 timeoutTrigger = false; 00200 00201 mpu->stop(); 00202 gap.startAdvertising(); 00203 } 00204 00205 void timeoutCallback(Gap::TimeoutSource_t source) 00206 { 00207 timeoutTrigger = true; 00208 } 00209 00210 00211 00212 // Disconnection 00213 00214 static bool disconnectionTrigger = false; 00215 00216 void disconnectionHandler(Gap &gap, MPU6050Service *mpu) 00217 { 00218 disconnectionTrigger = false; 00219 00220 mpu->stop(); 00221 gap.startAdvertising(); 00222 } 00223 00224 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) 00225 { 00226 timeoutTrigger = true; 00227 } 00228 00229 00230 // Connection 00231 00232 static bool connectionTrigger = false; 00233 00234 void connectionHandler(MPU6050Service *mpu6050) 00235 { 00236 connectionTrigger = false; 00237 00238 mpu6050->start(); 00239 } 00240 00241 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) 00242 { 00243 // update the connection parameters with the tuned fast ones 00244 ble.updateConnectionParams(params->handle, &fast); 00245 00246 connectionTrigger = true; 00247 } 00248 00249 00250 00251 /** Main */ 00252 00253 int main() 00254 { 00255 btLed = 1.0f; 00256 pwrLed = 1.0f; 00257 aliveLed = 0; 00258 00259 ble.init(); 00260 00261 Gap &gap = ble.gap(); 00262 00263 powerAccumulationTicker.attach(powerAccumulationPeriodicCallback, powerAccumulationTimeout); 00264 powerServiceUpdateTicker.attach(powerServiceUpdatePeriodicCallback, powerServiceUpdateTimeout); 00265 ledTicker.attach(ledPeriodicCallback, ledTimeout); 00266 00267 gap.onTimeout(timeoutCallback); 00268 gap.onDisconnection(disconnectionCallback); 00269 gap.onConnection(connectionCallback); 00270 00271 gap.setDeviceName((const uint8_t*)deviceName); 00272 00273 gap.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00274 gap.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (const uint8_t*)deviceName, sizeof(deviceName)); 00275 gap.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00276 00277 //TODO: DECISION: advertising at minimal interval may consumes to much power, but is way faster 00278 gap.setAdvertisingInterval(gap.getMinAdvertisingInterval()); 00279 00280 // tune the preferred connection parameters to enable transfer more often 00281 // TODO: DECISION: also waht about power consumption? 00282 gap.getPreferredConnectionParams(&fast); 00283 fast.minConnectionInterval = minimumConnectionInterval; 00284 fast.maxConnectionInterval = maximumConnectionInterval; 00285 fast.slaveLatency = slaveLatency; 00286 gap.setPreferredConnectionParams(&fast); 00287 00288 DeviceInformationService deviceInformation(ble, deviceManufacturers, deviceModelNumber, deviceSerialNumber, deviceHardwareRev, deviceFirmwareRev, deviceSoftwareRev); 00289 PowerService powerService(ble); 00290 MPU6050Service mpu6050(ble, mpu, &intIn); 00291 00292 gap.startAdvertising(); 00293 00294 while (true) 00295 { 00296 // Handle all stuff within the user context 00297 00298 if (powerServiceUpdateTrigger) 00299 powerServiceUpdateHandler(&powerService); 00300 00301 if (ledTrigger) 00302 ledHandler(gap); 00303 00304 if (connectionTrigger) 00305 connectionHandler(&mpu6050); 00306 00307 if (disconnectionTrigger) 00308 disconnectionHandler(gap, &mpu6050); 00309 00310 if (timeoutTrigger) 00311 timeoutHandler(gap, &mpu6050); 00312 00313 ble.waitForEvent(); 00314 00315 mpu6050.handleService(); 00316 } 00317 }
Generated on Sun Jul 24 2022 10:35:29 by
1.7.2