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.

Revision:
0:6a77043d1ee1
Child:
1:f355c8472bdf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Jan 25 13:27:13 2018 +0100
@@ -0,0 +1,250 @@
+/* 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"
+
+/* specific SensorTile serial on UART_5. To redirect STDIO_UART on UART_5 it needs to modify the baseport on PeripheralNames.h file */
+Serial pc(PC_12, PD_2);  
+#define printf(...) pc.printf(__VA_ARGS__)
+
+#ifndef SPI3W_SUPPORT
+//#define SPI3W_SUPPORT
+#endif
+#ifndef SPI3W_TEST
+//#define SPI3W_TEST
+#endif
+/*
+0x58 	Temperature
+T 	signed value from -20 to +40 celsius
+0xA8 	Humidity
+H 	not used,
+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
+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 	not used
+P   not used
+*/	
+
+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					
+
+
+BLE &ble = BLE::Instance();
+uint8_t uuid[] = { 0x19, 0x10, 0x58, 0x18, 0xA8, 0x00, 0x18, 0x01, 0x00, 0x99, 0x38, 0x01, 0x17, 0x47, 0x28, 0xE1, 0x03, 0x0D, 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;
+	
+	/*
+	BLEProtocol::AddressType_t addr_type;
+	uint8_t adr[6] = { 0x00, 0x0B, 0x57, 0x00, 0xDF, 0x27 };
+	BLEProtocol::AddressBytes_t address;
+
+    address[0] = 0x00;
+    address[1] = 0x0B;
+    address[2] = 0x57;
+    address[3] = 0x00;
+    address[4] = 0xDF;
+    address[5] = 0x27;
+*/
+    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().getAddress(&addr_type, adr);
+	printf( "addrtype> %d, ret = %d\n", addr_type, ble.gap().setAddress(BLEProtocol::AddressType::PUBLIC, address) );
+	*/
+    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));
+}
+
+/* Helper function for printing floats & doubles */
+static char *print_double(char* str, double v, int decimalDigits=2)
+{
+  int i = 1;
+  int intPart, fractPart;
+  int len;
+  char *ptr;
+
+  /* prepare decimal digits multiplicator */
+  for (;decimalDigits!=0; i*=10, decimalDigits--);
+
+  /* calculate integer & fractinal parts */
+  intPart = (int)v;
+  fractPart = (int)((v-(double)(int)v)*i);
+
+  /* fill in integer part */
+  sprintf(str, "%i.", intPart);
+
+  /* prepare fill in of fractional part */
+  len = strlen(str);
+  ptr = &str[len];
+
+  /* fill in leading fractional zeros */
+  for (i/=10;i>1; i/=10, ptr++) {
+    if (fractPart >= i) {
+      break;
+    }
+    *ptr = '0';
+  }
+
+  /* fill in (rest of) fractional part */
+  sprintf(ptr, "%i", fractPart);
+
+  return str;
+}
+
+void readSensors(void)
+{
+  float temp, press;
+  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);
+  //printf("LPS22HB: [temp] %7s C, [press] %s mbar\r\n", print_double(buffer1, value1), print_double(buffer2, value2));
+
+  mag.get_m_axes(mag_axes);
+  uuid[11] = (int8_t)mag_axes[0];
+  uuid[12] = (int8_t)mag_axes[1];
+  uuid[13] = (int8_t)mag_axes[2];
+  //printf("LSM303AGR [mag/mgauss]:  %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
+
+  acc.get_x_axes(acc_axes);
+  uuid[7] = (int8_t)acc_axes[0];
+  uuid[8] = (int8_t)acc_axes[1];
+  uuid[9] = (int8_t)acc_axes[2];
+  //printf("LSM303AGR [acc/mg]:  %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
+
+  //acc_gyro.get_x_axes(axes);
+  //printf("LSM6DSL [acc/mg]:      %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
+
+  acc_gyro.get_g_axes(gyr_axes);
+  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", axes[0], axes[1], axes[2]);
+}
+
+void getDataSensors( void )
+{
+	ble.gap().stopAdvertising();
+	readSensors();
+	advGatewayPtr->updatePayload( uuid );
+	ble.gap().startAdvertising();
+}
+
+int main()
+{
+  press_temp.enable();	
+				
+  acc_gyro.enable_x();
+  acc_gyro.enable_g();	
+  /* Enable Free Fall Detection. */
+  acc_gyro.enable_free_fall_detection(LSM6DSL_INT2_PIN); 	
+  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);
+
+  printf("LS303acc ID %x LS303mag ID %x LSM6DSL ID %x LPS22HB ID %x \r\n", id303acc, id303mag, idLSM6, id22);	  
+  printf("\r\n");  
+  
+  
+  
+	
+	eventQueue.call_every( 500, getDataSensors );
+    ble.onEventsToProcess(scheduleBleEventsProcessing);
+    ble.init(bleInitComplete);
+
+    eventQueue.dispatch_forever();
+
+    return 0;
+}