aconno acnsensa project for iOS devices with iBeacon packets support.

Dependencies:   LSM9DS1 Si7006A20 aconno_SEGGER_RTT aconno_bsp adc52832_common

Committer:
Dautor
Date:
Fri Mar 02 14:32:08 2018 +0000
Revision:
4:634796e5b8c3
Parent:
3:78ceda8ef565
Child:
6:51745805d8b0
Added battery percentage to the MSD

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jurica238814 0:12899fa39f88 1 /*
jurica238814 0:12899fa39f88 2 * aconno.de
jurica238814 0:12899fa39f88 3 * Made by Jurica Resetar
Dautor 1:326ce5e200fb 4 * Edited by Karlo Milicevic
jurica238814 0:12899fa39f88 5 * All right reserved
jurica238814 0:12899fa39f88 6 *
jurica238814 0:12899fa39f88 7 */
jurica238814 0:12899fa39f88 8
jurica238814 0:12899fa39f88 9 #include "mbed.h"
jurica238814 0:12899fa39f88 10 #include "ble/BLE.h"
jurica238814 0:12899fa39f88 11 #include "acd52832_bsp.h"
jurica238814 0:12899fa39f88 12 #include "GapAdvertisingData.h"
jurica238814 0:12899fa39f88 13 #include "Si7006A20.h"
jurica238814 0:12899fa39f88 14 #include "LSM9DS1.h"
jurica238814 0:12899fa39f88 15 #include "math.h"
jurica238814 0:12899fa39f88 16 #include "nrf52_digital.h"
Dautor 1:326ce5e200fb 17 #include "adc52832_common/utilities.h"
Dautor 1:326ce5e200fb 18 #include "MPL115A1.h"
Dautor 4:634796e5b8c3 19 #include "acd_nrf52_saadc.h"
jurica238814 0:12899fa39f88 20
jurica238814 0:12899fa39f88 21 #define V0 0.47 /* In volts */
jurica238814 0:12899fa39f88 22 #define TC 0.01 /* In volts */
jurica238814 0:12899fa39f88 23 #define VCC (3.6)
Dautor 1:326ce5e200fb 24 #define VALUE_TO_PERCENTAGE (100)
Dautor 1:326ce5e200fb 25 #define WAKEUP_TIME_DELAY_MS (150)
Dautor 1:326ce5e200fb 26 #define APPLICATION_ID (0xCF170059)
Dautor 1:326ce5e200fb 27
Dautor 4:634796e5b8c3 28 #define ADC_REFERENCE (3.6f) /* adc reference voltage */
Dautor 4:634796e5b8c3 29 #define ADC_RESOLUTION (1024) /* 10-bit adc */
Dautor 4:634796e5b8c3 30
Dautor 1:326ce5e200fb 31 #define I2C_DATA (p19)
Dautor 1:326ce5e200fb 32 #define I2C_CLK (p20)
Dautor 1:326ce5e200fb 33 #define SPI_MISO (p5)
Dautor 1:326ce5e200fb 34 #define SPI_MOSI (p3)
Dautor 1:326ce5e200fb 35 #define SPI_SCLK (p4)
jurica238814 0:12899fa39f88 36
jurica238814 0:12899fa39f88 37 #define DEBUG_PRINT (0)
jurica238814 0:12899fa39f88 38 #define SLEEP_TIME (0.150) /* Sleep time in seconds */
jurica238814 0:12899fa39f88 39 #define WAKE_UP_TIME (0.150) /* Awake time in ms */
jurica238814 0:12899fa39f88 40 #define ADV_INTERVAL (100) /* Advertising interval in ms */
jurica238814 0:12899fa39f88 41 #define GO_TO_SLEEP (0) /* Sleep flag: 0 -> Device will not go to sleep, 1 -> Will go to sleep mode */
Dautor 1:326ce5e200fb 42 #define CALIBRATION_STEPS 20
jurica238814 0:12899fa39f88 43
Dautor 4:634796e5b8c3 44 static NRF52_SAADC analogIn;
Dautor 1:326ce5e200fb 45 static NRF52_DigitalOut lightPower(p28);
Dautor 1:326ce5e200fb 46 static NRF52_DigitalOut temperaturePower(p31);
Dautor 1:326ce5e200fb 47 static NRF52_DigitalOut shdn(p6);
Dautor 1:326ce5e200fb 48 static NRF52_DigitalOut led(p23);
Dautor 1:326ce5e200fb 49 static NRF52_DigitalOut power(p2);
Dautor 1:326ce5e200fb 50 static NRF52_DigitalOut cs(p7);
Dautor 1:326ce5e200fb 51 static Si7006 *si;
Dautor 1:326ce5e200fb 52 static LSM9DS1 *mems;
Dautor 1:326ce5e200fb 53 static SPI *spi;
Dautor 1:326ce5e200fb 54 static MPL115A1 *mpl115a1;
jurica238814 0:12899fa39f88 55
jurica238814 0:12899fa39f88 56 #if DEBUG_PRINT
jurica238814 0:12899fa39f88 57 #include "nrf52_uart.h"
Dautor 1:326ce5e200fb 58 NRF52_UART serial = NRF52_UART(p25, p26, Baud9600); //Tx, RX BaudRate
jurica238814 0:12899fa39f88 59 char buffer[256] = {0};
jurica238814 0:12899fa39f88 60 #define SEND(...) {uint8_t len = sprintf(buffer, __VA_ARGS__); serial.send(buffer, len);}
Dautor 1:326ce5e200fb 61 #define SENDN(...) {uint8_t len = sprintf(buffer "\n\r", __VA_ARGS__); serial.send(buffer, len);}
jurica238814 0:12899fa39f88 62 #else
jurica238814 0:12899fa39f88 63 #define SEND(...);
Dautor 1:326ce5e200fb 64 #define SENDN(...);
jurica238814 0:12899fa39f88 65 #endif
jurica238814 0:12899fa39f88 66
Dautor 1:326ce5e200fb 67 static bool sleepFlag = true;
jurica238814 0:12899fa39f88 68
Dautor 3:78ceda8ef565 69 static vector3_s memsAccelerometerInit;
Dautor 3:78ceda8ef565 70 static vector3_s memsGyroscopeInit;
Dautor 3:78ceda8ef565 71 static vector3_s memsMagnetometerInit;
jurica238814 0:12899fa39f88 72
Dautor 1:326ce5e200fb 73 static BLE &ble = BLE::Instance();
Dautor 1:326ce5e200fb 74 static GapAdvertisingData adv_data = GapAdvertisingData();
jurica238814 0:12899fa39f88 75
Dautor 1:326ce5e200fb 76 struct __attribute__((packed, aligned(1))) advertising_packet{
Dautor 1:326ce5e200fb 77 uint32_t header;
Dautor 1:326ce5e200fb 78 uint8_t type;
Dautor 1:326ce5e200fb 79 union{
Dautor 1:326ce5e200fb 80 struct{
Dautor 3:78ceda8ef565 81 int16_t gyroscope[3];
Dautor 3:78ceda8ef565 82 int16_t accelerometer[3];
Dautor 3:78ceda8ef565 83 int16_t magnetometer[3];
Dautor 1:326ce5e200fb 84 };
Dautor 1:326ce5e200fb 85 struct{
Dautor 1:326ce5e200fb 86 float temperature;
Dautor 1:326ce5e200fb 87 float humidity;
Dautor 1:326ce5e200fb 88 float pressure;
Dautor 1:326ce5e200fb 89 float light;
Dautor 4:634796e5b8c3 90 uint8_t battery;
Dautor 1:326ce5e200fb 91 };
Dautor 1:326ce5e200fb 92 };
Dautor 1:326ce5e200fb 93 };
Dautor 3:78ceda8ef565 94 static advertising_packet advertisementPacket;
jurica238814 0:12899fa39f88 95
jurica238814 0:12899fa39f88 96 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){
Dautor 1:326ce5e200fb 97 // Restart Advertising on disconnection
jurica238814 0:12899fa39f88 98 BLE::Instance().gap().startAdvertising();
jurica238814 0:12899fa39f88 99 }
jurica238814 0:12899fa39f88 100
jurica238814 0:12899fa39f88 101 /**
jurica238814 0:12899fa39f88 102 * Function for waking the core up
jurica238814 0:12899fa39f88 103 */
Dautor 1:326ce5e200fb 104 void wakeMeUp(){
Dautor 1:326ce5e200fb 105 sleepFlag = false;
Dautor 1:326ce5e200fb 106 }
jurica238814 0:12899fa39f88 107
jurica238814 0:12899fa39f88 108 /**
jurica238814 0:12899fa39f88 109 * Callback triggered when the ble initialization process has finished
jurica238814 0:12899fa39f88 110 */
jurica238814 0:12899fa39f88 111 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){
jurica238814 0:12899fa39f88 112 BLE& ble = params->ble;
jurica238814 0:12899fa39f88 113 ble_error_t error = params->error;
jurica238814 0:12899fa39f88 114
Dautor 3:78ceda8ef565 115 if (error != BLE_ERROR_NONE){
jurica238814 0:12899fa39f88 116 return;
jurica238814 0:12899fa39f88 117 }
jurica238814 0:12899fa39f88 118
jurica238814 0:12899fa39f88 119 /* Ensure that it is the default instance of BLE */
Dautor 3:78ceda8ef565 120 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE){
jurica238814 0:12899fa39f88 121 return;
jurica238814 0:12899fa39f88 122 }
jurica238814 0:12899fa39f88 123
jurica238814 0:12899fa39f88 124 ble.gap().onDisconnection(disconnectionCallback);
jurica238814 0:12899fa39f88 125
jurica238814 0:12899fa39f88 126 /* setup advertising */
jurica238814 0:12899fa39f88 127 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
Dautor 3:78ceda8ef565 128 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&advertisementPacket, sizeof(advertisementPacket));
jurica238814 0:12899fa39f88 129 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
jurica238814 0:12899fa39f88 130 ble.gap().setAdvertisingInterval(ADV_INTERVAL);
jurica238814 0:12899fa39f88 131 ble.gap().startAdvertising();
jurica238814 0:12899fa39f88 132 }
jurica238814 0:12899fa39f88 133
Dautor 1:326ce5e200fb 134 float getLight(){
Dautor 4:634796e5b8c3 135 return ((float)analogIn.getData()[1])/ADC_RESOLUTION * VALUE_TO_PERCENTAGE;
jurica238814 0:12899fa39f88 136 }
jurica238814 0:12899fa39f88 137
jurica238814 0:12899fa39f88 138 float voltage2temp(float vOut){
jurica238814 0:12899fa39f88 139 return ((float)vOut - (float)V0)/((float)TC);
jurica238814 0:12899fa39f88 140 }
jurica238814 0:12899fa39f88 141
Dautor 1:326ce5e200fb 142 float getTemperature(){
Dautor 4:634796e5b8c3 143 return voltage2temp(((float)analogIn.getData()[2])/ADC_RESOLUTION * (float)VCC);
Dautor 4:634796e5b8c3 144 }
Dautor 4:634796e5b8c3 145
Dautor 4:634796e5b8c3 146 uint8_t getBattery(){
Dautor 4:634796e5b8c3 147 uint16_t batteryVoltage = analogIn.getData()[2];
Dautor 4:634796e5b8c3 148 if(batteryVoltage >= 810) return 100;
Dautor 4:634796e5b8c3 149 if(batteryVoltage >= 796) return 85;
Dautor 4:634796e5b8c3 150 if(batteryVoltage >= 782) return 75;
Dautor 4:634796e5b8c3 151 if(batteryVoltage >= 768) return 50;
Dautor 4:634796e5b8c3 152 if(batteryVoltage >= 754) return 25;
Dautor 4:634796e5b8c3 153 if(batteryVoltage >= 740) return 10;
Dautor 4:634796e5b8c3 154 return 0;
jurica238814 0:12899fa39f88 155 }
jurica238814 0:12899fa39f88 156
Dautor 1:326ce5e200fb 157 float getHumidity(){
Dautor 1:326ce5e200fb 158 float result;
Dautor 1:326ce5e200fb 159 si->getHumidity(&result);
Dautor 1:326ce5e200fb 160 return result;
jurica238814 0:12899fa39f88 161 }
jurica238814 0:12899fa39f88 162
Dautor 3:78ceda8ef565 163 void readGyroscope(vector3_s *gyroscopeData){
Dautor 3:78ceda8ef565 164 mems->readGyroscope((int16_t *)gyroscopeData);
Dautor 3:78ceda8ef565 165 *gyroscopeData -= memsGyroscopeInit;
jurica238814 0:12899fa39f88 166 }
jurica238814 0:12899fa39f88 167
Dautor 3:78ceda8ef565 168 void readAccelerometer(vector3_s *accelerometerData){
Dautor 3:78ceda8ef565 169 mems->readAccelerometer((int16_t *)accelerometerData);
Dautor 3:78ceda8ef565 170 *accelerometerData -= memsAccelerometerInit;
jurica238814 0:12899fa39f88 171 }
jurica238814 0:12899fa39f88 172
Dautor 3:78ceda8ef565 173 void readMagnetometer(vector3_s *magnetometerData){
Dautor 3:78ceda8ef565 174 mems->readMagnetometer((int16_t *)magnetometerData);
Dautor 3:78ceda8ef565 175 *magnetometerData -= memsMagnetometerInit;
jurica238814 0:12899fa39f88 176 }
jurica238814 0:12899fa39f88 177
Dautor 3:78ceda8ef565 178 void calibrateAccelerometer(){
Dautor 3:78ceda8ef565 179 vector3_s accelerometerData;
Dautor 1:326ce5e200fb 180 for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter){
Dautor 3:78ceda8ef565 181 readAccelerometer(&accelerometerData);
Dautor 3:78ceda8ef565 182 memsAccelerometerInit += accelerometerData;
jurica238814 0:12899fa39f88 183 }
Dautor 3:78ceda8ef565 184 memsAccelerometerInit /= CALIBRATION_STEPS;
jurica238814 0:12899fa39f88 185 }
jurica238814 0:12899fa39f88 186
Dautor 3:78ceda8ef565 187 void calibrateGyroscope(){
Dautor 3:78ceda8ef565 188 vector3_s gyroscopeData;
Dautor 1:326ce5e200fb 189 for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter){
Dautor 3:78ceda8ef565 190 readGyroscope(&gyroscopeData);
Dautor 3:78ceda8ef565 191 memsGyroscopeInit += gyroscopeData;
jurica238814 0:12899fa39f88 192 }
Dautor 3:78ceda8ef565 193 memsGyroscopeInit /= CALIBRATION_STEPS;
jurica238814 0:12899fa39f88 194 }
jurica238814 0:12899fa39f88 195
jurica238814 0:12899fa39f88 196 void calibrateMag(){
Dautor 3:78ceda8ef565 197 vector3_s magnetometerData;
Dautor 1:326ce5e200fb 198 for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter){
Dautor 3:78ceda8ef565 199 readMagnetometer(&magnetometerData);
Dautor 3:78ceda8ef565 200 memsMagnetometerInit += magnetometerData;
jurica238814 0:12899fa39f88 201 }
Dautor 3:78ceda8ef565 202 memsMagnetometerInit /= CALIBRATION_STEPS;
jurica238814 0:12899fa39f88 203 }
jurica238814 0:12899fa39f88 204
jurica238814 0:12899fa39f88 205 void updateData(){
Dautor 3:78ceda8ef565 206 static uint8_t advertisementType = 0;
jurica238814 0:12899fa39f88 207
Dautor 3:78ceda8ef565 208 if(advertisementType < 1){
Dautor 3:78ceda8ef565 209 advertisementPacket.type = 0x00;
Dautor 3:78ceda8ef565 210 readGyroscope((vector3_s *)advertisementPacket.gyroscope);
Dautor 3:78ceda8ef565 211 readAccelerometer((vector3_s *)advertisementPacket.accelerometer);
Dautor 3:78ceda8ef565 212 readMagnetometer((vector3_s *)advertisementPacket.magnetometer);
jurica238814 0:12899fa39f88 213 }
jurica238814 0:12899fa39f88 214 else{
Dautor 3:78ceda8ef565 215 advertisementPacket.type = 0x01;
Dautor 3:78ceda8ef565 216 advertisementPacket.temperature = getTemperature();
Dautor 3:78ceda8ef565 217 advertisementPacket.light = getLight();
Dautor 3:78ceda8ef565 218 advertisementPacket.humidity = getHumidity();
Dautor 3:78ceda8ef565 219 advertisementPacket.pressure = mpl115a1->getPressure();
Dautor 4:634796e5b8c3 220 advertisementPacket.battery = getBattery();
jurica238814 0:12899fa39f88 221 }
Dautor 3:78ceda8ef565 222 if(++advertisementType > 2) advertisementType = 0;
jurica238814 0:12899fa39f88 223
jurica238814 0:12899fa39f88 224 adv_data = ble.getAdvertisingData();
Dautor 3:78ceda8ef565 225 adv_data.updateData(adv_data.MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&advertisementPacket, sizeof(advertisementPacket));
jurica238814 0:12899fa39f88 226 ble.setAdvertisingData(adv_data);
jurica238814 0:12899fa39f88 227 }
jurica238814 0:12899fa39f88 228
jurica238814 0:12899fa39f88 229
Dautor 1:326ce5e200fb 230 int main(){
jurica238814 0:12899fa39f88 231 power = 1;
Dautor 1:326ce5e200fb 232 wait_ms(WAKEUP_TIME_DELAY_MS);
jurica238814 0:12899fa39f88 233 temperaturePower = 1;
jurica238814 0:12899fa39f88 234 lightPower = 1;
Dautor 1:326ce5e200fb 235 shdn = 1; // Wake up the pressure sensor
Dautor 4:634796e5b8c3 236 analogIn.addChannel(9); // Set VDD as source to SAADC
Dautor 4:634796e5b8c3 237 analogIn.addChannel(6); // Light
Dautor 4:634796e5b8c3 238 analogIn.addChannel(7); // Temp
Dautor 4:634796e5b8c3 239 analogIn.calibrate();
Dautor 4:634796e5b8c3 240
Dautor 3:78ceda8ef565 241 advertisementPacket.header = APPLICATION_ID;
Dautor 1:326ce5e200fb 242
Dautor 1:326ce5e200fb 243 ble.init(bleInitComplete);
jurica238814 0:12899fa39f88 244
Dautor 1:326ce5e200fb 245 I2C i2c(I2C_DATA, I2C_CLK);
Dautor 1:326ce5e200fb 246 si = new Si7006(&i2c);
Dautor 2:c0654c5fb771 247 mems = new LSM9DS1(&i2c);
Dautor 1:326ce5e200fb 248 spi = new SPI(SPI_MOSI, SPI_MISO, SPI_SCLK);
Dautor 1:326ce5e200fb 249 mpl115a1 = new MPL115A1(*spi, cs);
jurica238814 0:12899fa39f88 250
Dautor 3:78ceda8ef565 251 mems->startAccelerometer();
Dautor 3:78ceda8ef565 252 mems->startGyroscope();
Dautor 3:78ceda8ef565 253 mems->startMagnetometer();
jurica238814 0:12899fa39f88 254
jurica238814 0:12899fa39f88 255 led = 1;
jurica238814 0:12899fa39f88 256
jurica238814 0:12899fa39f88 257 Ticker ticker;
Dautor 1:326ce5e200fb 258 ticker.attach(wakeMeUp, SLEEP_TIME); // Wake the device up
jurica238814 0:12899fa39f88 259
Dautor 4:634796e5b8c3 260 while(ble.hasInitialized() == false){
Dautor 4:634796e5b8c3 261 /* spin loop */
Dautor 4:634796e5b8c3 262 }
Dautor 4:634796e5b8c3 263
Dautor 1:326ce5e200fb 264 while(true){
Dautor 1:326ce5e200fb 265 if (sleepFlag && GO_TO_SLEEP){
Dautor 1:326ce5e200fb 266 ble.gap().stopAdvertising();
Dautor 1:326ce5e200fb 267 sleep();
Dautor 1:326ce5e200fb 268 ble.waitForEvent();
Dautor 1:326ce5e200fb 269 }
Dautor 1:326ce5e200fb 270 else{
Dautor 1:326ce5e200fb 271 // I'm awake
Dautor 1:326ce5e200fb 272 updateData();
Dautor 1:326ce5e200fb 273 ble.gap().startAdvertising();
Dautor 1:326ce5e200fb 274 wait_ms(WAKE_UP_TIME);
Dautor 1:326ce5e200fb 275 sleepFlag = true;
jurica238814 0:12899fa39f88 276 }
jurica238814 0:12899fa39f88 277 }
jurica238814 0:12899fa39f88 278 }