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
Diff: main.cpp
- Revision:
- 3:53db6c57bb61
- Parent:
- 1:839f9cac1eca
- Child:
- 4:de22f0d73c12
diff -r 839f9cac1eca -r 53db6c57bb61 main.cpp
--- a/main.cpp Tue Nov 22 18:19:08 2016 +0000
+++ b/main.cpp Thu May 04 09:58:43 2017 +0000
@@ -1,48 +1,162 @@
#include "mbed.h"
-//#include "HDC1000.h"
+#include "defineGPIOs.h"
#include "BLE.h"
-#include "HealthThermometerService.h"
-//#include "SetTemperatureService.h"
-//#include "SetModeService.h"
-//#include "UARTService.h"
+//#include "HealthThermometerService.h"
+#include "ble/services/HealthThermometerService.h" // added
#include "PresenceDetectionService.h"
-#include "TemperatureMeasureService.h"
-
+//#include "TemperatureMeasureService.h"
+#include "HumidityMeasureService.h"
#include "ble_gatt.h"
#include "Si7020.h"
+#include "UARTService.h"
+#include <string.h>
-Serial pc(p22, p23);
-//Serial pc(USBTX, USBRX);
-//I2C i2c(PIN_SDA,PIN_SCL);
-I2C i2c(p12, p13);
+
+// 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 0
+#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 0 // 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(p11);
-//InterruptIn motion(p8);
-//InterruptIn motion(p23);
+
+InterruptIn motion_pin(PIN_PRESENCE_RIGHT);
+DigitalIn pinR(PIN_PRESENCE_RIGHT, PullNone);
+//DigitalInOut pinR(PIN_PRESENCE_RIGHT); //, PullNone);
+
+DigitalOut ledB(PIN_BLED_PCB, 1);
+DigitalOut ledR(PIN_RLED_PCB, 1);
+
+/* 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
+}
-DigitalOut led(p21, 1);
-//DigitalOut led(LED2, 0);
+float getBatteryVolt (void)
+{
+ char Vpower[10];
+
+ float Vadc = (float)my_analogin_read_u16();
+ float Vref = 1.2; // Internal Vref
+ float Vcc = 3 * 4 * Vref * Vadc / 1024.0;
+
+ sprintf (Vpower, "Vcc=%.2fV, ", Vcc);
+ DEBUG(Vpower);
+ return Vcc;
+}
+
+int getBatteryPercent ()
+{
+ char batt_mess[10];
+ float Vbat_min = 2.3; //2;
+ float Vbat_max = 3;
+ int battLevel = (int) ( ((getBatteryVolt()-Vbat_min) / (Vbat_max-Vbat_min)) *100);
+
+ sprintf (batt_mess, "Vbatt=%i, ", battLevel);
+ DEBUG(batt_mess);
+
+ // To avoid values bigger than 100%
+ if (battLevel > 100) {
+ battLevel = 100;
+ }
+
+ return battLevel;
+}
+
+/* BLE CONFIGURATION */
BLE ble;
+static const char DEVICE_NAME[] = "SM-PIR";
+static const uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE};
+static volatile bool triggerSensorPolling = false;
+static char fwversion[31] = "CAT-1817";
+static uint8_t batteryLevel = 100;
+static int8_t TxPower = +4;
-const static char DEVICE_NAME[] = "SensorModulePIR";
-//static const uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE, SetTemperatureService::SET_TEMPERATURE_SERVICE_UUID};
-static const uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE};
+static HealthThermometerService *thermometerServicePtr;
+PresenceDetectionService *presenceService = NULL;
+HumidityMeasureService *humidityService = NULL;
+UARTService *uart;
+const static uint8_t ManufData[] = {0x01,0x02,0x03,0x04,0x05}; // Set up to 26B of advertising data to use fro the Manufacturer data.
+
+// 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 *));
+
+//Battery
+GattCharacteristic batteryPercentage(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, (uint8_t *)batteryLevel, sizeof(batteryLevel), sizeof(batteryLevel), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+GattCharacteristic *batteryChars[] = {&batteryPercentage};
+GattService batteryService(GattService::UUID_BATTERY_SERVICE, batteryChars, sizeof(batteryChars) / 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 *));
-static volatile bool triggerSensorPolling = false;
-uint8_t presence_now = 0;
-uint8_t presence_before = 0;
-float currentTemperature;
+
+bool presence = false;
+bool presenceL = false;
+uint8_t presence_count = 0;
+bool ledOn = 0;
+static volatile bool triggerPresencePolling = false;
-PresenceDetectionService *presenceService = NULL;
-TemperatureMeasureService *temperatureService = NULL;
+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
+ }
+}
+/* Restart Advertising on disconnection*/
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
- //led = !led;
- pc.printf("Disconnected\r\n");
- ble.gap().startAdvertising();
+ SERIAL_DEBUG("Disconnected\r\n");
+ BLE::Instance().gap().startAdvertising();
}
/**
@@ -50,36 +164,75 @@
*/
void onBleInitError(BLE &ble, ble_error_t error)
{
+ /* Avoid compiler warnings */
+ (void) ble;
+ (void) error;
/* Initialization error handling should go here */
}
+
float getTemperature(void)
{
- /*
- float t = hdc1000.temperature();
- t = t/0x10000*165-40;
- pc.printf("Temperature: %f \n", t);
+ float temp;
- return t;
- */
+ if(tempsensor.getTemperature(&temp) != 0) {
+ DEBUG("Error getting temperature");
+ temp = -1;
+ }
- //float t = 26.8;
- //return t;
+ // Debugging:
+ SERIAL_DEBUG("\nTemperature = %.2f", temp);
+ char message[50];
+ sprintf (message, "T=%.2fC\n", temp);
+ DEBUG(message);
- float temp;
- if(tempsensor.getTemperature(&temp) != 0) {
- //pc.printf("Error getting temperature");
- temp = -1;
- }
- pc.printf("Temperature = %fC\n", temp);
-
- return temp;
+ // Adding offset:
+ temp = temp + OFFSET;
+
+ return temp;
}
-void onDataWrittenCallback(const GattWriteCallbackParams *params)
+float getHumidity(void)
+{
+
+ float hum;
+ if(tempsensor.getHumidity(&hum) != 0) {
+ SERIAL_DEBUG("Error getting humidity");
+ hum = -1;
+ }
+
+ // Debugging:
+ SERIAL_DEBUG("\nHumidity = %f", hum);
+ char message[50];
+ sprintf (message, "RH=%d\n", (int)hum);
+ DEBUG(message);
+
+ return hum;
+}
+
+void onDataWrittenCallback(const GattWriteCallbackParams *params)
{
- pc.printf("Resetting presence\n");
- presence_before = 0;
+ if (params->data[0] == 1) {
+ blinkLed(ledOn,1);
+ SERIAL_DEBUG("BLE. Resetting presence\n");
+ presence_count = 0;
+ }
+
+ if (params->data[0] == 2) {
+ blinkLed(1,1);
+ blinkLed(1,1);
+ SERIAL_DEBUG("BLE. All LEDs ON/OFF\n");
+ ledOn = !ledOn;
+ }
+
+ 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
+ }
}
/**
@@ -87,9 +240,9 @@
*/
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
- pc.printf("Init \n");
-
- BLE &ble = params->ble;
+ SERIAL_DEBUG("BLE. Init \n");
+
+ BLE& ble = params->ble;
ble_error_t error = params->error;
if (error != BLE_ERROR_NONE) {
@@ -102,106 +255,126 @@
if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
return;
}
-
+
//ble.gap().onConnection(connectionCallback);
- //ble.gap().onDisconnection(disconnectionCallback);
- ble.onDisconnection(disconnectionCallback);
+ ble.gap().onDisconnection(disconnectionCallback);
- ble.gap().setScanParams(500, 400);
+ // Set Transmission power:
+ ble.setTxPower(TxPower);
+
+ //ble.gap().setScanParams(500, 400);
//ble.gap().startScan(advertisementCallback);
-
+
//BLE server setup
- //ble.init();
- //ble_server.gap().onDisconnection(disconnectionCallbackServer); check why gives error
ble.gattServer().onDataWritten(onDataWrittenCallback);
-
+
//Setup primary services
- presenceService = new PresenceDetectionService(ble, presence_before);
- temperatureService = new TemperatureMeasureService(ble, getTemperature());
-
- //setup advertising
+ presenceService = new PresenceDetectionService(ble, presence_count);
+ thermometerServicePtr = new HealthThermometerService(ble, getTemperature(), HealthThermometerService::LOCATION_EAR);
+ humidityService = new HumidityMeasureService(ble, getHumidity());
+ ble.addService(batteryService);
+ 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::THERMOMETER_EAR);
+ 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.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
- ble.gap().setAdvertisingInterval(1000); //1000ms
- ble.gap().startAdvertising();
-}
-
-/**
-*Server functions
-*/
-/* Restart Advertising on disconnection*/
-//void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
-//{
-// ble_server.gap().startAdvertising();
-//}
-
-void periodicCallbackSensor(void)
-{
- //led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
-
- /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
- * heavy-weight sensor polling from the main thread. */
- triggerSensorPolling = true;
- pc.printf("Periodic sensor \n");
+ ble.setAdvertisingInterval(1000); /* 1000ms */
+ //ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
+ ble.startAdvertising();
}
void periodicCallbackPresence(void)
{
- pc.printf("Periodic presence \n");
- //presence_before = 0;
+ triggerPresencePolling = true;
+ presence = 1;
}
-void irq_handler(void)
+void periodicCallbackSensor (void)
{
- presence_now = 1;
- presence_before = 1;
- pc.printf("Presence detected \n");
+ triggerSensorPolling = true;
}
int main(void)
-{
- pc.printf("Start \n");
-
+{
+ SERIAL_DEBUG("Start \n");
+ char pres_message[20];
+
+ blinkLed(1,1);
+
+ //Ticker ticker_presence;
+ //ticker_presence.attach(periodicCallbackPresence, 0.5);
+
+ motion_pin.fall(&periodicCallbackPresence);
+ //motion_pin.rise(&periodicCallbackPresence);
+
Ticker ticker_sensor;
- ticker_sensor.attach(periodicCallbackSensor, 5);
-
- Ticker ticker_presence;
- ticker_presence.attach(periodicCallbackPresence, 300);
-
- motion.rise(&irq_handler);
-
+ ticker_sensor.attach(periodicCallbackSensor, 60);
+
//BLE instance setup
BLE &bleptr = BLE::Instance();
bleptr.init(bleInitComplete);
-
- //float initialDesiredTemperature = 20;
-
+
+ /*
+ //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;
+ //presence = motion_pin.read();
+
+ if (presence) {
+ presence_count++;
+
+ // Debugging:
+ if (presence) {
+ blinkLed(ledOn,1);
+ }
+
+ SERIAL_DEBUG("Presence counter: %i\n", presence_count);
+ sprintf (pres_message, "Pres=%i\n", presence_count);
+ DEBUG(pres_message);
+
+ presence=0;
+ }
+
+ else {
+ SERIAL_DEBUG(".");
+ }
+ }
+
+ /* Update BLE services: */
if (triggerSensorPolling && ble.getGapState().connected) {
triggerSensorPolling = false;
-
- //Do blocking calls or whatever is necessary for sensor polling.
- // error = sensor.readData();
- // if (!error) {
- // thermometerService.updateTemperature(c);
- // }
+ thermometerServicePtr->updateTemperature(getTemperature());
+ humidityService->updateHumidity(getHumidity());
+ presenceService->updatePresence(presence_count);
+ batteryLevel = getBatteryPercent();
+ ble.updateCharacteristicValue(batteryPercentage.getValueAttribute().getHandle(), &batteryLevel, sizeof(batteryLevel));
+ ble.updateCharacteristicValue(TxPowerChar.getValueAttribute().getHandle(), (uint8_t*)&TxPower, 1);
- temperatureService->updateTemperature(getTemperature());
- presenceService->updatePresence(presence_before);
- }
- ble.waitForEvent();
-
- if(presence_now) {
- led = 0;
- //cnt++;
- presence_now = 0;
- //pc.printf("Presence detected \n", cnt);
- wait(2);
- led = 1;
+ } else {
+ ble.waitForEvent();
}
}
}
