Adaptation of SMPIR for the Window Sensor Module of the Agile-IoT project.
Dependencies: BLE_API mbed nRF51822
Fork of SensorModulePIR by
main.cpp
- Committer:
- MisterGiet
- Date:
- 2017-07-07
- Revision:
- 13:0dc9a52cff66
- Parent:
- 12:92f008fe602c
- Child:
- 14:5a1467f7cfb2
File content as of revision 13:0dc9a52cff66:
#include "mbed.h" #include "defineGPIOs.h" #include "BLE.h" #include "HealthThermometerService.h" #include "BatteryService.h" #include "EnvironmentalService.h" #include "HumidityMeasureService.h" #include "PresenceDetectionService.h" #include "ble_gatt.h" #include "Si7020.h" #include "UARTService.h" #include <string.h> //#include "DFUService.h" // OFFSET TEMPERATURE CONFIGURATIONS: #define STANDARD -1 // Squared radar sensor module: -1ºC #define ZERO 0 // no offset #define OFFSET STANDARD #define NEED_SERIAL_CONSOLE_OUTPUT 1 #if NEED_SERIAL_CONSOLE_OUTPUT Serial pc(PIN_TX, PIN_RX); #define SERIAL_DEBUG(...) { printf(__VA_ARGS__); } //Defaults to stdio without having to wirte pcUart explicitly #else #define SERIAL_DEBUG(...) /* nothing */ #endif #define NEED_BLE_OUTPUT 1 // Set this if you need debug messages on the console; #if NEED_BLE_OUTPUT #define DEBUG(STR) { if (uart) uart->write(STR, strlen(STR)); } #else #define DEBUG(...) /* nothing */ #endif /* #if NEED_CONSOLE_OUTPUT */ I2C i2c(PIN_SDA, PIN_SCL); Si7020 tempsensor(&i2c); InterruptIn motion_pin(PIN_PRESENCE_RIGHT); DigitalIn pinR(PIN_PRESENCE_RIGHT, PullNone); DigitalOut ledB(PIN_BLED_PCB, 1); DigitalOut ledR(PIN_RLED_PCB, 1); bool presenceState = false; int presenceCounter = 0; //uint8_t presenceCounterBLE = 0; bool installMode = 0; bool battNotify = 1; static volatile bool triggerPresencePolling = false; /* BLE CONFIGURATION */ BLE ble; static const char DEVICE_NAME[] = "SM00"; static const uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE}; static volatile bool triggerSensorPolling = false; static char fwversion[31] = "APP-2217"; static uint8_t batteryLevel = 99; static int8_t TxPower = +4; //static uint8_t humidity = 99; static uint8_t ManufData[] = {0x01,0x02,0x03,0x04,0x05}; // Set up to 26B of advertising data to use for the Manufacturer data. //const static uint8_t ManufData[] = {0x01,0x02,0x03,0x04,0x05}; // Set up to 26B of advertising data to use for the Manufacturer data. static HealthThermometerService *thermometerServicePtr = NULL;; static EnvironmentalService* humidityTemperatureServicePtr = NULL; static HumidityMeasureService *humidityService = NULL; static PresenceDetectionService *presenceService = NULL; static BatteryService* batteryServicePtr = NULL;; UARTService *uart; // Firmware GattCharacteristic fwChars(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR, (uint8_t *)fwversion, sizeof(fwversion), sizeof(fwversion),GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); GattCharacteristic *firmwareChars[] = {&fwChars }; GattService firmwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, firmwareChars, sizeof(firmwareChars) / sizeof(GattCharacteristic *)); //Power GattCharacteristic TxPowerChar(GattCharacteristic::UUID_TX_POWER_LEVEL_CHAR, (uint8_t*)&TxPower, sizeof(TxPower), sizeof(TxPower), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); GattCharacteristic *charTable[] = {&TxPowerChar}; GattService TxPowerService(GattService::UUID_TX_POWER_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); /* BATTERY MEASUREMENT */ void my_analogin_init(void) { NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled; NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) | (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) | (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) | (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); } uint16_t my_analogin_read_u16(void) { NRF_ADC->CONFIG &= ~ADC_CONFIG_PSEL_Msk; NRF_ADC->CONFIG |= ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos; NRF_ADC->TASKS_START = 1; while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {}; return (uint16_t)NRF_ADC->RESULT; // 10 bit } float getBatteryVolt (void) { float Vadc = (float)my_analogin_read_u16(); float Vref = 1.2; // Internal Vref float Vcc = 3 * 4 * Vref * Vadc / 1024.0; // Debugging: char message[10]; // 1B per Ascii character sprintf (message, "VCC=%.2f;", Vcc); DEBUG(message); SERIAL_DEBUG(message); return Vcc; } int getBatteryPercent () { float Vbat_min = 2; //2; float Vbat_max = 3; int battLevel = (int) ( ((getBatteryVolt()-Vbat_min) / (Vbat_max-Vbat_min)) *100); // To avoid values bigger than 100% if (battLevel > 100) { battLevel = 100; } // To avoid overflow due to a value lower than Vbat_min if (battLevel >= 250) { battLevel = 0; } // Debugging: char message[10]; // 1B per Ascii character sprintf (message, "BAT=%i;", battLevel); DEBUG(message); SERIAL_DEBUG(message); return battLevel; } void blinkLed (bool enable, int color) { if (enable) { if (color == 1) { ledB=0; wait(0.2); ledB=1; wait(0.2); } if (color == 2) { ledR=0; wait(0.2); ledR=1; wait(0.2); } } else { // do nothing if enable=0 } } uint8_t updatePresenceCounter (int counts) { uint8_t uint8_counter; if (counts>=255) { uint8_counter = 255; } else { uint8_counter = uint8_t(counts); } // Debugging: char message[10]; // 1B per Ascii character sprintf (message, "PRES=%i;", uint8_counter); DEBUG(message); SERIAL_DEBUG(message); return uint8_counter; } float getHumidity(void) { float hum; if(tempsensor.getHumidity(&hum) != 0) { SERIAL_DEBUG("Error getting humidity"); hum = -1; } // Debugging: char message[10]; // 1B per Ascii character //sprintf (message, "HUM=%.2f;", hum); sprintf (message, "HUM=%i;",(uint16_t)hum); SERIAL_DEBUG(message); DEBUG(message); return hum; } float getTemperature(void) { float temp; if(tempsensor.getTemperature(&temp) != 0) { DEBUG("Error getting temperature"); temp = -1; } // Adding offset: temp = temp + OFFSET; // Debugging: char msg[11]; // 1B per Ascii character char msg2[10]; sprintf (msg, "\nTEM=%.2f;", temp); sprintf (msg2, "OFFSET=%i;",OFFSET); SERIAL_DEBUG(msg); DEBUG(msg); SERIAL_DEBUG(msg2); DEBUG(msg2); return temp; } void updateManufData () { float temp = getTemperature(); float hum = getHumidity(); ManufData [1]= (uint8_t) temp; ManufData [2]= (uint8_t) ((temp -((uint8_t)temp))*100); ManufData [3]= (uint8_t) hum; ManufData [4]= updatePresenceCounter(presenceCounter); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ManufData, sizeof(ManufData)); // Debugging: char message1[10]; // 1B per Ascii character char message2[10]; // 1B per Ascii character char message3[10]; // 1B per Ascii character char message4[10]; // 1B per Ascii character sprintf (message1, "MD1=%i;", ManufData [1]); sprintf (message2, "MD2=%i;", ManufData [2]); sprintf (message3, "MD3=%i;", ManufData [3]); sprintf (message4, "MD4=%i;", ManufData [4]); SERIAL_DEBUG(message1); SERIAL_DEBUG(message2); SERIAL_DEBUG(message3); SERIAL_DEBUG(message4); DEBUG(message1); DEBUG(message2); DEBUG(message3); DEBUG(message4); } /* Restart Advertising on disconnection*/ void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { SERIAL_DEBUG("\nDISCONNECTED\n"); BLE::Instance().gap().startAdvertising(); } void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { SERIAL_DEBUG("\nCONNECTED\n"); } /** * This function is called when the ble initialization process has failed */ void onBleInitError(BLE &ble, ble_error_t error) { /* Avoid compiler warnings */ (void) ble; (void) error; /* Initialization error handling should go here */ } void onDataWrittenCallback(const GattWriteCallbackParams *params) { int var = params->data[0]; if (var == 1) { blinkLed(installMode,1); SERIAL_DEBUG("BLE. Resetting presence\n"); presenceCounter = 0; //presenceCounterBLE = 0; triggerSensorPolling = true; // force update of all BLE services } if (var == 2) { blinkLed(1,1); blinkLed(1,1); SERIAL_DEBUG("BLE. All LEDs ON/OFF\n"); installMode = !installMode; } if (params->data[0] == 3) { blinkLed(1,1); blinkLed(1,1); blinkLed(1,1); SERIAL_DEBUG("BLE. Rebooting sensor\n"); wait(3); NVIC_SystemReset(); // SW Reset } if (params->data[0] == 4) { blinkLed(1,1); blinkLed(1,1); blinkLed(1,1); blinkLed(1,1); SERIAL_DEBUG("BLE. Rebooting sensor\n"); /* Enable over-the-air firmware updates. Instantiating DFUSservice introduces a * control characteristic which can be used to trigger the application to * handover control to a resident bootloader. */ //DFUService dfu(ble); } } /** * Callback triggered when the ble initialization process has finished */ void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { SERIAL_DEBUG("BLE.Init \n"); BLE& ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { /* In case of error, forward the error handling to onBleInitError */ onBleInitError(ble, error); return; } /* Ensure that it is the default instance of BLE */ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } ble.gap().onConnection(connectionCallback); ble.gap().onDisconnection(disconnectionCallback); // Set Transmission power: ble.setTxPower(TxPower); //ble.gap().setScanParams(500, 400); //ble.gap().startScan(advertisementCallback); //BLE server setup ble.gattServer().onDataWritten(onDataWrittenCallback); //Setup primary services presenceService = new PresenceDetectionService(ble, updatePresenceCounter(presenceCounter)); thermometerServicePtr = new HealthThermometerService(ble, getTemperature(), HealthThermometerService::LOCATION_EAR); humidityService = new HumidityMeasureService(ble, getHumidity()); humidityTemperatureServicePtr = new EnvironmentalService (ble); batteryServicePtr = new BatteryService(ble, batteryLevel); ble.addService(firmwareService); uart = new UARTService(ble); //ble.addService(TxPowerService); /* setup advertising */ /* Sacrifice 3B of 31B to Advertising Flags */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); /* Sacrifice 2B of 31B to AdvType overhead, rest goes to AdvData array you define */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ManufData, sizeof(ManufData)); ble.gap().accumulateAdvertisingPayloadTxPower(TxPower); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER); //ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,(const uint8_t *)"BLE UART", sizeof("BLE UART") - 1); //ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); ble.setAdvertisingInterval(1000); /* 1000ms */ ble.startAdvertising(); } void periodicCallbackPresence(void) { triggerPresencePolling = true; presenceState = true; } void periodicCallbackSensor (void) { triggerSensorPolling = true; } void updateBLEservices () { thermometerServicePtr->updateTemperature(getTemperature()); humidityService->updateHumidity(getHumidity()); humidityTemperatureServicePtr->updateTemperature (getTemperature()); humidityTemperatureServicePtr->updateHumidity (getHumidity()); batteryServicePtr->updateBatteryLevel(getBatteryPercent()); presenceService->updatePresence(updatePresenceCounter(presenceCounter)); // updateuart ? } int main(void) { SERIAL_DEBUG("\nSTART\n"); DEBUG("\nSTART\n"); char pres_message[20]; //Serial pc(PIN_TX, PIN_RX); //pc.printf ("PIPPO\n"); blinkLed(1,1); //Ticker ticker_presence; //ticker_presence.attach(periodicCallbackPresence, 0.5); motion_pin.fall(&periodicCallbackPresence); Ticker ticker_sensor; ticker_sensor.attach(periodicCallbackSensor, 3); // 5 min //BLE instance setup BLE &bleptr = BLE::Instance(); bleptr.init(bleInitComplete); /* //SpinWait for initialization to complete. This is necessary because the //BLE object is used in the main loop below. while (ble.hasInitialized() == false) { } */ while (true) { /* Get Presence data: */ if(triggerPresencePolling) { triggerPresencePolling = false; // if presence is detected: if (presenceState) { presenceCounter++; // Update all BLE services for every presence detected: updateBLEservices(); // Debugging: blinkLed(installMode,1); SERIAL_DEBUG("Presence counter: %i\n", presenceCounter); sprintf (pres_message, "Pres=%i\n", presenceCounter); DEBUG(pres_message); presenceState=0; } // if no presence: else { SERIAL_DEBUG("."); } } updateManufData (); // update advertising values /* Update BLE services if connected: */ if (triggerSensorPolling && ble.getGapState().connected) { // Quanto consuma quando sta leggendo la temperatura? triggerSensorPolling = false; updateBLEservices(); /* // Red LED blinks if low battery, at every connection if (batteryLevel <= 10) { blinkLed(battNotify,2); } */ } else { ble.waitForEvent(); } //SERIAL_DEBUG("\n"); //DEBUG("\n"); } }