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
Fork of SensorModulePIR by
main.cpp
00001 #include "mbed.h" 00002 #include "defineGPIOs.h" 00003 #include "BLE.h" 00004 #include "ble/services/HealthThermometerService.h" 00005 #include "ble/services/BatteryService.h" 00006 #include "ble/services/EnvironmentalService.h" 00007 #include "HumidityMeasureService.h" 00008 #include "PresenceDetectionService.h" 00009 #include "ble_gatt.h" 00010 #include "Si7020.h" 00011 #include "UARTService.h" 00012 #include <string.h> 00013 00014 00015 00016 // OFFSET TEMPERATURE CONFIGURATIONS: 00017 #define STANDARD -1 // Squared radar sensor module: -1ºC 00018 #define ZERO 0 // no offset 00019 #define OFFSET STANDARD 00020 00021 #define NEED_SERIAL_CONSOLE_OUTPUT 0 00022 #if NEED_SERIAL_CONSOLE_OUTPUT 00023 Serial pc(PIN_TX, PIN_RX); 00024 #define SERIAL_DEBUG(...) { printf(__VA_ARGS__); } //Defaults to stdio without having to wirte pcUart explicitly 00025 #else 00026 #define SERIAL_DEBUG(...) /* nothing */ 00027 #endif 00028 00029 #define NEED_BLE_OUTPUT 1 // Set this if you need debug messages on the console; 00030 #if NEED_BLE_OUTPUT 00031 #define DEBUG(STR) { if (uart) uart->write(STR, strlen(STR)); } 00032 #else 00033 #define DEBUG(...) /* nothing */ 00034 #endif /* #if NEED_CONSOLE_OUTPUT */ 00035 00036 I2C i2c(PIN_SDA, PIN_SCL); 00037 Si7020 tempsensor(&i2c); 00038 00039 InterruptIn motion_pin(PIN_PRESENCE_RIGHT); 00040 DigitalIn pinR(PIN_PRESENCE_RIGHT, PullNone); 00041 DigitalOut ledB(PIN_BLED_PCB, 1); 00042 DigitalOut ledR(PIN_RLED_PCB, 1); 00043 00044 bool presenceState = false; 00045 int presenceCounter = 0; 00046 //uint8_t presenceCounterBLE = 0; 00047 bool installMode = 0; 00048 bool battNotify = 1; 00049 static volatile bool triggerPresencePolling = false; 00050 00051 00052 /* BLE CONFIGURATION */ 00053 00054 BLE ble; 00055 static const char DEVICE_NAME[] = "WindowSensorUnit"; 00056 static const uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE}; 00057 static volatile bool triggerSensorPolling = false; 00058 static char fwversion[31] = "Agile-IoT"; 00059 static uint8_t batteryLevel = 99; 00060 static int8_t TxPower = +4; 00061 //static uint8_t humidity = 99; 00062 const static uint8_t ManufData[] = {0x01,0x02,0x03,0x04,0x05}; // Set up to 26B of advertising data to use for the Manufacturer data. 00063 00064 00065 //static HealthThermometerService *thermometerServicePtr = NULL;; 00066 static BatteryService* batteryServicePtr = NULL;; 00067 //static EnvironmentalService* humidityTemperatureServicePtr = NULL; 00068 UARTService *uart; 00069 00070 // Firmware 00071 GattCharacteristic fwChars(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR, (uint8_t *)fwversion, sizeof(fwversion), sizeof(fwversion),GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); 00072 GattCharacteristic *firmwareChars[] = {&fwChars }; 00073 GattService firmwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, firmwareChars, sizeof(firmwareChars) / sizeof(GattCharacteristic *)); 00074 00075 //Power 00076 GattCharacteristic TxPowerChar(GattCharacteristic::UUID_TX_POWER_LEVEL_CHAR, (uint8_t*)&TxPower, sizeof(TxPower), sizeof(TxPower), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); 00077 GattCharacteristic *charTable[] = {&TxPowerChar}; 00078 GattService TxPowerService(GattService::UUID_TX_POWER_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00079 00080 /* BATTERY MEASUREMENT */ 00081 void my_analogin_init(void) 00082 { 00083 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled; 00084 NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | 00085 (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) | 00086 (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) | 00087 (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) | 00088 (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); 00089 } 00090 00091 uint16_t my_analogin_read_u16(void) 00092 { 00093 NRF_ADC->CONFIG &= ~ADC_CONFIG_PSEL_Msk; 00094 NRF_ADC->CONFIG |= ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos; 00095 NRF_ADC->TASKS_START = 1; 00096 while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {}; 00097 return (uint16_t)NRF_ADC->RESULT; // 10 bit 00098 } 00099 00100 float getBatteryVolt (void) 00101 { 00102 char Vpower[10]; 00103 00104 float Vadc = (float)my_analogin_read_u16(); 00105 float Vref = 1.2; // Internal Vref 00106 float Vcc = 0.62 * Vref * Vadc / 1024.0;; //3 * 4 * Vref * Vadc / 1024.0; 00107 00108 sprintf (Vpower, "Vcc=%.2fV, ", Vcc); 00109 DEBUG(Vpower); 00110 return Vcc; 00111 } 00112 00113 int getBatteryPercent () 00114 { 00115 char batt_mess[10]; 00116 float Vbat_min = 3; //2; 00117 float Vbat_max = 3.7; 00118 int battLevel = (int) ( ((getBatteryVolt()-Vbat_min) / (Vbat_max-Vbat_min)) *100); 00119 00120 sprintf (batt_mess, "Vbatt=%i, ", battLevel); 00121 DEBUG(batt_mess); 00122 00123 return battLevel; 00124 } 00125 00126 void blinkLed (bool enable, int color) 00127 { 00128 if (enable) { 00129 if (color == 1) { 00130 ledB=0; 00131 wait(0.2); 00132 ledB=1; 00133 wait(0.2); 00134 } 00135 if (color == 2) { 00136 ledR=0; 00137 wait(0.2); 00138 ledR=1; 00139 wait(0.2); 00140 } 00141 } else { 00142 // do nothing if enable=0 00143 } 00144 } 00145 00146 uint8_t updatePresenceCounter (int counts) 00147 { 00148 uint8_t uint8_counter; 00149 00150 if (counts>=255) { 00151 uint8_counter = 255; 00152 00153 } else { 00154 uint8_counter = uint8_t(counts); 00155 } 00156 00157 return uint8_counter; 00158 } 00159 00160 float getHumidity(void) 00161 { 00162 float hum; 00163 if(tempsensor.getHumidity(&hum) != 0) { 00164 SERIAL_DEBUG("Error getting humidity"); 00165 hum = -1; 00166 } 00167 00168 // Debugging: 00169 SERIAL_DEBUG("\nHumidity = %f", hum); 00170 char message[50]; 00171 sprintf (message, "RH=%.2f %i\n", hum, (uint16_t)hum); 00172 DEBUG(message); 00173 00174 //return uint8_t(hum); 00175 //return uint16_t(hum); 00176 return hum; 00177 } 00178 00179 float getTemperature(void) 00180 { 00181 float temp; 00182 00183 if(tempsensor.getTemperature(&temp) != 0) { 00184 DEBUG("Error getting temperature"); 00185 temp = -1; 00186 } 00187 00188 // Debugging: 00189 SERIAL_DEBUG("\nTemperature = %.2f", temp); 00190 char message[50]; 00191 sprintf (message, "T=%.2fC\n", temp); 00192 DEBUG(message); 00193 00194 // Adding offset: 00195 temp = temp + OFFSET; 00196 00197 return temp; 00198 } 00199 00200 /* Restart Advertising on disconnection*/ 00201 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) 00202 { 00203 SERIAL_DEBUG("Disconnected\r\n"); 00204 BLE::Instance().gap().startAdvertising(); 00205 } 00206 00207 /** 00208 * This function is called when the ble initialization process has failed 00209 */ 00210 void onBleInitError(BLE &ble, ble_error_t error) 00211 { 00212 /* Avoid compiler warnings */ 00213 (void) ble; 00214 (void) error; 00215 /* Initialization error handling should go here */ 00216 } 00217 00218 void onDataWrittenCallback(const GattWriteCallbackParams *params) 00219 { 00220 int var = params->data[0]; 00221 00222 if (var == 1) { 00223 blinkLed(installMode,1); 00224 SERIAL_DEBUG("BLE. Resetting presence\n"); 00225 presenceCounter = 0; 00226 //presenceCounterBLE = 0; 00227 triggerSensorPolling = true; // force update of all BLE services 00228 } 00229 00230 if (var == 2) { 00231 blinkLed(1,1); 00232 blinkLed(1,1); 00233 SERIAL_DEBUG("BLE. All LEDs ON/OFF\n"); 00234 installMode = !installMode; 00235 } 00236 00237 if (params->data[0] == 3) { 00238 blinkLed(1,1); 00239 blinkLed(1,1); 00240 blinkLed(1,1); 00241 SERIAL_DEBUG("BLE. Rebooting sensor\n"); 00242 wait(3); 00243 NVIC_SystemReset(); // SW Reset 00244 } 00245 } 00246 00247 /** 00248 * Callback triggered when the ble initialization process has finished 00249 */ 00250 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00251 { 00252 SERIAL_DEBUG("BLE. Init \n"); 00253 00254 BLE& ble = params->ble; 00255 ble_error_t error = params->error; 00256 00257 if (error != BLE_ERROR_NONE) { 00258 /* In case of error, forward the error handling to onBleInitError */ 00259 onBleInitError(ble, error); 00260 return; 00261 } 00262 00263 /* Ensure that it is the default instance of BLE */ 00264 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00265 return; 00266 } 00267 00268 //ble.gap().onConnection(connectionCallback); 00269 ble.gap().onDisconnection(disconnectionCallback); 00270 00271 // Set Transmission power: 00272 ble.setTxPower(TxPower); 00273 00274 //BLE server setup 00275 ble.gattServer().onDataWritten(onDataWrittenCallback); 00276 00277 //Setup primary services 00278 batteryServicePtr = new BatteryService(ble, batteryLevel); 00279 00280 //humidityTemperatureServicePtr = new EnvironmentalService (ble); 00281 00282 ble.addService(firmwareService); 00283 //ble.addService(TxPowerService); 00284 00285 /* setup advertising */ 00286 00287 /* Sacrifice 3B of 31B to Advertising Flags */ 00288 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00289 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00290 00291 /* Sacrifice 2B of 31B to AdvType overhead, rest goes to AdvData array you define */ 00292 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00293 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); 00294 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER); 00295 00296 ble.setAdvertisingInterval(1000); /* 1000ms */ 00297 ble.startAdvertising(); 00298 } 00299 00300 void periodicCallbackPresence(void) 00301 { 00302 triggerPresencePolling = true; 00303 presenceState = true; 00304 } 00305 00306 void periodicCallbackSensor (void) 00307 { 00308 triggerSensorPolling = true; 00309 } 00310 00311 void updateBLEservices () 00312 { 00313 //humidityTemperatureServicePtr->updateTemperature (getTemperature()); 00314 //humidityTemperatureServicePtr->updateHumidity (getHumidity()); 00315 00316 batteryServicePtr->updateBatteryLevel(getBatteryPercent()); 00317 00318 } 00319 00320 int main(void) 00321 { 00322 SERIAL_DEBUG("Start \n"); 00323 char pres_message[20]; 00324 00325 blinkLed(1,1); 00326 00327 motion_pin.fall(&periodicCallbackPresence); 00328 00329 Ticker ticker_sensor; 00330 ticker_sensor.attach(periodicCallbackSensor, 3); // 5 min 00331 00332 //BLE instance setup 00333 BLE &bleptr = BLE::Instance(); 00334 bleptr.init(bleInitComplete); 00335 00336 while (true) { 00337 00338 /* Get Presence data: */ 00339 if(triggerPresencePolling) { 00340 triggerPresencePolling = false; 00341 00342 // if presence is detected: 00343 if (presenceState) { 00344 00345 presenceCounter++; 00346 00347 // Update all BLE services for every presence detected: 00348 updateBLEservices(); 00349 00350 // Debugging: 00351 blinkLed(installMode,1); 00352 SERIAL_DEBUG("Presence counter: %i\n", presenceCounter); 00353 sprintf (pres_message, "Pres=%i\n", presenceCounter); 00354 DEBUG(pres_message); 00355 00356 presenceState=0; 00357 } 00358 00359 // if no presence: 00360 else { 00361 SERIAL_DEBUG("."); 00362 } 00363 } 00364 00365 /* Update BLE services if connected: */ 00366 if (triggerSensorPolling && ble.getGapState().connected) { 00367 00368 // Quanto consuma quando sta leggendo la temperatura? 00369 triggerSensorPolling = false; 00370 00371 updateBLEservices(); 00372 00373 /* 00374 // Red LED blinks if low battery, at every connection 00375 if (batteryLevel <= 10) { 00376 blinkLed(battNotify,2); 00377 } 00378 */ 00379 00380 } else { 00381 ble.waitForEvent(); 00382 } 00383 } 00384 }
Generated on Wed Jul 20 2022 20:14:52 by
1.7.2
