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:
Thu Jan 25 13:27:13 2018 +0100
Revision:
0:6a77043d1ee1
Child:
1:f355c8472bdf
alpha version

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 0:6a77043d1ee1 28
rspelta 0:6a77043d1ee1 29 /* specific SensorTile serial on UART_5. To redirect STDIO_UART on UART_5 it needs to modify the baseport on PeripheralNames.h file */
rspelta 0:6a77043d1ee1 30 Serial pc(PC_12, PD_2);
rspelta 0:6a77043d1ee1 31 #define printf(...) pc.printf(__VA_ARGS__)
rspelta 0:6a77043d1ee1 32
rspelta 0:6a77043d1ee1 33 #ifndef SPI3W_SUPPORT
rspelta 0:6a77043d1ee1 34 //#define SPI3W_SUPPORT
rspelta 0:6a77043d1ee1 35 #endif
rspelta 0:6a77043d1ee1 36 #ifndef SPI3W_TEST
rspelta 0:6a77043d1ee1 37 //#define SPI3W_TEST
rspelta 0:6a77043d1ee1 38 #endif
rspelta 0:6a77043d1ee1 39 /*
rspelta 0:6a77043d1ee1 40 0x58 Temperature
rspelta 0:6a77043d1ee1 41 T signed value from -20 to +40 celsius
rspelta 0:6a77043d1ee1 42 0xA8 Humidity
rspelta 0:6a77043d1ee1 43 H not used,
rspelta 0:6a77043d1ee1 44 0x18 Accelerometer
rspelta 0:6a77043d1ee1 45 X 2’complement value in units of 0.01g
rspelta 0:6a77043d1ee1 46 Y 2’complement value in units of 0.01g
rspelta 0:6a77043d1ee1 47 Z 2’complement value in units of 0.01g
rspelta 0:6a77043d1ee1 48 0x38 Magnetometer
rspelta 0:6a77043d1ee1 49 X 2’ complement value in units of 10-6T
rspelta 0:6a77043d1ee1 50 Y 2’ complement value in units of 10-6T
rspelta 0:6a77043d1ee1 51 Z 2’ complement value in units of 10-6T
rspelta 0:6a77043d1ee1 52 0x28 Gyroscope
rspelta 0:6a77043d1ee1 53 X 2’ complement value in units od 0.1deg/s
rspelta 0:6a77043d1ee1 54 Y 2’ complement value in units od 0.1deg/s
rspelta 0:6a77043d1ee1 55 Z 2’ complement value in units od 0.1deg/s
rspelta 0:6a77043d1ee1 56 0x48 Ambient light & Proximity
rspelta 0:6a77043d1ee1 57 A not used
rspelta 0:6a77043d1ee1 58 P not used
rspelta 0:6a77043d1ee1 59 */
rspelta 0:6a77043d1ee1 60
rspelta 0:6a77043d1ee1 61 SPI3W sens_intf(PB_15, NC, PB_13); // 3W mosi, sclk on Nucleo L476 same as BTLE
rspelta 0:6a77043d1ee1 62 LPS22HBSensor press_temp(&sens_intf, PA_3); // on SensorTile L476JG
rspelta 0:6a77043d1ee1 63 LSM6DSLSensor acc_gyro(&sens_intf, PB_12, NC, PA_2 ); // on SensorTile L476JG
rspelta 0:6a77043d1ee1 64 LSM303AGRMagSensor mag(&sens_intf, PB_1 ); //on SensorTile L476JG
rspelta 0:6a77043d1ee1 65 LSM303AGRAccSensor acc(&sens_intf, PC_4 ); //on SensorTile L476JG
rspelta 0:6a77043d1ee1 66
rspelta 0:6a77043d1ee1 67
rspelta 0:6a77043d1ee1 68 BLE &ble = BLE::Instance();
rspelta 0:6a77043d1ee1 69 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};
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 /*
rspelta 0:6a77043d1ee1 105 BLEProtocol::AddressType_t addr_type;
rspelta 0:6a77043d1ee1 106 uint8_t adr[6] = { 0x00, 0x0B, 0x57, 0x00, 0xDF, 0x27 };
rspelta 0:6a77043d1ee1 107 BLEProtocol::AddressBytes_t address;
rspelta 0:6a77043d1ee1 108
rspelta 0:6a77043d1ee1 109 address[0] = 0x00;
rspelta 0:6a77043d1ee1 110 address[1] = 0x0B;
rspelta 0:6a77043d1ee1 111 address[2] = 0x57;
rspelta 0:6a77043d1ee1 112 address[3] = 0x00;
rspelta 0:6a77043d1ee1 113 address[4] = 0xDF;
rspelta 0:6a77043d1ee1 114 address[5] = 0x27;
rspelta 0:6a77043d1ee1 115 */
rspelta 0:6a77043d1ee1 116 if (error != BLE_ERROR_NONE) {
rspelta 0:6a77043d1ee1 117 /* In case of error, forward the error handling to onBleInitError */
rspelta 0:6a77043d1ee1 118 onBleInitError(ble, error);
rspelta 0:6a77043d1ee1 119 return;
rspelta 0:6a77043d1ee1 120 }
rspelta 0:6a77043d1ee1 121
rspelta 0:6a77043d1ee1 122 /* Ensure that it is the default instance of BLE */
rspelta 0:6a77043d1ee1 123 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
rspelta 0:6a77043d1ee1 124 return;
rspelta 0:6a77043d1ee1 125 }
rspelta 0:6a77043d1ee1 126
rspelta 0:6a77043d1ee1 127 advGatewayPtr = new advGateway(ble, uuid);
rspelta 0:6a77043d1ee1 128 /*
rspelta 0:6a77043d1ee1 129 ble.gap().getAddress(&addr_type, adr);
rspelta 0:6a77043d1ee1 130 printf( "addrtype> %d, ret = %d\n", addr_type, ble.gap().setAddress(BLEProtocol::AddressType::PUBLIC, address) );
rspelta 0:6a77043d1ee1 131 */
rspelta 0:6a77043d1ee1 132 ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
rspelta 0:6a77043d1ee1 133 ble.gap().startAdvertising();
rspelta 0:6a77043d1ee1 134
rspelta 0:6a77043d1ee1 135 printMacAddress();
rspelta 0:6a77043d1ee1 136 }
rspelta 0:6a77043d1ee1 137
rspelta 0:6a77043d1ee1 138 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
rspelta 0:6a77043d1ee1 139 BLE &ble = BLE::Instance();
rspelta 0:6a77043d1ee1 140 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
rspelta 0:6a77043d1ee1 141 }
rspelta 0:6a77043d1ee1 142
rspelta 0:6a77043d1ee1 143 /* Helper function for printing floats & doubles */
rspelta 0:6a77043d1ee1 144 static char *print_double(char* str, double v, int decimalDigits=2)
rspelta 0:6a77043d1ee1 145 {
rspelta 0:6a77043d1ee1 146 int i = 1;
rspelta 0:6a77043d1ee1 147 int intPart, fractPart;
rspelta 0:6a77043d1ee1 148 int len;
rspelta 0:6a77043d1ee1 149 char *ptr;
rspelta 0:6a77043d1ee1 150
rspelta 0:6a77043d1ee1 151 /* prepare decimal digits multiplicator */
rspelta 0:6a77043d1ee1 152 for (;decimalDigits!=0; i*=10, decimalDigits--);
rspelta 0:6a77043d1ee1 153
rspelta 0:6a77043d1ee1 154 /* calculate integer & fractinal parts */
rspelta 0:6a77043d1ee1 155 intPart = (int)v;
rspelta 0:6a77043d1ee1 156 fractPart = (int)((v-(double)(int)v)*i);
rspelta 0:6a77043d1ee1 157
rspelta 0:6a77043d1ee1 158 /* fill in integer part */
rspelta 0:6a77043d1ee1 159 sprintf(str, "%i.", intPart);
rspelta 0:6a77043d1ee1 160
rspelta 0:6a77043d1ee1 161 /* prepare fill in of fractional part */
rspelta 0:6a77043d1ee1 162 len = strlen(str);
rspelta 0:6a77043d1ee1 163 ptr = &str[len];
rspelta 0:6a77043d1ee1 164
rspelta 0:6a77043d1ee1 165 /* fill in leading fractional zeros */
rspelta 0:6a77043d1ee1 166 for (i/=10;i>1; i/=10, ptr++) {
rspelta 0:6a77043d1ee1 167 if (fractPart >= i) {
rspelta 0:6a77043d1ee1 168 break;
rspelta 0:6a77043d1ee1 169 }
rspelta 0:6a77043d1ee1 170 *ptr = '0';
rspelta 0:6a77043d1ee1 171 }
rspelta 0:6a77043d1ee1 172
rspelta 0:6a77043d1ee1 173 /* fill in (rest of) fractional part */
rspelta 0:6a77043d1ee1 174 sprintf(ptr, "%i", fractPart);
rspelta 0:6a77043d1ee1 175
rspelta 0:6a77043d1ee1 176 return str;
rspelta 0:6a77043d1ee1 177 }
rspelta 0:6a77043d1ee1 178
rspelta 0:6a77043d1ee1 179 void readSensors(void)
rspelta 0:6a77043d1ee1 180 {
rspelta 0:6a77043d1ee1 181 float temp, press;
rspelta 0:6a77043d1ee1 182 int32_t mag_axes[3], acc_axes[3], gyr_axes[3];
rspelta 0:6a77043d1ee1 183
rspelta 0:6a77043d1ee1 184 press_temp.get_temperature(&temp);
rspelta 0:6a77043d1ee1 185 uuid[3] = (int8_t)temp;
rspelta 0:6a77043d1ee1 186
rspelta 0:6a77043d1ee1 187 //press_temp.get_pressure(&press);
rspelta 0:6a77043d1ee1 188 //printf("LPS22HB: [temp] %7s C, [press] %s mbar\r\n", print_double(buffer1, value1), print_double(buffer2, value2));
rspelta 0:6a77043d1ee1 189
rspelta 0:6a77043d1ee1 190 mag.get_m_axes(mag_axes);
rspelta 0:6a77043d1ee1 191 uuid[11] = (int8_t)mag_axes[0];
rspelta 0:6a77043d1ee1 192 uuid[12] = (int8_t)mag_axes[1];
rspelta 0:6a77043d1ee1 193 uuid[13] = (int8_t)mag_axes[2];
rspelta 0:6a77043d1ee1 194 //printf("LSM303AGR [mag/mgauss]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
rspelta 0:6a77043d1ee1 195
rspelta 0:6a77043d1ee1 196 acc.get_x_axes(acc_axes);
rspelta 0:6a77043d1ee1 197 uuid[7] = (int8_t)acc_axes[0];
rspelta 0:6a77043d1ee1 198 uuid[8] = (int8_t)acc_axes[1];
rspelta 0:6a77043d1ee1 199 uuid[9] = (int8_t)acc_axes[2];
rspelta 0:6a77043d1ee1 200 //printf("LSM303AGR [acc/mg]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
rspelta 0:6a77043d1ee1 201
rspelta 0:6a77043d1ee1 202 //acc_gyro.get_x_axes(axes);
rspelta 0:6a77043d1ee1 203 //printf("LSM6DSL [acc/mg]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
rspelta 0:6a77043d1ee1 204
rspelta 0:6a77043d1ee1 205 acc_gyro.get_g_axes(gyr_axes);
rspelta 0:6a77043d1ee1 206 uuid[15] = (int8_t)gyr_axes[0];
rspelta 0:6a77043d1ee1 207 uuid[16] = (int8_t)gyr_axes[1];
rspelta 0:6a77043d1ee1 208 uuid[17] = (int8_t)gyr_axes[2];
rspelta 0:6a77043d1ee1 209 //printf("LSM6DSL [gyro/mdps]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
rspelta 0:6a77043d1ee1 210 }
rspelta 0:6a77043d1ee1 211
rspelta 0:6a77043d1ee1 212 void getDataSensors( void )
rspelta 0:6a77043d1ee1 213 {
rspelta 0:6a77043d1ee1 214 ble.gap().stopAdvertising();
rspelta 0:6a77043d1ee1 215 readSensors();
rspelta 0:6a77043d1ee1 216 advGatewayPtr->updatePayload( uuid );
rspelta 0:6a77043d1ee1 217 ble.gap().startAdvertising();
rspelta 0:6a77043d1ee1 218 }
rspelta 0:6a77043d1ee1 219
rspelta 0:6a77043d1ee1 220 int main()
rspelta 0:6a77043d1ee1 221 {
rspelta 0:6a77043d1ee1 222 press_temp.enable();
rspelta 0:6a77043d1ee1 223
rspelta 0:6a77043d1ee1 224 acc_gyro.enable_x();
rspelta 0:6a77043d1ee1 225 acc_gyro.enable_g();
rspelta 0:6a77043d1ee1 226 /* Enable Free Fall Detection. */
rspelta 0:6a77043d1ee1 227 acc_gyro.enable_free_fall_detection(LSM6DSL_INT2_PIN);
rspelta 0:6a77043d1ee1 228 mag.enable();
rspelta 0:6a77043d1ee1 229 acc.enable();
rspelta 0:6a77043d1ee1 230
rspelta 0:6a77043d1ee1 231 uint8_t id22=0, idLSM6=0, id303mag=0, id303acc=0;
rspelta 0:6a77043d1ee1 232 press_temp.read_id(&id22);
rspelta 0:6a77043d1ee1 233 acc_gyro.read_id(&idLSM6);
rspelta 0:6a77043d1ee1 234 mag.read_id(&id303mag);
rspelta 0:6a77043d1ee1 235 acc.read_id(&id303acc);
rspelta 0:6a77043d1ee1 236
rspelta 0:6a77043d1ee1 237 printf("LS303acc ID %x LS303mag ID %x LSM6DSL ID %x LPS22HB ID %x \r\n", id303acc, id303mag, idLSM6, id22);
rspelta 0:6a77043d1ee1 238 printf("\r\n");
rspelta 0:6a77043d1ee1 239
rspelta 0:6a77043d1ee1 240
rspelta 0:6a77043d1ee1 241
rspelta 0:6a77043d1ee1 242
rspelta 0:6a77043d1ee1 243 eventQueue.call_every( 500, getDataSensors );
rspelta 0:6a77043d1ee1 244 ble.onEventsToProcess(scheduleBleEventsProcessing);
rspelta 0:6a77043d1ee1 245 ble.init(bleInitComplete);
rspelta 0:6a77043d1ee1 246
rspelta 0:6a77043d1ee1 247 eventQueue.dispatch_forever();
rspelta 0:6a77043d1ee1 248
rspelta 0:6a77043d1ee1 249 return 0;
rspelta 0:6a77043d1ee1 250 }