aconno acnsensa project for iOS devices with iBeacon packets support.
Dependencies: LSM9DS1 Si7006A20 aconno_SEGGER_RTT aconno_bsp adc52832_common
main.cpp
- Committer:
- jurica238814
- Date:
- 2018-08-03
- Branch:
- noSensors
- Revision:
- 25:dd95f36e3461
- Parent:
- 22:3710de547ff1
File content as of revision 25:dd95f36e3461:
/* * aconno.de * Made by Jurica Resetar * Edited by Karlo Milicevic * Edited by Dominik Bartolovic * 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" #include "acd_nrf52_saadc.h" #include "service.h" #include <events/mbed_events.h> #include "aconnoConfig.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 ADC_REFERENCE (3.6f) /* adc reference voltage */ #define ADC_RESOLUTION (1024) /* 10-bit adc */ #define I2C_DATA (p19) #define I2C_CLK (p20) #define SPI_MISO (p5) #define SPI_MOSI (p3) #define SPI_SCLK (p4) #define DEBUG (0) #define DEBUG_PRINT (1) #define SLEEP_TIME (0.150) /* Sleep time in seconds */ #define WAKE_UP_TIME (0.150) /* Awake time in ms */ #define ADV_INTERVAL (1000) /* 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) #define TX_POWER_DB (4) #define INVERT_AXES (0) uint8_t gConnected = 0; DigitalOut aliveLed(p23); DigitalOut connectedLed(p24); static EventQueue eventQueue(32 * EVENTS_EVENT_SIZE); uint8_t myMacAddress[6] = {}; MACService *macServicePtr; #if DEBUG_PRINT #include "SEGGER_RTT.h" #define printf(...) SEGGER_RTT_printf(0, __VA_ARGS__) #else #define printf(...) #endif static bool sleepFlag = true; static vector3_s memsAccelerometerInit; static vector3_s memsGyroscopeInit; static vector3_s memsMagnetometerInit; static GapAdvertisingData adv_data = GapAdvertisingData(); typedef struct __attribute__((packed, aligned(1))) { // AppleID is constant uint16_t appleID = 0x004C; // secondID is constant uint8_t secondID = 0x02; // DataSize is constant uint8_t DataSize = 0x15; uint8_t UUID[16] = {UUID_INIT}; uint16_t major = MAJOR; uint16_t minor = MINOR; int8_t RSSI = RSSI_INIT; }IBeaconMSD; 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]; uint16_t acc_lsb_value; }; struct{ float temperature; float humidity; float pressure; float light; uint8_t battery; }; }; }; void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { BLE &ble = context->ble; eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); } static advertising_packet advertisementPacket; IBeaconMSD ibeaconMSD; void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { // Restart Advertising on disconnection gConnected = 0; connectedLed = 1; BLE::Instance().gap().startAdvertising(); } void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params) { printf("Connection callback.\n"); connectedLed = 0; gConnected = 1; } /** * Callback triggered when the ble initialization process has finished */ void bleInitCompleteSensors(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; } uint8_t mac[6] = {0,0,0,0,0,0}; BLEProtocol::AddressType_t temp_address_type; ble.gap().getAddress(&temp_address_type, myMacAddress); macServicePtr = new MACService(ble, mac); macServicePtr->updateMacAddress(myMacAddress); // Update MAC address ble.gap().onConnection(onConnectionCallback); 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_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(ADV_INTERVAL); printf("Init started....\t\t"); ble.gap().setTxPower(TX_POWER_DB); // Set TX power to TX_POWER_DB ble.gap().startAdvertising(); printf("Init done.\n"); } void updateData(){ static uint8_t advertisementType = 0; int16_t temp_acc[3]; BLE &ble = BLE::Instance(); if(!advertisementType && !gConnected) { printf("Sensor format 1.\n"); ble.gap().clearAdvertisingPayload(); /* 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_CONNECTABLE_UNDIRECTED); adv_data = ble.getAdvertisingData(); advertisementPacket.type = 0x00; advertisementPacket.acc_lsb_value = (0xF9E); // ^--- That's in ug cuz MSB is 1 #if INVERT_AXES advertisementPacket.accelerometer[0] = temp_acc[1]; advertisementPacket.accelerometer[1] = temp_acc[0]; advertisementPacket.accelerometer[2] = temp_acc[2]; #endif adv_data.updateData(adv_data.MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&advertisementPacket, sizeof(advertisementPacket)); ble.setAdvertisingData(adv_data); } else if (advertisementType == 1 && !gConnected) { printf("Sensor format 2.\n"); adv_data = ble.getAdvertisingData(); advertisementPacket.type = 0x01; advertisementPacket.temperature = 0.23; adv_data.updateData(adv_data.MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&advertisementPacket, sizeof(advertisementPacket)); ble.setAdvertisingData(adv_data); } else if (!gConnected) { printf("Beacon format!\n"); ble.gap().clearAdvertisingPayload(); ble.gap().accumulateAdvertisingPayload( GapAdvertisingData::BREDR_NOT_SUPPORTED); ble.gap().accumulateAdvertisingPayload( GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t*)&ibeaconMSD, sizeof(ibeaconMSD)); ble.gap().startAdvertising(); } if(++advertisementType > 2) advertisementType = 0; } void blinky() { aliveLed = !aliveLed; } int main() { printf("Main started.\n"); Thread bleT; connectedLed = 1; advertisementPacket.header = APPLICATION_ID; ibeaconMSD.appleID = 0x004C; ibeaconMSD.secondID = 0x02; ibeaconMSD.DataSize = 0x15; ibeaconMSD.UUID[0] = 0x11; ibeaconMSD.UUID[1] = 0x22; ibeaconMSD.UUID[2] = 0x33; ibeaconMSD.RSSI = -4; BLE &ble = BLE::Instance(); ble.init(bleInitCompleteSensors); while(ble.hasInitialized() == false){ /* spin loop */ } ble.onEventsToProcess(scheduleBleEventsProcessing); eventQueue.call_every(500, blinky); eventQueue.call_every(500, updateData); // This call stops main thread eventQueue.dispatch_forever(); }