aconno acnsensa project for iOS devices with iBeacon packets support.

Dependencies:   LSM9DS1 Si7006A20 aconno_SEGGER_RTT aconno_bsp adc52832_common

Committer:
jurica238814
Date:
Fri Aug 03 15:03:04 2018 +0200
Branch:
noSensors
Revision:
25:dd95f36e3461
Parent:
22:3710de547ff1
bug fixed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jurica238814 16:e86a91db0b72 1 /*
jurica238814 16:e86a91db0b72 2 * aconno.de
jurica238814 16:e86a91db0b72 3 * Made by Jurica Resetar
jurica238814 16:e86a91db0b72 4 * Edited by Karlo Milicevic
jurica238814 16:e86a91db0b72 5 * Edited by Dominik Bartolovic
jurica238814 16:e86a91db0b72 6 * All right reserved
jurica238814 16:e86a91db0b72 7 *
jurica238814 16:e86a91db0b72 8 */
jurica238814 16:e86a91db0b72 9
jurica238814 16:e86a91db0b72 10 #include "mbed.h"
jurica238814 16:e86a91db0b72 11 #include "ble/BLE.h"
jurica238814 16:e86a91db0b72 12 #include "acd52832_bsp.h"
jurica238814 16:e86a91db0b72 13 #include "GapAdvertisingData.h"
jurica238814 16:e86a91db0b72 14 #include "Si7006A20.h"
jurica238814 16:e86a91db0b72 15 #include "LSM9DS1.h"
jurica238814 16:e86a91db0b72 16 #include "math.h"
jurica238814 16:e86a91db0b72 17 #include "nrf52_digital.h"
jurica238814 16:e86a91db0b72 18 #include "adc52832_common/utilities.h"
jurica238814 16:e86a91db0b72 19 #include "MPL115A1.h"
jurica238814 16:e86a91db0b72 20 #include "acd_nrf52_saadc.h"
jurica238814 16:e86a91db0b72 21 #include "service.h"
jurica238814 16:e86a91db0b72 22 #include <events/mbed_events.h>
jurica238814 25:dd95f36e3461 23 #include "aconnoConfig.h"
jurica238814 16:e86a91db0b72 24
jurica238814 16:e86a91db0b72 25 #define V0 0.47 /* In volts */
jurica238814 16:e86a91db0b72 26 #define TC 0.01 /* In volts */
jurica238814 16:e86a91db0b72 27 #define VCC (3.6)
jurica238814 16:e86a91db0b72 28 #define VALUE_TO_PERCENTAGE (100)
jurica238814 16:e86a91db0b72 29 #define WAKEUP_TIME_DELAY_MS (150)
jurica238814 16:e86a91db0b72 30 #define APPLICATION_ID (0xCF170059)
jurica238814 16:e86a91db0b72 31
jurica238814 16:e86a91db0b72 32 #define ADC_REFERENCE (3.6f) /* adc reference voltage */
jurica238814 16:e86a91db0b72 33 #define ADC_RESOLUTION (1024) /* 10-bit adc */
jurica238814 16:e86a91db0b72 34
jurica238814 16:e86a91db0b72 35 #define I2C_DATA (p19)
jurica238814 16:e86a91db0b72 36 #define I2C_CLK (p20)
jurica238814 16:e86a91db0b72 37 #define SPI_MISO (p5)
jurica238814 16:e86a91db0b72 38 #define SPI_MOSI (p3)
jurica238814 16:e86a91db0b72 39 #define SPI_SCLK (p4)
jurica238814 16:e86a91db0b72 40
jurica238814 16:e86a91db0b72 41 #define DEBUG (0)
jurica238814 16:e86a91db0b72 42 #define DEBUG_PRINT (1)
jurica238814 16:e86a91db0b72 43 #define SLEEP_TIME (0.150) /* Sleep time in seconds */
jurica238814 16:e86a91db0b72 44 #define WAKE_UP_TIME (0.150) /* Awake time in ms */
jurica238814 16:e86a91db0b72 45 #define ADV_INTERVAL (1000) /* Advertising interval in ms */
jurica238814 16:e86a91db0b72 46 #define GO_TO_SLEEP (0)
jurica238814 16:e86a91db0b72 47 /* Sleep flag: 0 -> Device will not go to sleep, 1 -> Will go to sleep mode */
jurica238814 16:e86a91db0b72 48 #define CALIBRATION_STEPS (20)
jurica238814 16:e86a91db0b72 49 #define TX_POWER_DB (4)
jurica238814 16:e86a91db0b72 50 #define INVERT_AXES (0)
jurica238814 16:e86a91db0b72 51
jurica238814 16:e86a91db0b72 52 uint8_t gConnected = 0;
jurica238814 20:fc639ef579b6 53 DigitalOut aliveLed(p23);
jurica238814 20:fc639ef579b6 54 DigitalOut connectedLed(p24);
jurica238814 16:e86a91db0b72 55
jurica238814 16:e86a91db0b72 56 static EventQueue eventQueue(32 * EVENTS_EVENT_SIZE);
jurica238814 16:e86a91db0b72 57 uint8_t myMacAddress[6] = {};
jurica238814 16:e86a91db0b72 58 MACService *macServicePtr;
jurica238814 16:e86a91db0b72 59
jurica238814 16:e86a91db0b72 60 #if DEBUG_PRINT
jurica238814 16:e86a91db0b72 61 #include "SEGGER_RTT.h"
jurica238814 16:e86a91db0b72 62 #define printf(...) SEGGER_RTT_printf(0, __VA_ARGS__)
jurica238814 16:e86a91db0b72 63 #else
jurica238814 16:e86a91db0b72 64 #define printf(...)
jurica238814 16:e86a91db0b72 65 #endif
jurica238814 16:e86a91db0b72 66
jurica238814 16:e86a91db0b72 67 static bool sleepFlag = true;
jurica238814 16:e86a91db0b72 68
jurica238814 16:e86a91db0b72 69 static vector3_s memsAccelerometerInit;
jurica238814 16:e86a91db0b72 70 static vector3_s memsGyroscopeInit;
jurica238814 16:e86a91db0b72 71 static vector3_s memsMagnetometerInit;
jurica238814 16:e86a91db0b72 72
jurica238814 16:e86a91db0b72 73 static GapAdvertisingData adv_data = GapAdvertisingData();
jurica238814 16:e86a91db0b72 74
jurica238814 16:e86a91db0b72 75 typedef struct __attribute__((packed, aligned(1)))
jurica238814 16:e86a91db0b72 76 {
jurica238814 22:3710de547ff1 77 // AppleID is constant
jurica238814 22:3710de547ff1 78 uint16_t appleID = 0x004C;
jurica238814 22:3710de547ff1 79 // secondID is constant
jurica238814 22:3710de547ff1 80 uint8_t secondID = 0x02;
jurica238814 22:3710de547ff1 81 // DataSize is constant
jurica238814 22:3710de547ff1 82 uint8_t DataSize = 0x15;
jurica238814 22:3710de547ff1 83 uint8_t UUID[16] = {UUID_INIT};
jurica238814 22:3710de547ff1 84 uint16_t major = MAJOR;
jurica238814 22:3710de547ff1 85 uint16_t minor = MINOR;
jurica238814 22:3710de547ff1 86 int8_t RSSI = RSSI_INIT;
jurica238814 16:e86a91db0b72 87 }IBeaconMSD;
jurica238814 16:e86a91db0b72 88
jurica238814 16:e86a91db0b72 89 struct __attribute__((packed, aligned(1))) advertising_packet
jurica238814 16:e86a91db0b72 90 {
jurica238814 16:e86a91db0b72 91 uint32_t header;
jurica238814 16:e86a91db0b72 92 uint8_t type;
jurica238814 16:e86a91db0b72 93 union{
jurica238814 16:e86a91db0b72 94 struct{
jurica238814 16:e86a91db0b72 95 int16_t gyroscope[3];
jurica238814 16:e86a91db0b72 96 int16_t accelerometer[3];
jurica238814 16:e86a91db0b72 97 int16_t magnetometer[3];
jurica238814 16:e86a91db0b72 98 uint16_t acc_lsb_value;
jurica238814 16:e86a91db0b72 99 };
jurica238814 16:e86a91db0b72 100 struct{
jurica238814 16:e86a91db0b72 101 float temperature;
jurica238814 16:e86a91db0b72 102 float humidity;
jurica238814 16:e86a91db0b72 103 float pressure;
jurica238814 16:e86a91db0b72 104 float light;
jurica238814 16:e86a91db0b72 105 uint8_t battery;
jurica238814 16:e86a91db0b72 106 };
jurica238814 16:e86a91db0b72 107 };
jurica238814 16:e86a91db0b72 108 };
jurica238814 16:e86a91db0b72 109
jurica238814 16:e86a91db0b72 110 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context)
jurica238814 16:e86a91db0b72 111 {
jurica238814 16:e86a91db0b72 112 BLE &ble = context->ble;
jurica238814 16:e86a91db0b72 113 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
jurica238814 16:e86a91db0b72 114 }
jurica238814 16:e86a91db0b72 115
jurica238814 16:e86a91db0b72 116 static advertising_packet advertisementPacket;
jurica238814 16:e86a91db0b72 117 IBeaconMSD ibeaconMSD;
jurica238814 16:e86a91db0b72 118
jurica238814 16:e86a91db0b72 119 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
jurica238814 16:e86a91db0b72 120 {
jurica238814 16:e86a91db0b72 121 // Restart Advertising on disconnection
jurica238814 16:e86a91db0b72 122 gConnected = 0;
jurica238814 20:fc639ef579b6 123 connectedLed = 1;
jurica238814 16:e86a91db0b72 124 BLE::Instance().gap().startAdvertising();
jurica238814 16:e86a91db0b72 125 }
jurica238814 16:e86a91db0b72 126
jurica238814 16:e86a91db0b72 127 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
jurica238814 16:e86a91db0b72 128 {
jurica238814 16:e86a91db0b72 129 printf("Connection callback.\n");
jurica238814 20:fc639ef579b6 130 connectedLed = 0;
jurica238814 16:e86a91db0b72 131 gConnected = 1;
jurica238814 16:e86a91db0b72 132 }
jurica238814 16:e86a91db0b72 133
jurica238814 16:e86a91db0b72 134 /**
jurica238814 16:e86a91db0b72 135 * Callback triggered when the ble initialization process has finished
jurica238814 16:e86a91db0b72 136 */
jurica238814 16:e86a91db0b72 137 void bleInitCompleteSensors(BLE::InitializationCompleteCallbackContext *params)
jurica238814 16:e86a91db0b72 138 {
jurica238814 16:e86a91db0b72 139 BLE& ble = params->ble;
jurica238814 16:e86a91db0b72 140 ble_error_t error = params->error;
jurica238814 16:e86a91db0b72 141
jurica238814 16:e86a91db0b72 142 if (error != BLE_ERROR_NONE){
jurica238814 16:e86a91db0b72 143 return;
jurica238814 16:e86a91db0b72 144 }
jurica238814 16:e86a91db0b72 145
jurica238814 16:e86a91db0b72 146 /* Ensure that it is the default instance of BLE */
jurica238814 16:e86a91db0b72 147 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE){
jurica238814 16:e86a91db0b72 148 return;
jurica238814 16:e86a91db0b72 149 }
jurica238814 16:e86a91db0b72 150
jurica238814 18:442bc914996b 151 uint8_t mac[6] = {0,0,0,0,0,0};
jurica238814 16:e86a91db0b72 152 BLEProtocol::AddressType_t temp_address_type;
jurica238814 16:e86a91db0b72 153 ble.gap().getAddress(&temp_address_type, myMacAddress);
jurica238814 16:e86a91db0b72 154 macServicePtr = new MACService(ble, mac);
jurica238814 16:e86a91db0b72 155 macServicePtr->updateMacAddress(myMacAddress); // Update MAC address
jurica238814 16:e86a91db0b72 156
jurica238814 16:e86a91db0b72 157 ble.gap().onConnection(onConnectionCallback);
jurica238814 16:e86a91db0b72 158 ble.gap().onDisconnection(disconnectionCallback);
jurica238814 16:e86a91db0b72 159
jurica238814 16:e86a91db0b72 160 /* setup advertising */
jurica238814 16:e86a91db0b72 161 ble.gap().accumulateAdvertisingPayload(
jurica238814 16:e86a91db0b72 162 GapAdvertisingData::BREDR_NOT_SUPPORTED);
jurica238814 16:e86a91db0b72 163 ble.gap().accumulateAdvertisingPayload(
jurica238814 16:e86a91db0b72 164 GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA,
jurica238814 16:e86a91db0b72 165 (uint8_t *)&advertisementPacket, sizeof(advertisementPacket));
jurica238814 16:e86a91db0b72 166 ble.gap().setAdvertisingType(
jurica238814 16:e86a91db0b72 167 GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
jurica238814 16:e86a91db0b72 168 ble.gap().setAdvertisingInterval(ADV_INTERVAL);
jurica238814 18:442bc914996b 169 printf("Init started....\t\t");
jurica238814 17:18f4bf2a368a 170 ble.gap().setTxPower(TX_POWER_DB); // Set TX power to TX_POWER_DB
jurica238814 16:e86a91db0b72 171 ble.gap().startAdvertising();
jurica238814 18:442bc914996b 172 printf("Init done.\n");
jurica238814 16:e86a91db0b72 173 }
jurica238814 16:e86a91db0b72 174
jurica238814 16:e86a91db0b72 175 void updateData(){
jurica238814 16:e86a91db0b72 176 static uint8_t advertisementType = 0;
jurica238814 16:e86a91db0b72 177 int16_t temp_acc[3];
jurica238814 16:e86a91db0b72 178 BLE &ble = BLE::Instance();
jurica238814 16:e86a91db0b72 179
jurica238814 16:e86a91db0b72 180 if(!advertisementType && !gConnected)
jurica238814 16:e86a91db0b72 181 {
jurica238814 16:e86a91db0b72 182 printf("Sensor format 1.\n");
jurica238814 18:442bc914996b 183 ble.gap().clearAdvertisingPayload();
jurica238814 18:442bc914996b 184 /* setup advertising */
jurica238814 18:442bc914996b 185 ble.gap().accumulateAdvertisingPayload(
jurica238814 18:442bc914996b 186 GapAdvertisingData::BREDR_NOT_SUPPORTED);
jurica238814 18:442bc914996b 187 ble.gap().accumulateAdvertisingPayload(
jurica238814 18:442bc914996b 188 GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA,
jurica238814 18:442bc914996b 189 (uint8_t *)&advertisementPacket, sizeof(advertisementPacket));
jurica238814 18:442bc914996b 190 ble.gap().setAdvertisingType(
jurica238814 18:442bc914996b 191 GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
jurica238814 18:442bc914996b 192
jurica238814 16:e86a91db0b72 193 adv_data = ble.getAdvertisingData();
jurica238814 16:e86a91db0b72 194 advertisementPacket.type = 0x00;
jurica238814 16:e86a91db0b72 195 advertisementPacket.acc_lsb_value = (0xF9E);
jurica238814 16:e86a91db0b72 196 // ^--- That's in ug cuz MSB is 1
jurica238814 16:e86a91db0b72 197 #if INVERT_AXES
jurica238814 16:e86a91db0b72 198 advertisementPacket.accelerometer[0] = temp_acc[1];
jurica238814 16:e86a91db0b72 199 advertisementPacket.accelerometer[1] = temp_acc[0];
jurica238814 16:e86a91db0b72 200 advertisementPacket.accelerometer[2] = temp_acc[2];
jurica238814 16:e86a91db0b72 201 #endif
jurica238814 16:e86a91db0b72 202
jurica238814 16:e86a91db0b72 203 adv_data.updateData(adv_data.MANUFACTURER_SPECIFIC_DATA,
jurica238814 16:e86a91db0b72 204 (uint8_t *)&advertisementPacket, sizeof(advertisementPacket));
jurica238814 16:e86a91db0b72 205 ble.setAdvertisingData(adv_data);
jurica238814 16:e86a91db0b72 206 }
jurica238814 16:e86a91db0b72 207 else if (advertisementType == 1 && !gConnected)
jurica238814 16:e86a91db0b72 208 {
jurica238814 16:e86a91db0b72 209 printf("Sensor format 2.\n");
jurica238814 16:e86a91db0b72 210 adv_data = ble.getAdvertisingData();
jurica238814 16:e86a91db0b72 211 advertisementPacket.type = 0x01;
jurica238814 20:fc639ef579b6 212 advertisementPacket.temperature = 0.23;
jurica238814 16:e86a91db0b72 213
jurica238814 16:e86a91db0b72 214 adv_data.updateData(adv_data.MANUFACTURER_SPECIFIC_DATA,
jurica238814 16:e86a91db0b72 215 (uint8_t *)&advertisementPacket, sizeof(advertisementPacket));
jurica238814 16:e86a91db0b72 216 ble.setAdvertisingData(adv_data);
jurica238814 16:e86a91db0b72 217 }
jurica238814 16:e86a91db0b72 218
jurica238814 16:e86a91db0b72 219 else if (!gConnected)
jurica238814 16:e86a91db0b72 220 {
jurica238814 16:e86a91db0b72 221 printf("Beacon format!\n");
jurica238814 18:442bc914996b 222 ble.gap().clearAdvertisingPayload();
jurica238814 18:442bc914996b 223 ble.gap().accumulateAdvertisingPayload(
jurica238814 18:442bc914996b 224 GapAdvertisingData::BREDR_NOT_SUPPORTED);
jurica238814 18:442bc914996b 225 ble.gap().accumulateAdvertisingPayload(
jurica238814 18:442bc914996b 226 GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA,
jurica238814 18:442bc914996b 227 (uint8_t*)&ibeaconMSD, sizeof(ibeaconMSD));
jurica238814 18:442bc914996b 228 ble.gap().startAdvertising();
jurica238814 16:e86a91db0b72 229 }
jurica238814 16:e86a91db0b72 230 if(++advertisementType > 2) advertisementType = 0;
jurica238814 16:e86a91db0b72 231 }
jurica238814 16:e86a91db0b72 232
jurica238814 20:fc639ef579b6 233 void blinky()
jurica238814 20:fc639ef579b6 234 {
jurica238814 20:fc639ef579b6 235 aliveLed = !aliveLed;
jurica238814 20:fc639ef579b6 236 }
jurica238814 20:fc639ef579b6 237
jurica238814 16:e86a91db0b72 238 int main()
jurica238814 16:e86a91db0b72 239 {
jurica238814 16:e86a91db0b72 240 printf("Main started.\n");
jurica238814 16:e86a91db0b72 241
jurica238814 16:e86a91db0b72 242 Thread bleT;
jurica238814 16:e86a91db0b72 243
jurica238814 20:fc639ef579b6 244 connectedLed = 1;
jurica238814 16:e86a91db0b72 245
jurica238814 16:e86a91db0b72 246 advertisementPacket.header = APPLICATION_ID;
jurica238814 16:e86a91db0b72 247
jurica238814 16:e86a91db0b72 248 ibeaconMSD.appleID = 0x004C;
jurica238814 16:e86a91db0b72 249 ibeaconMSD.secondID = 0x02;
jurica238814 16:e86a91db0b72 250 ibeaconMSD.DataSize = 0x15;
jurica238814 16:e86a91db0b72 251 ibeaconMSD.UUID[0] = 0x11;
jurica238814 16:e86a91db0b72 252 ibeaconMSD.UUID[1] = 0x22;
jurica238814 16:e86a91db0b72 253 ibeaconMSD.UUID[2] = 0x33;
jurica238814 16:e86a91db0b72 254 ibeaconMSD.RSSI = -4;
jurica238814 16:e86a91db0b72 255
jurica238814 16:e86a91db0b72 256 BLE &ble = BLE::Instance();
jurica238814 16:e86a91db0b72 257 ble.init(bleInitCompleteSensors);
jurica238814 16:e86a91db0b72 258 while(ble.hasInitialized() == false){
jurica238814 16:e86a91db0b72 259 /* spin loop */
jurica238814 16:e86a91db0b72 260 }
jurica238814 16:e86a91db0b72 261 ble.onEventsToProcess(scheduleBleEventsProcessing);
jurica238814 16:e86a91db0b72 262
jurica238814 20:fc639ef579b6 263 eventQueue.call_every(500, blinky);
jurica238814 18:442bc914996b 264 eventQueue.call_every(500, updateData);
jurica238814 16:e86a91db0b72 265
jurica238814 16:e86a91db0b72 266 // This call stops main thread
jurica238814 16:e86a91db0b72 267 eventQueue.dispatch_forever();
jurica238814 16:e86a91db0b72 268
jurica238814 16:e86a91db0b72 269 }