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:
- 2018-03-02
- Revision:
- 3:78ceda8ef565
- Parent:
- 2:c0654c5fb771
- Child:
- 4:634796e5b8c3
File content as of revision 3:78ceda8ef565:
/* * 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 memsAccelerometerInit; static vector3_s memsGyroscopeInit; static vector3_s memsMagnetometerInit; 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 gyroscope[3]; int16_t accelerometer[3]; int16_t magnetometer[3]; }; struct{ float temperature; float humidity; float pressure; float light; }; }; }; static advertising_packet advertisementPacket; 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; } /** * 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){ 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 *)&advertisementPacket, sizeof(advertisementPacket)); 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 readGyroscope(vector3_s *gyroscopeData){ mems->readGyroscope((int16_t *)gyroscopeData); *gyroscopeData -= memsGyroscopeInit; } void readAccelerometer(vector3_s *accelerometerData){ mems->readAccelerometer((int16_t *)accelerometerData); *accelerometerData -= memsAccelerometerInit; } void readMagnetometer(vector3_s *magnetometerData){ mems->readMagnetometer((int16_t *)magnetometerData); *magnetometerData -= memsMagnetometerInit; } void calibrateAccelerometer(){ vector3_s accelerometerData; for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter){ readAccelerometer(&accelerometerData); memsAccelerometerInit += accelerometerData; } memsAccelerometerInit /= CALIBRATION_STEPS; } void calibrateGyroscope(){ vector3_s gyroscopeData; for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter){ readGyroscope(&gyroscopeData); memsGyroscopeInit += gyroscopeData; } memsGyroscopeInit /= CALIBRATION_STEPS; } void calibrateMag(){ vector3_s magnetometerData; for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter){ readMagnetometer(&magnetometerData); memsMagnetometerInit += magnetometerData; } memsMagnetometerInit /= CALIBRATION_STEPS; } void updateData(){ static uint8_t advertisementType = 0; if(advertisementType < 1){ advertisementPacket.type = 0x00; readGyroscope((vector3_s *)advertisementPacket.gyroscope); readAccelerometer((vector3_s *)advertisementPacket.accelerometer); readMagnetometer((vector3_s *)advertisementPacket.magnetometer); } else{ advertisementPacket.type = 0x01; advertisementPacket.temperature = getTemperature(); advertisementPacket.light = getLight(); advertisementPacket.humidity = getHumidity(); advertisementPacket.pressure = mpl115a1->getPressure(); } if(++advertisementType > 2) advertisementType = 0; adv_data = ble.getAdvertisingData(); adv_data.updateData(adv_data.MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&advertisementPacket, sizeof(advertisementPacket)); 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 advertisementPacket.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->startAccelerometer(); mems->startGyroscope(); mems->startMagnetometer(); 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; } } }