Silica Sensor Node board sends custom ble advertising for the Gateway board

Dependencies:   X_NUCLEO_IKS01A2_SPI3W

Fork of sensor-node-ble by Roberto Spelta

Getting started with mbed SensorNode BLE

Information

History project:

  • 26/01/2017 - First Release

This project uses the Bluetooth Low Energy in order to send advertaisments every second. These payloads are read by the Visible Things Gateway board, more about it here . Every advertaisments contains sensors data read form the SensorTile and the Silica Sensor Board. For details please read the document in the MAN folder,

The application:

  • reads sensors data (accelerometer, gyroscope, lux, pressure, temperature, proximity, magnetometer)
  • send these data by BLE

You can compile this project in three ways:

1. Using the Online compiler.

Information

Learn how to use the Online compiler reading https://docs.mbed.com/docs/mbed-os-handbook/en/latest/dev_tools/online_comp/ page.

2. Using the compiler on your PC

Information

Learn how to use the mbed-cli reading https://docs.mbed.com/docs/mbed-os-handbook/en/latest/dev_tools/cli/ page.
The name of the machine is SILICA_SENSOR_NODE.

3. Exporting to 3rd party tools (IDE)

Information

Learn how to use the mbed-cli reading https://docs.mbed.com/docs/mbed-os-handbook/en/latest/dev_tools/third_party/ page. We have exported the project for you, please read here

Warning

This example requires a Visible Things Gateway board. If you don't have this board you can use RF Connect app from an Android phone just to see the raw data sent from the SensorNode.

main.cpp

Committer:
rspelta
Date:
2018-01-26
Revision:
5:26b07c500aa2
Parent:
3:94aee6f716b7

File content as of revision 5:26b07c500aa2:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2015 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.	
 */

#include <events/mbed_events.h>
#include <mbed.h>
#include "ble/BLE.h"
#include "ble/Gap.h"
#include "ble/services/advGateway.h"

#include "LPS22HBSensor.h"
#include "LSM6DSLSensor.h"
#include "LSM303AGRMagSensor.h"
#include "LSM303AGRAccSensor.h"
#include "SPI3W.h"
#include "VL6180X.h"

#define VERSION_SW "1.0"

SPI3W sens_intf(PB_15, NC, PB_13); 						// 3W mosi, sclk on Nucleo L476 same as BTLE
LPS22HBSensor press_temp(&sens_intf, PA_3);	 			// on SensorTile L476JG
LSM6DSLSensor acc_gyro(&sens_intf, PB_12, NC, PA_2 );	// on SensorTile L476JG  
LSM303AGRMagSensor mag(&sens_intf, PB_1 ); 				//on SensorTile L476JG				  
LSM303AGRAccSensor acc(&sens_intf, PC_4 ); 				//on SensorTile L476JG		
I2C _i2c(I2C_SDA, I2C_SCL);
VL6180x sensor(&_i2c, VL6180X_ADDRESS);					//on Sensor VL6180X
		
BLE &ble = BLE::Instance();

/* FORMAT
0x19, 0x10 CompanyID
0x58 	Temperature
T 	signed value from -20 to +40 celsius
0xB8 	Pressure
H 	2’complement value in units of 1mbar
0x18 	Accelerometer
X 	2’complement value in units of 0.01g
Y 	2’complement value in units of 0.01g
Z 	2’complement value in units of 0.01g
0x38 	Magnetometer
X 	2’ complement value in units of 10-6T
Y 	2’ complement value in units of 10-6T
Z 	2’ complement value in units of 10-6T
0x28 	Gyroscope (it is not showed on the gateway)
X 	2’ complement value in units od 0.1deg/s
Y 	2’ complement value in units od 0.1deg/s
Z 	2’ complement value in units od 0.1deg/s
0x48 	Ambient light & Proximity
A 	units ok klux
P   mm
*/	
uint8_t uuid[] = { 0x19, 0x10, 0x58, 0x00, 0xBB, 0x00, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00};

static advGateway* advGatewayPtr;

static EventQueue eventQueue(/* event count */ 4 * EVENTS_EVENT_SIZE);

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

void printMacAddress()
{
    /* Print out device MAC address to the console*/
    Gap::AddressType_t addr_type;
    Gap::Address_t address;
	BLE::Instance().gap().getAddress(&addr_type, address);
    printf("DEVICE MAC ADDRESS: ");
    for (int i = 5; i >= 1; i--){
        printf("%02x:", address[i]);
    }
    printf("%02x\r\n", address[0]);
}

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

    advGatewayPtr = new advGateway(ble, uuid);

    ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
    ble.gap().startAdvertising();

    printMacAddress();
}

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

void readSensors(void)
{
  float temp, press, lux, prox;
  int32_t mag_axes[3], acc_axes[3], gyr_axes[3];	
  
  press_temp.get_temperature(&temp);
  uuid[3] = (int8_t)temp;

  press_temp.get_pressure(&press);
  uuid[5] = (int8_t)(press/8);
  //printf("LPS22HB: [temp] %7f C, [press] %f mbar\r\n", temp, press);

  mag.get_m_axes(mag_axes);
  uuid[11] = (int8_t)((mag_axes[0]*1.5)/10);
  uuid[12] = (int8_t)((mag_axes[1]*1.5)/10);
  uuid[13] = (int8_t)((mag_axes[2]*1.5)/10);
  //printf("LSM303AGR [mag/mgauss]:  %d, %d, %d\r\n", uuid[11], uuid[12], uuid[13]);  //*1.5=1mG

  acc_gyro.get_x_axes(acc_axes);
  uuid[7] = (int8_t)((acc_axes[0]*100)/1024);
  uuid[8] = (int8_t)((acc_axes[1]*100)/1024);
  uuid[9] = (int8_t)((acc_axes[2]*100)/1024);
  //printf("LSM6DSL [acc/mg]:      %02x, %02x, %02x\r\n", acc_axes[0], acc_axes[1],acc_axes[2]);  // 1024 = 1G

  acc_gyro.get_g_axes(gyr_axes); // not used by the gateway
  uuid[15] = (int8_t)gyr_axes[0];
  uuid[16] = (int8_t)gyr_axes[1];
  uuid[17] = (int8_t)gyr_axes[2];
  //printf("LSM6DSL [gyro/mdps]:   %6ld, %6ld, %6ld\r\n", uuid[15], uuid[16], uuid[17]);
  
  lux = sensor.getAmbientLight(GAIN_1);
  prox = sensor.getDistance();
  uuid[19] =  (int8_t)(lux/10);
  // uuid[20] = (int8_t)prox;  not used, mm unit
}

void getDataSensors( void )
{
	ble.gap().stopAdvertising();
	readSensors();
	advGatewayPtr->updatePayload( uuid );
	ble.gap().startAdvertising();
}

int main()
{
  VL6180xIdentification identification;
	
  printf("Silica Sensor Node BLE v%s\n\r", VERSION_SW);

  sensor.VL6180xInit();
  sensor.VL6180xDefautSettings(); //Load default settings to get started.

  press_temp.enable();
				
  acc_gyro.enable_x();
  acc_gyro.enable_g();	
  mag.enable();	
  acc.enable();
	
  uint8_t id22=0, idLSM6=0, id303mag=0, id303acc=0;
  press_temp.read_id(&id22);
  acc_gyro.read_id(&idLSM6);				
  mag.read_id(&id303mag);
  acc.read_id(&id303acc);
  sensor.getIdentification(&identification);

  printf("LS303acc ID %x LS303mag ID %x LSM6DSL ID %x LPS22HB ID %x VL6180x ID %x\r\n", id303acc, id303mag, idLSM6, id22, identification.idModel);	  
  
  eventQueue.call_every( 500, getDataSensors );
  ble.onEventsToProcess(scheduleBleEventsProcessing);
  ble.init(bleInitComplete);

  eventQueue.dispatch_forever();

  return 0;
}