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