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 16:43:34 2018 +0100
Revision:
1:f355c8472bdf
Parent:
0:6a77043d1ee1
Child:
2:934cd97bfe1a
beta version, conversion data sensors done

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 1:f355c8472bdf 39
rspelta 1:f355c8472bdf 40 SPI3W sens_intf(PB_15, NC, PB_13); // 3W mosi, sclk on Nucleo L476 same as BTLE
rspelta 1:f355c8472bdf 41 LPS22HBSensor press_temp(&sens_intf, PA_3); // on SensorTile L476JG
rspelta 1:f355c8472bdf 42 LSM6DSLSensor acc_gyro(&sens_intf, PB_12, NC, PA_2 ); // on SensorTile L476JG
rspelta 1:f355c8472bdf 43 LSM303AGRMagSensor mag(&sens_intf, PB_1 ); //on SensorTile L476JG
rspelta 1:f355c8472bdf 44 LSM303AGRAccSensor acc(&sens_intf, PC_4 ); //on SensorTile L476JG
rspelta 1:f355c8472bdf 45
rspelta 1:f355c8472bdf 46
rspelta 1:f355c8472bdf 47 BLE &ble = BLE::Instance();
rspelta 1:f355c8472bdf 48
rspelta 1:f355c8472bdf 49 /* FORMAT
rspelta 1:f355c8472bdf 50 0x19, 0x10 CompanyID
rspelta 0:6a77043d1ee1 51 0x58 Temperature
rspelta 0:6a77043d1ee1 52 T signed value from -20 to +40 celsius
rspelta 0:6a77043d1ee1 53 0xA8 Humidity
rspelta 0:6a77043d1ee1 54 H not used,
rspelta 0:6a77043d1ee1 55 0x18 Accelerometer
rspelta 0:6a77043d1ee1 56 X 2’complement value in units of 0.01g
rspelta 0:6a77043d1ee1 57 Y 2’complement value in units of 0.01g
rspelta 0:6a77043d1ee1 58 Z 2’complement value in units of 0.01g
rspelta 0:6a77043d1ee1 59 0x38 Magnetometer
rspelta 0:6a77043d1ee1 60 X 2’ complement value in units of 10-6T
rspelta 0:6a77043d1ee1 61 Y 2’ complement value in units of 10-6T
rspelta 0:6a77043d1ee1 62 Z 2’ complement value in units of 10-6T
rspelta 1:f355c8472bdf 63 0x28 Gyroscope (it is not showed on the gateway)
rspelta 0:6a77043d1ee1 64 X 2’ complement value in units od 0.1deg/s
rspelta 0:6a77043d1ee1 65 Y 2’ complement value in units od 0.1deg/s
rspelta 0:6a77043d1ee1 66 Z 2’ complement value in units od 0.1deg/s
rspelta 0:6a77043d1ee1 67 0x48 Ambient light & Proximity
rspelta 0:6a77043d1ee1 68 A not used
rspelta 0:6a77043d1ee1 69 P not used
rspelta 0:6a77043d1ee1 70 */
rspelta 0:6a77043d1ee1 71 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 72
rspelta 0:6a77043d1ee1 73 static advGateway* advGatewayPtr;
rspelta 0:6a77043d1ee1 74
rspelta 0:6a77043d1ee1 75 static EventQueue eventQueue(/* event count */ 4 * EVENTS_EVENT_SIZE);
rspelta 0:6a77043d1ee1 76
rspelta 0:6a77043d1ee1 77 /**
rspelta 0:6a77043d1ee1 78 * This function is called when the ble initialization process has failled
rspelta 0:6a77043d1ee1 79 */
rspelta 0:6a77043d1ee1 80 void onBleInitError(BLE &ble, ble_error_t error)
rspelta 0:6a77043d1ee1 81 {
rspelta 0:6a77043d1ee1 82 /* Initialization error handling should go here */
rspelta 0:6a77043d1ee1 83 }
rspelta 0:6a77043d1ee1 84
rspelta 0:6a77043d1ee1 85 void printMacAddress()
rspelta 0:6a77043d1ee1 86 {
rspelta 0:6a77043d1ee1 87 /* Print out device MAC address to the console*/
rspelta 0:6a77043d1ee1 88 Gap::AddressType_t addr_type;
rspelta 0:6a77043d1ee1 89 Gap::Address_t address;
rspelta 0:6a77043d1ee1 90 BLE::Instance().gap().getAddress(&addr_type, address);
rspelta 0:6a77043d1ee1 91 printf("DEVICE MAC ADDRESS: ");
rspelta 0:6a77043d1ee1 92 for (int i = 5; i >= 1; i--){
rspelta 0:6a77043d1ee1 93 printf("%02x:", address[i]);
rspelta 0:6a77043d1ee1 94 }
rspelta 0:6a77043d1ee1 95 printf("%02x\r\n", address[0]);
rspelta 0:6a77043d1ee1 96 }
rspelta 0:6a77043d1ee1 97
rspelta 0:6a77043d1ee1 98 /**
rspelta 0:6a77043d1ee1 99 * Callback triggered when the ble initialization process has finished
rspelta 0:6a77043d1ee1 100 */
rspelta 0:6a77043d1ee1 101 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
rspelta 0:6a77043d1ee1 102 {
rspelta 0:6a77043d1ee1 103 BLE& ble = params->ble;
rspelta 0:6a77043d1ee1 104 ble_error_t error = params->error;
rspelta 0:6a77043d1ee1 105
rspelta 0:6a77043d1ee1 106 if (error != BLE_ERROR_NONE) {
rspelta 0:6a77043d1ee1 107 /* In case of error, forward the error handling to onBleInitError */
rspelta 0:6a77043d1ee1 108 onBleInitError(ble, error);
rspelta 0:6a77043d1ee1 109 return;
rspelta 0:6a77043d1ee1 110 }
rspelta 0:6a77043d1ee1 111
rspelta 0:6a77043d1ee1 112 /* Ensure that it is the default instance of BLE */
rspelta 0:6a77043d1ee1 113 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
rspelta 0:6a77043d1ee1 114 return;
rspelta 0:6a77043d1ee1 115 }
rspelta 0:6a77043d1ee1 116
rspelta 0:6a77043d1ee1 117 advGatewayPtr = new advGateway(ble, uuid);
rspelta 1:f355c8472bdf 118
rspelta 0:6a77043d1ee1 119 ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
rspelta 0:6a77043d1ee1 120 ble.gap().startAdvertising();
rspelta 0:6a77043d1ee1 121
rspelta 0:6a77043d1ee1 122 printMacAddress();
rspelta 0:6a77043d1ee1 123 }
rspelta 0:6a77043d1ee1 124
rspelta 0:6a77043d1ee1 125 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
rspelta 0:6a77043d1ee1 126 BLE &ble = BLE::Instance();
rspelta 0:6a77043d1ee1 127 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
rspelta 0:6a77043d1ee1 128 }
rspelta 0:6a77043d1ee1 129
rspelta 0:6a77043d1ee1 130 /* Helper function for printing floats & doubles */
rspelta 0:6a77043d1ee1 131 static char *print_double(char* str, double v, int decimalDigits=2)
rspelta 0:6a77043d1ee1 132 {
rspelta 0:6a77043d1ee1 133 int i = 1;
rspelta 0:6a77043d1ee1 134 int intPart, fractPart;
rspelta 0:6a77043d1ee1 135 int len;
rspelta 0:6a77043d1ee1 136 char *ptr;
rspelta 0:6a77043d1ee1 137
rspelta 0:6a77043d1ee1 138 /* prepare decimal digits multiplicator */
rspelta 0:6a77043d1ee1 139 for (;decimalDigits!=0; i*=10, decimalDigits--);
rspelta 0:6a77043d1ee1 140
rspelta 0:6a77043d1ee1 141 /* calculate integer & fractinal parts */
rspelta 0:6a77043d1ee1 142 intPart = (int)v;
rspelta 0:6a77043d1ee1 143 fractPart = (int)((v-(double)(int)v)*i);
rspelta 0:6a77043d1ee1 144
rspelta 0:6a77043d1ee1 145 /* fill in integer part */
rspelta 0:6a77043d1ee1 146 sprintf(str, "%i.", intPart);
rspelta 0:6a77043d1ee1 147
rspelta 0:6a77043d1ee1 148 /* prepare fill in of fractional part */
rspelta 0:6a77043d1ee1 149 len = strlen(str);
rspelta 0:6a77043d1ee1 150 ptr = &str[len];
rspelta 0:6a77043d1ee1 151
rspelta 0:6a77043d1ee1 152 /* fill in leading fractional zeros */
rspelta 0:6a77043d1ee1 153 for (i/=10;i>1; i/=10, ptr++) {
rspelta 0:6a77043d1ee1 154 if (fractPart >= i) {
rspelta 0:6a77043d1ee1 155 break;
rspelta 0:6a77043d1ee1 156 }
rspelta 0:6a77043d1ee1 157 *ptr = '0';
rspelta 0:6a77043d1ee1 158 }
rspelta 0:6a77043d1ee1 159
rspelta 0:6a77043d1ee1 160 /* fill in (rest of) fractional part */
rspelta 0:6a77043d1ee1 161 sprintf(ptr, "%i", fractPart);
rspelta 0:6a77043d1ee1 162
rspelta 0:6a77043d1ee1 163 return str;
rspelta 0:6a77043d1ee1 164 }
rspelta 0:6a77043d1ee1 165
rspelta 0:6a77043d1ee1 166 void readSensors(void)
rspelta 0:6a77043d1ee1 167 {
rspelta 1:f355c8472bdf 168 float temp;//, press;
rspelta 0:6a77043d1ee1 169 int32_t mag_axes[3], acc_axes[3], gyr_axes[3];
rspelta 0:6a77043d1ee1 170
rspelta 0:6a77043d1ee1 171 press_temp.get_temperature(&temp);
rspelta 0:6a77043d1ee1 172 uuid[3] = (int8_t)temp;
rspelta 0:6a77043d1ee1 173
rspelta 1:f355c8472bdf 174 //press_temp.get_pressure(&press); not used
rspelta 0:6a77043d1ee1 175 //printf("LPS22HB: [temp] %7s C, [press] %s mbar\r\n", print_double(buffer1, value1), print_double(buffer2, value2));
rspelta 0:6a77043d1ee1 176
rspelta 0:6a77043d1ee1 177 mag.get_m_axes(mag_axes);
rspelta 1:f355c8472bdf 178 uuid[11] = (int8_t)((mag_axes[0]*1.5)/10);
rspelta 1:f355c8472bdf 179 uuid[12] = (int8_t)((mag_axes[1]*1.5)/10);
rspelta 1:f355c8472bdf 180 uuid[13] = (int8_t)((mag_axes[2]*1.5)/10);
rspelta 1:f355c8472bdf 181 //printf("LSM303AGR [mag/mgauss]: %d, %d, %d\r\n", uuid[11], uuid[12], uuid[13]); //*1.5=1mG
rspelta 0:6a77043d1ee1 182
rspelta 1:f355c8472bdf 183 acc_gyro.get_x_axes(acc_axes);
rspelta 1:f355c8472bdf 184 uuid[7] = (int8_t)((acc_axes[0]*100)/1024);
rspelta 1:f355c8472bdf 185 uuid[8] = (int8_t)((acc_axes[1]*100)/1024);
rspelta 1:f355c8472bdf 186 uuid[9] = (int8_t)((acc_axes[2]*100)/1024);
rspelta 1:f355c8472bdf 187 //printf("LSM6DSL [acc/mg]: %02x, %02x, %02x\r\n", acc_axes[0], acc_axes[1],acc_axes[2]); // 1024 = 1G
rspelta 0:6a77043d1ee1 188
rspelta 1:f355c8472bdf 189 acc_gyro.get_g_axes(gyr_axes); // not used by the gateway
rspelta 0:6a77043d1ee1 190 uuid[15] = (int8_t)gyr_axes[0];
rspelta 0:6a77043d1ee1 191 uuid[16] = (int8_t)gyr_axes[1];
rspelta 0:6a77043d1ee1 192 uuid[17] = (int8_t)gyr_axes[2];
rspelta 1:f355c8472bdf 193 //printf("LSM6DSL [gyro/mdps]: %6ld, %6ld, %6ld\r\n", uuid[15], uuid[16], uuid[17]);
rspelta 0:6a77043d1ee1 194 }
rspelta 0:6a77043d1ee1 195
rspelta 0:6a77043d1ee1 196 void getDataSensors( void )
rspelta 0:6a77043d1ee1 197 {
rspelta 0:6a77043d1ee1 198 ble.gap().stopAdvertising();
rspelta 0:6a77043d1ee1 199 readSensors();
rspelta 0:6a77043d1ee1 200 advGatewayPtr->updatePayload( uuid );
rspelta 0:6a77043d1ee1 201 ble.gap().startAdvertising();
rspelta 0:6a77043d1ee1 202 }
rspelta 0:6a77043d1ee1 203
rspelta 0:6a77043d1ee1 204 int main()
rspelta 0:6a77043d1ee1 205 {
rspelta 0:6a77043d1ee1 206 press_temp.enable();
rspelta 0:6a77043d1ee1 207
rspelta 0:6a77043d1ee1 208 acc_gyro.enable_x();
rspelta 0:6a77043d1ee1 209 acc_gyro.enable_g();
rspelta 0:6a77043d1ee1 210 /* Enable Free Fall Detection. */
rspelta 1:f355c8472bdf 211 //acc_gyro.enable_free_fall_detection(LSM6DSL_INT2_PIN);
rspelta 0:6a77043d1ee1 212 mag.enable();
rspelta 0:6a77043d1ee1 213 acc.enable();
rspelta 0:6a77043d1ee1 214
rspelta 0:6a77043d1ee1 215 uint8_t id22=0, idLSM6=0, id303mag=0, id303acc=0;
rspelta 0:6a77043d1ee1 216 press_temp.read_id(&id22);
rspelta 0:6a77043d1ee1 217 acc_gyro.read_id(&idLSM6);
rspelta 0:6a77043d1ee1 218 mag.read_id(&id303mag);
rspelta 0:6a77043d1ee1 219 acc.read_id(&id303acc);
rspelta 0:6a77043d1ee1 220
rspelta 0:6a77043d1ee1 221 printf("LS303acc ID %x LS303mag ID %x LSM6DSL ID %x LPS22HB ID %x \r\n", id303acc, id303mag, idLSM6, id22);
rspelta 0:6a77043d1ee1 222 printf("\r\n");
rspelta 0:6a77043d1ee1 223
rspelta 1:f355c8472bdf 224 eventQueue.call_every( 500, getDataSensors );
rspelta 1:f355c8472bdf 225 ble.onEventsToProcess(scheduleBleEventsProcessing);
rspelta 1:f355c8472bdf 226 ble.init(bleInitComplete);
rspelta 0:6a77043d1ee1 227
rspelta 1:f355c8472bdf 228 eventQueue.dispatch_forever();
rspelta 0:6a77043d1ee1 229
rspelta 1:f355c8472bdf 230 return 0;
rspelta 0:6a77043d1ee1 231 }