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:
22:3710de547ff1
Parent:
20:fc639ef579b6
Child:
25:dd95f36e3461

File content as of revision 22:3710de547ff1:

/*
 * 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>

#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();

}