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.

Committer:
rspelta
Date:
Fri Jan 26 18:19:41 2018 +0100
Revision:
3:94aee6f716b7
Parent:
2:934cd97bfe1a
Child:
5:26b07c500aa2
added VL6180 sensor, lux and proximity

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rspelta 0:6a77043d1ee1 1 /* mbed Microcontroller Library
rspelta 0:6a77043d1ee1 2 * Copyright (c) 2006-2015 ARM Limited
rspelta 0:6a77043d1ee1 3 *
rspelta 0:6a77043d1ee1 4 * Licensed under the Apache License, Version 2.0 (the "License");
rspelta 0:6a77043d1ee1 5 * you may not use this file except in compliance with the License.
rspelta 0:6a77043d1ee1 6 * You may obtain a copy of the License at
rspelta 0:6a77043d1ee1 7 *
rspelta 0:6a77043d1ee1 8 * http://www.apache.org/licenses/LICENSE-2.0
rspelta 0:6a77043d1ee1 9 *
rspelta 0:6a77043d1ee1 10 * Unless required by applicable law or agreed to in writing, software
rspelta 0:6a77043d1ee1 11 * distributed under the License is distributed on an "AS IS" BASIS,
rspelta 0:6a77043d1ee1 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rspelta 0:6a77043d1ee1 13 * See the License for the specific language governing permissions and
rspelta 0:6a77043d1ee1 14 * limitations under the License.
rspelta 0:6a77043d1ee1 15 */
rspelta 0:6a77043d1ee1 16
rspelta 0:6a77043d1ee1 17 #include <events/mbed_events.h>
rspelta 0:6a77043d1ee1 18 #include <mbed.h>
rspelta 0:6a77043d1ee1 19 #include "ble/BLE.h"
rspelta 0:6a77043d1ee1 20 #include "ble/Gap.h"
rspelta 0:6a77043d1ee1 21 #include "ble/services/advGateway.h"
rspelta 0:6a77043d1ee1 22
rspelta 0:6a77043d1ee1 23 #include "LPS22HBSensor.h"
rspelta 0:6a77043d1ee1 24 #include "LSM6DSLSensor.h"
rspelta 0:6a77043d1ee1 25 #include "LSM303AGRMagSensor.h"
rspelta 0:6a77043d1ee1 26 #include "LSM303AGRAccSensor.h"
rspelta 0:6a77043d1ee1 27 #include "SPI3W.h"
rspelta 3:94aee6f716b7 28 #include "VL6180X.h"
rspelta 3:94aee6f716b7 29
rspelta 0:6a77043d1ee1 30
rspelta 0:6a77043d1ee1 31 /* specific SensorTile serial on UART_5. To redirect STDIO_UART on UART_5 it needs to modify the baseport on PeripheralNames.h file */
rspelta 3:94aee6f716b7 32 //Serial pc(PC_12, PD_2);
rspelta 3:94aee6f716b7 33 //#define printf(...) pc.printf(__VA_ARGS__)
rspelta 0:6a77043d1ee1 34
rspelta 3:94aee6f716b7 35 #define VERSION_SW "1.0"
rspelta 1:f355c8472bdf 36
rspelta 1:f355c8472bdf 37 SPI3W sens_intf(PB_15, NC, PB_13); // 3W mosi, sclk on Nucleo L476 same as BTLE
rspelta 1:f355c8472bdf 38 LPS22HBSensor press_temp(&sens_intf, PA_3); // on SensorTile L476JG
rspelta 1:f355c8472bdf 39 LSM6DSLSensor acc_gyro(&sens_intf, PB_12, NC, PA_2 ); // on SensorTile L476JG
rspelta 1:f355c8472bdf 40 LSM303AGRMagSensor mag(&sens_intf, PB_1 ); //on SensorTile L476JG
rspelta 3:94aee6f716b7 41 LSM303AGRAccSensor acc(&sens_intf, PC_4 ); //on SensorTile L476JG
rspelta 3:94aee6f716b7 42 I2C _i2c(I2C_SDA, I2C_SCL);
rspelta 3:94aee6f716b7 43 VL6180x sensor(&_i2c, VL6180X_ADDRESS); //on Sensor VL6180X
rspelta 3:94aee6f716b7 44
rspelta 1:f355c8472bdf 45 BLE &ble = BLE::Instance();
rspelta 1:f355c8472bdf 46
rspelta 1:f355c8472bdf 47 /* FORMAT
rspelta 1:f355c8472bdf 48 0x19, 0x10 CompanyID
rspelta 0:6a77043d1ee1 49 0x58 Temperature
rspelta 0:6a77043d1ee1 50 T signed value from -20 to +40 celsius
rspelta 2:934cd97bfe1a 51 0xB8 Pressure
rspelta 3:94aee6f716b7 52 H 2’complement value in units of 1mbar
rspelta 0:6a77043d1ee1 53 0x18 Accelerometer
rspelta 0:6a77043d1ee1 54 X 2’complement value in units of 0.01g
rspelta 0:6a77043d1ee1 55 Y 2’complement value in units of 0.01g
rspelta 0:6a77043d1ee1 56 Z 2’complement value in units of 0.01g
rspelta 0:6a77043d1ee1 57 0x38 Magnetometer
rspelta 0:6a77043d1ee1 58 X 2’ complement value in units of 10-6T
rspelta 0:6a77043d1ee1 59 Y 2’ complement value in units of 10-6T
rspelta 0:6a77043d1ee1 60 Z 2’ complement value in units of 10-6T
rspelta 1:f355c8472bdf 61 0x28 Gyroscope (it is not showed on the gateway)
rspelta 0:6a77043d1ee1 62 X 2’ complement value in units od 0.1deg/s
rspelta 0:6a77043d1ee1 63 Y 2’ complement value in units od 0.1deg/s
rspelta 0:6a77043d1ee1 64 Z 2’ complement value in units od 0.1deg/s
rspelta 0:6a77043d1ee1 65 0x48 Ambient light & Proximity
rspelta 3:94aee6f716b7 66 A units ok klux
rspelta 3:94aee6f716b7 67 P mm
rspelta 0:6a77043d1ee1 68 */
rspelta 2:934cd97bfe1a 69 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};
rspelta 0:6a77043d1ee1 70
rspelta 0:6a77043d1ee1 71 static advGateway* advGatewayPtr;
rspelta 0:6a77043d1ee1 72
rspelta 0:6a77043d1ee1 73 static EventQueue eventQueue(/* event count */ 4 * EVENTS_EVENT_SIZE);
rspelta 0:6a77043d1ee1 74
rspelta 0:6a77043d1ee1 75 /**
rspelta 0:6a77043d1ee1 76 * This function is called when the ble initialization process has failled
rspelta 0:6a77043d1ee1 77 */
rspelta 0:6a77043d1ee1 78 void onBleInitError(BLE &ble, ble_error_t error)
rspelta 0:6a77043d1ee1 79 {
rspelta 0:6a77043d1ee1 80 /* Initialization error handling should go here */
rspelta 0:6a77043d1ee1 81 }
rspelta 0:6a77043d1ee1 82
rspelta 0:6a77043d1ee1 83 void printMacAddress()
rspelta 0:6a77043d1ee1 84 {
rspelta 0:6a77043d1ee1 85 /* Print out device MAC address to the console*/
rspelta 0:6a77043d1ee1 86 Gap::AddressType_t addr_type;
rspelta 0:6a77043d1ee1 87 Gap::Address_t address;
rspelta 0:6a77043d1ee1 88 BLE::Instance().gap().getAddress(&addr_type, address);
rspelta 0:6a77043d1ee1 89 printf("DEVICE MAC ADDRESS: ");
rspelta 0:6a77043d1ee1 90 for (int i = 5; i >= 1; i--){
rspelta 0:6a77043d1ee1 91 printf("%02x:", address[i]);
rspelta 0:6a77043d1ee1 92 }
rspelta 0:6a77043d1ee1 93 printf("%02x\r\n", address[0]);
rspelta 0:6a77043d1ee1 94 }
rspelta 0:6a77043d1ee1 95
rspelta 0:6a77043d1ee1 96 /**
rspelta 0:6a77043d1ee1 97 * Callback triggered when the ble initialization process has finished
rspelta 0:6a77043d1ee1 98 */
rspelta 0:6a77043d1ee1 99 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
rspelta 0:6a77043d1ee1 100 {
rspelta 0:6a77043d1ee1 101 BLE& ble = params->ble;
rspelta 0:6a77043d1ee1 102 ble_error_t error = params->error;
rspelta 0:6a77043d1ee1 103
rspelta 0:6a77043d1ee1 104 if (error != BLE_ERROR_NONE) {
rspelta 0:6a77043d1ee1 105 /* In case of error, forward the error handling to onBleInitError */
rspelta 0:6a77043d1ee1 106 onBleInitError(ble, error);
rspelta 0:6a77043d1ee1 107 return;
rspelta 0:6a77043d1ee1 108 }
rspelta 0:6a77043d1ee1 109
rspelta 0:6a77043d1ee1 110 /* Ensure that it is the default instance of BLE */
rspelta 0:6a77043d1ee1 111 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
rspelta 0:6a77043d1ee1 112 return;
rspelta 0:6a77043d1ee1 113 }
rspelta 0:6a77043d1ee1 114
rspelta 0:6a77043d1ee1 115 advGatewayPtr = new advGateway(ble, uuid);
rspelta 1:f355c8472bdf 116
rspelta 0:6a77043d1ee1 117 ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
rspelta 0:6a77043d1ee1 118 ble.gap().startAdvertising();
rspelta 0:6a77043d1ee1 119
rspelta 0:6a77043d1ee1 120 printMacAddress();
rspelta 0:6a77043d1ee1 121 }
rspelta 0:6a77043d1ee1 122
rspelta 0:6a77043d1ee1 123 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
rspelta 0:6a77043d1ee1 124 BLE &ble = BLE::Instance();
rspelta 0:6a77043d1ee1 125 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
rspelta 0:6a77043d1ee1 126 }
rspelta 0:6a77043d1ee1 127
rspelta 0:6a77043d1ee1 128 void readSensors(void)
rspelta 0:6a77043d1ee1 129 {
rspelta 3:94aee6f716b7 130 float temp, press, lux, prox;
rspelta 0:6a77043d1ee1 131 int32_t mag_axes[3], acc_axes[3], gyr_axes[3];
rspelta 0:6a77043d1ee1 132
rspelta 0:6a77043d1ee1 133 press_temp.get_temperature(&temp);
rspelta 0:6a77043d1ee1 134 uuid[3] = (int8_t)temp;
rspelta 0:6a77043d1ee1 135
rspelta 2:934cd97bfe1a 136 press_temp.get_pressure(&press);
rspelta 2:934cd97bfe1a 137 uuid[5] = (int8_t)(press/8);
rspelta 2:934cd97bfe1a 138 //printf("LPS22HB: [temp] %7f C, [press] %f mbar\r\n", temp, press);
rspelta 0:6a77043d1ee1 139
rspelta 0:6a77043d1ee1 140 mag.get_m_axes(mag_axes);
rspelta 1:f355c8472bdf 141 uuid[11] = (int8_t)((mag_axes[0]*1.5)/10);
rspelta 1:f355c8472bdf 142 uuid[12] = (int8_t)((mag_axes[1]*1.5)/10);
rspelta 1:f355c8472bdf 143 uuid[13] = (int8_t)((mag_axes[2]*1.5)/10);
rspelta 1:f355c8472bdf 144 //printf("LSM303AGR [mag/mgauss]: %d, %d, %d\r\n", uuid[11], uuid[12], uuid[13]); //*1.5=1mG
rspelta 0:6a77043d1ee1 145
rspelta 1:f355c8472bdf 146 acc_gyro.get_x_axes(acc_axes);
rspelta 1:f355c8472bdf 147 uuid[7] = (int8_t)((acc_axes[0]*100)/1024);
rspelta 1:f355c8472bdf 148 uuid[8] = (int8_t)((acc_axes[1]*100)/1024);
rspelta 1:f355c8472bdf 149 uuid[9] = (int8_t)((acc_axes[2]*100)/1024);
rspelta 1:f355c8472bdf 150 //printf("LSM6DSL [acc/mg]: %02x, %02x, %02x\r\n", acc_axes[0], acc_axes[1],acc_axes[2]); // 1024 = 1G
rspelta 0:6a77043d1ee1 151
rspelta 1:f355c8472bdf 152 acc_gyro.get_g_axes(gyr_axes); // not used by the gateway
rspelta 0:6a77043d1ee1 153 uuid[15] = (int8_t)gyr_axes[0];
rspelta 0:6a77043d1ee1 154 uuid[16] = (int8_t)gyr_axes[1];
rspelta 0:6a77043d1ee1 155 uuid[17] = (int8_t)gyr_axes[2];
rspelta 1:f355c8472bdf 156 //printf("LSM6DSL [gyro/mdps]: %6ld, %6ld, %6ld\r\n", uuid[15], uuid[16], uuid[17]);
rspelta 3:94aee6f716b7 157
rspelta 3:94aee6f716b7 158 lux = sensor.getAmbientLight(GAIN_1);
rspelta 3:94aee6f716b7 159 prox = sensor.getDistance();
rspelta 3:94aee6f716b7 160 uuid[19] = (int8_t)(lux/10);
rspelta 3:94aee6f716b7 161 // uuid[20] = (int8_t)prox; not used, mm unit
rspelta 0:6a77043d1ee1 162 }
rspelta 0:6a77043d1ee1 163
rspelta 0:6a77043d1ee1 164 void getDataSensors( void )
rspelta 0:6a77043d1ee1 165 {
rspelta 0:6a77043d1ee1 166 ble.gap().stopAdvertising();
rspelta 0:6a77043d1ee1 167 readSensors();
rspelta 0:6a77043d1ee1 168 advGatewayPtr->updatePayload( uuid );
rspelta 0:6a77043d1ee1 169 ble.gap().startAdvertising();
rspelta 0:6a77043d1ee1 170 }
rspelta 0:6a77043d1ee1 171
rspelta 0:6a77043d1ee1 172 int main()
rspelta 0:6a77043d1ee1 173 {
rspelta 3:94aee6f716b7 174 VL6180xIdentification identification;
rspelta 3:94aee6f716b7 175
rspelta 3:94aee6f716b7 176 printf("Silica Sensor Node BLE v%s\n\r", VERSION_SW);
rspelta 3:94aee6f716b7 177
rspelta 3:94aee6f716b7 178 sensor.VL6180xInit();
rspelta 3:94aee6f716b7 179 sensor.VL6180xDefautSettings(); //Load default settings to get started.
rspelta 3:94aee6f716b7 180
rspelta 3:94aee6f716b7 181 press_temp.enable();
rspelta 0:6a77043d1ee1 182
rspelta 0:6a77043d1ee1 183 acc_gyro.enable_x();
rspelta 0:6a77043d1ee1 184 acc_gyro.enable_g();
rspelta 0:6a77043d1ee1 185 /* Enable Free Fall Detection. */
rspelta 1:f355c8472bdf 186 //acc_gyro.enable_free_fall_detection(LSM6DSL_INT2_PIN);
rspelta 0:6a77043d1ee1 187 mag.enable();
rspelta 0:6a77043d1ee1 188 acc.enable();
rspelta 0:6a77043d1ee1 189
rspelta 0:6a77043d1ee1 190 uint8_t id22=0, idLSM6=0, id303mag=0, id303acc=0;
rspelta 0:6a77043d1ee1 191 press_temp.read_id(&id22);
rspelta 0:6a77043d1ee1 192 acc_gyro.read_id(&idLSM6);
rspelta 0:6a77043d1ee1 193 mag.read_id(&id303mag);
rspelta 0:6a77043d1ee1 194 acc.read_id(&id303acc);
rspelta 3:94aee6f716b7 195 sensor.getIdentification(&identification);
rspelta 0:6a77043d1ee1 196
rspelta 3:94aee6f716b7 197 printf("LS303acc ID %x LS303mag ID %x LSM6DSL ID %x LPS22HB ID %x VL6180x ID %x\r\n", id303acc, id303mag, idLSM6, id22, identification.idModel);
rspelta 0:6a77043d1ee1 198 printf("\r\n");
rspelta 0:6a77043d1ee1 199
rspelta 1:f355c8472bdf 200 eventQueue.call_every( 500, getDataSensors );
rspelta 1:f355c8472bdf 201 ble.onEventsToProcess(scheduleBleEventsProcessing);
rspelta 1:f355c8472bdf 202 ble.init(bleInitComplete);
rspelta 0:6a77043d1ee1 203
rspelta 1:f355c8472bdf 204 eventQueue.dispatch_forever();
rspelta 0:6a77043d1ee1 205
rspelta 1:f355c8472bdf 206 return 0;
rspelta 0:6a77043d1ee1 207 }