BLE-WiFi with BIOSensors

Dependencies:   AS7000 BNO055 NNN50_WIFI_API

DELTA NNN50 (Bluetooth LE 4.X & 802.11 b/g/n) with Bio Sensor (HRM, 9DoF motion Sensor) reference design.

Env. Setup step by step.

  1. Download or build a TCP Server on you host computer
    1. Please find out the TCP server code or install TCP server application in your host computer.
  2. Import this sample application and setup these information about AP & TCP Server
    1. *char* AP_SSID = "SOG";
    2. *char* AP_PWD = "1122334455667788";
    3. *char* TCP_SERVER_ADDRESS = "10.0.1.13";
    4. *int TCP_SERVER_PORT = 1030;
  3. Compiler your code and download to your mBed device.
  4. Control your mBed device
    1. Please use NORDSemi nRF Tool and setup and watch these information: GATT CMD: 0x00 (connect to AP, TCP Server, and create TCP socket), 0x02 disconnection TCP server, close socket, and WiFi sleep), 0xA1 (send sensor data to tcp server from out_buffer[]) and Status will be update by Bluetooth LE adv through manufacturing information
0x000x020xA1
WiFi,AP&TCP Server connectWiFi,AP, & TCP Server disconnectSend sensor data to TCP Server

main.cpp

Committer:
sog_yang
Date:
2017-05-06
Revision:
10:248b81efda00
Parent:
9:d1861b00e0fd
Child:
11:54a1a576df9f

File content as of revision 10:248b81efda00:

#include "mbed.h"
#include "BNO055.h"
#include "AS7000.h"
#include "ble/BLE.h"
#include "ble/Gap.h"
#include "ble/services/BatteryService.h"
#include "DOORService.h"
#include "EthernetInterface.h"
#include "WIFIDevice.h"

#define DEBUG_LOG 0

union IP {
    unsigned int ip;
    struct {
      unsigned char d;
      unsigned char c;
      unsigned char b;
      unsigned char a;
    } ip2;
};

char  ips[20];
IP ip;

DOORService *doorServicePtr;

BNO055 imu(p0,p30);
AS7000 hrm(p0,p30);
Serial pc(USBTX, USBRX);
DigitalInOut myOutputPin(USBTX);
EthernetInterface eth;
WIFIDevice wifi;

TCPSocketConnection sock_tcp;
char* ECHO_SERVER_ADDRESS = "10.0.1.13";
//char* ECHO_SERVER_ADDRESS = "192.168.1.7";
int ECHO_SERVER_PORT = 1030;

uint8_t initialValueForDOORCharacteristic = 0xFF;
uint8_t BLE_RX_CMD = 0xFF;
const char DEVICE_NAME[] = "FITNCTL";
uint8_t ADV_manuf[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
char     out_buffer[45];
static EventQueue eventQueue(
    /* event count */ 16 * /* event size */ 32
);

 bool isConnect = false;
 bool isWiFiEnable = false;
 bool isCloudFiling = false;


void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    BLE::Instance().gap().startAdvertising();
}

void onDataWrittenCallback(const GattWriteCallbackParams *params) {
    
    
    if ((params->handle == doorServicePtr->getValueHandle()) && (params->len == 1)) {
        {
            BLE_RX_CMD = *(params->data);                   
        }
    }
}

/**
 * This function is called when the ble initialization process has failled
 */
void onBleInitError(BLE &ble, ble_error_t error)
{
    /* Initialization error handling should go here */
}

/**
 * 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) {
        /* In case of error, forward the error handling to onBleInitError */
        onBleInitError(ble, error);
        return;
    }

    /* Ensure that it is the default instance of BLE */
    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
        return;
    }

    ble.gap().onDisconnection(disconnectionCallback);
    ble.gattServer().onDataWritten(onDataWrittenCallback);
    
    /* Setup primary services */  
    doorServicePtr = new DOORService(ble, initialValueForDOORCharacteristic);

    /* Setup advertising */
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ADV_manuf, sizeof(ADV_manuf));
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.gap().setAdvertisingInterval(150); /* 1000ms */
    ble.gap().startAdvertising();
}

void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
    BLE &ble = BLE::Instance();
    eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
}


int main (void) {
    myOutputPin.mode(PullUp); 
    pc.baud(38400);    
    hrm.enable(); 
    imu.reset();    
    imu.setmode(OPERATION_MODE_NDOF);
    
    
    BLE &ble = BLE::Instance();
    ble.onEventsToProcess(scheduleBleEventsProcessing);
    ble.init(bleInitComplete);
    
    int i = 0;
    int j = 0;
    BLE_RX_CMD = 0xFF;
    wait_ms(10);
    sprintf(out_buffer,"\r\n");
    
    
    while (true) {
        wait_ms(2);
        imu.get_angles(); //query the i2c device
        hrm.hr_only();
        wait_ms(8);
        if (BLE_RX_CMD != 0xA1) {
            if (i > 40){
                pc.printf("*HR=%03d#", hrm.hrm.hreat_rate);
                i=0;
            } i++;
        }
        /* GATT Command 0xA1 Cloud Data Transfer*/
        if (BLE_RX_CMD == 0xA1){
            ADV_manuf[5] = 0xF1; 
            if (isWiFiEnable == true){                 
                if (isConnect == true) {                   
                    if (j > 2){
                        pc.printf("*HR=%03d#", hrm.hrm.hreat_rate);
                        j = 0;
                    }j++;                 
                    sprintf(out_buffer,"hrm:%03d yaw:%6.2f pitch:%6.2f roll:%6.2f\n", hrm.hrm.hreat_rate, imu.euler.yaw, imu.euler.pitch, imu.euler.roll);
                    sock_tcp.send_all(out_buffer, sizeof(out_buffer) - 1);  
                    sock_tcp.set_blocking(false, 200);// Timeout after 0.2s
                     isCloudFiling = true;
                } else {
                    if (sock_tcp.connect(ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT) < 0) {
                        isConnect = false;
                        BLE_RX_CMD = 0xFF;
#if DEBUG_LOG                        
                        pc.printf("Unable to connect to (%s) on port (%d)\n", ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT);
#endif                        
                        ADV_manuf[4] = 0xCF;
                        BLE_RX_CMD = 0xFF;
                    } else {
                         isConnect = true; 
                          ADV_manuf[4] = 0xF1;
#if DEBUG_LOG                           
                         pc.printf("Connected to Server at %s\n",ECHO_SERVER_ADDRESS);
#endif                         
                    }
                }
            }
        }
        /* GATT Command 0x02 WiFI & Cloud Connection Close*/
         if (BLE_RX_CMD == 0x02){
            BLE_RX_CMD = 0xFF;
            ADV_manuf[5] = 0xF2;  
            if ( isConnect == true ) {
                sock_tcp.close(); 
                isConnect = false;                                
            }
            if ( isWiFiEnable == true ) {
                eth.disconnect();                              
                wifi.sleep();
                isWiFiEnable = false;
            } 
            while(true) {
                    if (wifi.is_AP_connected()==0) break; //make sure wifi disconnect
            }
            if (isConnect == true) isConnect = false;   
            isConnect = false;
            isWiFiEnable = false;
            isCloudFiling = false;      
             
            ADV_manuf[0] = 0x00;
            ADV_manuf[1] = 0x00;
            ADV_manuf[2] = 0x00;
            ADV_manuf[3] = 0x00;
            ADV_manuf[4] = 0x00;
            sprintf(out_buffer,"\n");         
        }
        /* GATT Command 0x0 init WiFI & Cloud Connection*/ 
       if (BLE_RX_CMD == 0x00){
        if(isCloudFiling == false) {
            BLE_RX_CMD = 0xFF;
            ADV_manuf[5] = 0xF0; 
            
            if (isWiFiEnable == false) {
                eth.init();  
                wifi.setNetwork(M2M_WIFI_SEC_WPA_PSK, "SOG", "0227322327");
                //wifi.setNetwork(M2M_WIFI_SEC_WPA_PSK, "netis_2.4G_cybing", "11223344"); 
                eth.connect(); 
                while(true) {
                    if (wifi.is_AP_connected()==1) break;
                }
                sock_tcp.set_blocking(false, 1200);// Timeout after 1.2s 
#if DEBUG_LOG               
                pc.printf("Connect Success! \n");
                pc.printf("MAC: %s\n", eth.getMACAddress());            
                pc.printf("IP: %s\n", eth.getIPAddress());
                pc.printf("Gateway: %s\n", eth.getGateway());
                pc.printf("NetworkMask: %s\n", eth.getNetworkMask()); 
#endif            
                snprintf(ips, sizeof(ips), "%s",eth.getIPAddress());    
                unsigned short a, b, c, d;
                sscanf(ips, "%hu.%hu.%hu.%hu", &a, &b, &c, &d);    
                sprintf(ips, "%x.%x.%x.%x", a, b, c, d);
                ADV_manuf[0] = a;
                ADV_manuf[1] = b;
                ADV_manuf[2] = c;
                ADV_manuf[3] = d; 
                isWiFiEnable = true; 
            } 
            
            if (isConnect == false) {
                if (isWiFiEnable == true) {
                    if (sock_tcp.connect(ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT) < 0) {
#if DEBUG_LOG                         
                            pc.printf("Unable to connect to (%s) on port (%d)\n", ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT);
#endif                         
                            sock_tcp.close();
                            ADV_manuf[4] = 0xCF;
                        } else {
                             isConnect = true;
                             isCloudFiling = false;
                             ADV_manuf[4] = 0xF1;
#if DEBUG_LOG                          
                             pc.printf("Connected to Server at %s\n",ECHO_SERVER_ADDRESS);
#endif     
                        }
                    }  
                }
            }    
       }
       BLE::Instance(BLE::DEFAULT_INSTANCE).gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ADV_manuf, sizeof(ADV_manuf));
       ble.waitForEvent();    
    }
}