aconno acnsensa project for iOS devices with iBeacon packets support.
Dependencies: LSM9DS1 Si7006A20 aconno_SEGGER_RTT aconno_bsp adc52832_common
main.cpp
- Committer:
- Dautor
- Date:
- 2017-12-13
- Revision:
- 1:326ce5e200fb
- Parent:
- 0:12899fa39f88
- Child:
- 2:c0654c5fb771
File content as of revision 1:326ce5e200fb:
/* * aconno.de * Made by Jurica Resetar * Edited by Karlo Milicevic * All right reserved * */ #include "mbed.h" #include "ble/BLE.h" #include "acd52832_bsp.h" #include "GapAdvertisingData.h" #include "Si7006A20.h" #include "LSM9DS1.h" #include "math.h" #include "nrf52_digital.h" #include "adc52832_common/utilities.h" #include "MPL115A1.h" #define V0 0.47 /* In volts */ #define TC 0.01 /* In volts */ #define VCC (3.6) #define VALUE_TO_PERCENTAGE (100) #define WAKEUP_TIME_DELAY_MS (150) #define APPLICATION_ID (0xCF170059) #define I2C_DATA (p19) #define I2C_CLK (p20) #define SPI_MISO (p5) #define SPI_MOSI (p3) #define SPI_SCLK (p4) #define DEBUG_PRINT (0) #define SLEEP_TIME (0.150) /* Sleep time in seconds */ #define WAKE_UP_TIME (0.150) /* Awake time in ms */ #define ADV_INTERVAL (100) /* Advertising interval in ms */ #define GO_TO_SLEEP (0) /* Sleep flag: 0 -> Device will not go to sleep, 1 -> Will go to sleep mode */ #define CALIBRATION_STEPS 20 static AnalogIn temperature(ADC_TEMP); static AnalogIn light(ADC_LIGHT); static NRF52_DigitalOut lightPower(p28); static NRF52_DigitalOut temperaturePower(p31); static NRF52_DigitalOut shdn(p6); static NRF52_DigitalOut led(p23); static NRF52_DigitalOut power(p2); static NRF52_DigitalOut cs(p7); static Si7006 *si; static LSM9DS1 *mems; static SPI *spi; static MPL115A1 *mpl115a1; #if DEBUG_PRINT #include "nrf52_uart.h" NRF52_UART serial = NRF52_UART(p25, p26, Baud9600); //Tx, RX BaudRate char buffer[256] = {0}; #define SEND(...) {uint8_t len = sprintf(buffer, __VA_ARGS__); serial.send(buffer, len);} #define SENDN(...) {uint8_t len = sprintf(buffer "\n\r", __VA_ARGS__); serial.send(buffer, len);} #else #define SEND(...); #define SENDN(...); #endif static bool sleepFlag = true; static vector3_s memsAccInit; static vector3_s memsGyrInit; static vector3_s memsMagInit; static BLE &ble = BLE::Instance(); static GapAdvertisingData adv_data = GapAdvertisingData(); struct __attribute__((packed, aligned(1))) advertising_packet{ uint32_t header; uint8_t type; union{ struct{ int16_t gyr[3]; int16_t acc[3]; int16_t mag[3]; }; struct{ float temperature; float humidity; float pressure; float light; }; }; }; static advertising_packet advPacket; void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){ // Restart Advertising on disconnection BLE::Instance().gap().startAdvertising(); } /** * Function for waking the core up */ void wakeMeUp(){ sleepFlag = false; } void onBleInitError(BLE &ble, ble_error_t error){ /* Avoid compiler warnings */ (void) ble; (void) error; } /** * Callback triggered when the ble initialization process has finished */ void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){ BLE& ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { onBleInitError(ble, error); return; } /* Ensure that it is the default instance of BLE */ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } ble.gap().onDisconnection(disconnectionCallback); /* setup advertising */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&advPacket, sizeof(advPacket)); ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(ADV_INTERVAL); ble.gap().startAdvertising(); } float getLight(){ return light.read() * VALUE_TO_PERCENTAGE; } float voltage2temp(float vOut){ return ((float)vOut - (float)V0)/((float)TC); } float getTemperature(){ return voltage2temp(temperature.read()*(float)VCC); } float getHumidity(){ float result; si->getHumidity(&result); return result; } void readGyr(vector3_s *gyro_data){ mems->readGyro((int16_t *)gyro_data); *gyro_data -= memsGyrInit; } void readAcc(vector3_s *acc_data){ mems->readAcc((int16_t *)acc_data); *acc_data -= memsAccInit; } void readMag(vector3_s *magneto_data){ mems->readMag((int16_t *)magneto_data); *magneto_data -= memsMagInit; } void calibrateAcc(){ vector3_s acc_data; for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter){ readAcc(&acc_data); memsAccInit += acc_data; } memsAccInit /= CALIBRATION_STEPS; } void calibrateGyr(){ vector3_s gyro_data; for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter){ readGyr(&gyro_data); memsGyrInit += gyro_data; } memsGyrInit /= CALIBRATION_STEPS; } void calibrateMag(){ vector3_s mag_data; for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter){ readMag(&mag_data); memsMagInit += mag_data; } memsMagInit /= CALIBRATION_STEPS; } void updateData(){ static uint8_t adv_type = 0; if(adv_type < 1){ advPacket.type = 0x00; readGyr((vector3_s *)advPacket.gyr); readAcc((vector3_s *)advPacket.acc); readMag((vector3_s *)advPacket.mag); } else{ advPacket.type = 0x01; advPacket.temperature = getTemperature(); advPacket.light = getLight(); advPacket.humidity = getHumidity(); advPacket.pressure = mpl115a1->getPressure(); } if(++adv_type > 2) adv_type = 0; adv_data = ble.getAdvertisingData(); adv_data.updateData(adv_data.MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&advPacket, sizeof(advPacket)); ble.setAdvertisingData(adv_data); } int main(){ power = 1; wait_ms(WAKEUP_TIME_DELAY_MS); temperaturePower = 1; lightPower = 1; shdn = 1; // Wake up the pressure sensor advPacket.header = APPLICATION_ID; ble.init(bleInitComplete); I2C i2c(I2C_DATA, I2C_CLK); si = new Si7006(&i2c); mems = new LSM9DS1(i2c); spi = new SPI(SPI_MOSI, SPI_MISO, SPI_SCLK); mpl115a1 = new MPL115A1(*spi, cs); mems->startAcc(); mems->startGyro(); mems->startMag(); led = 1; Ticker ticker; ticker.attach(wakeMeUp, SLEEP_TIME); // Wake the device up while(ble.hasInitialized() == false); /* spin loop */ while(true){ if (sleepFlag && GO_TO_SLEEP){ ble.gap().stopAdvertising(); sleep(); ble.waitForEvent(); } else{ // I'm awake updateData(); ble.gap().startAdvertising(); wait_ms(WAKE_UP_TIME); sleepFlag = true; } } }