Example of using the mDot UDK with the X-NUCLEO-IKS01A2 board

Dependencies:   MTS_X_NUCLEO_IKS01A2 libmDot-mbed5

Fork of mDot-IKS01A1 by Peter Ferland

Committer:
pferland
Date:
Tue Feb 14 20:33:40 2017 +0000
Revision:
10:1e3e3ab9c29c
Parent:
9:e642e8f9ea37
Child:
12:63e90d375afd
Updated to latest mbed-os versions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pferland 0:9e88a9018fc0 1 #include "mbed.h"
pferland 0:9e88a9018fc0 2 #include "mDot.h"
pferland 0:9e88a9018fc0 3 #include "x_nucleo_iks01a1.h"
pferland 0:9e88a9018fc0 4 #include "dot_util.h"
pferland 0:9e88a9018fc0 5 #include "RadioEvent.h"
pferland 9:e642e8f9ea37 6 #include <cmath>
pferland 0:9e88a9018fc0 7
pferland 4:142c85980a6f 8 // mDot UDK board demo with X-NUCLEO-IKS01A1 sensor card
pferland 4:142c85980a6f 9 // For more examples see the Dot-Examples project:
pferland 4:142c85980a6f 10 // https://developer.mbed.org/teams/MultiTech/code/Dot-Examples/
pferland 4:142c85980a6f 11
pferland 4:142c85980a6f 12 // This triggers an I2C issue in mbed-os 5.1.5
pferland 4:142c85980a6f 13 // Use any other revision to compile. (Tested with libmDot-dev/mbed-os 5.2.2
pferland 9:e642e8f9ea37 14 #define SENET
pferland 10:1e3e3ab9c29c 15 #ifdef ACTILITY
pferland 10:1e3e3ab9c29c 16 // Network Id for Senet public network
pferland 10:1e3e3ab9c29c 17 static uint8_t network_id[] = {0xF0, 0x3D, 0x29,0xAC,0x71,0x00,0x00, 0x00};
pferland 10:1e3e3ab9c29c 18 // Register at or Sign in to http://portal.senetco.com/ and register your NodeId to receive your AppId
pferland 10:1e3e3ab9c29c 19 // {0xD3,0x5A,0x30,0x60,0xA6,0x0D,0x9E,0xEA,0xD9,0xA1,0x19,0x61,0x4F,0x29,0x9E,0x5B}
pferland 10:1e3e3ab9c29c 20 static uint8_t network_key[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //{0xD3,0x5A,0x30,0x60,0xA6,0x0D,0x9E,0xEA,0xD9,0xA1,0x19,0x61,0x4F,0x29,0x9E,0x5B};
pferland 10:1e3e3ab9c29c 21 static uint8_t frequency_sub_band = 0;
pferland 10:1e3e3ab9c29c 22 static bool public_network = true;
pferland 10:1e3e3ab9c29c 23 #elif defined(SENET)
pferland 4:142c85980a6f 24 // Network Id for Senet public network
pferland 4:142c85980a6f 25 static uint8_t network_id[] = {0x00,0x25,0x0C,0x00,0x00,0x01,0x00,0x01};
pferland 4:142c85980a6f 26 // Register at or Sign in to http://portal.senetco.com/ and register your NodeId to receive your AppId
pferland 9:e642e8f9ea37 27 // {0xD3,0x5A,0x30,0x60,0xA6,0x0D,0x9E,0xEA,0xD9,0xA1,0x19,0x61,0x4F,0x29,0x9E,0x5B}
pferland 10:1e3e3ab9c29c 28 static uint8_t network_key[] = {0x5F,0x7B,0x08,0x15,0x55,0x69,0x9A,0x2E,0x3C,0x91,0xE3,0xFE,0xF0,0x2A,0x77,0x79};
pferland 4:142c85980a6f 29 // 1 For Senet, configurable on your Conduit
pferland 0:9e88a9018fc0 30 static uint8_t frequency_sub_band = 1;
pferland 4:142c85980a6f 31 // True for Senet, false for your Conduit.
pferland 4:142c85980a6f 32 static bool public_network = true;
pferland 9:e642e8f9ea37 33 #else
pferland 9:e642e8f9ea37 34 //Replace with settings on your Conduit
pferland 10:1e3e3ab9c29c 35 static std::string network_name = "EcoLabTest";
pferland 10:1e3e3ab9c29c 36 static std::string network_passphrase = "EcoLabTest";
pferland 9:e642e8f9ea37 37 // 1 For Senet, configurable on your Conduit
pferland 9:e642e8f9ea37 38 static uint8_t frequency_sub_band = 1;
pferland 9:e642e8f9ea37 39 // True for Senet, false for your Conduit.
pferland 9:e642e8f9ea37 40 static bool public_network = false;
pferland 9:e642e8f9ea37 41 #endif
pferland 10:1e3e3ab9c29c 42 static uint8_t ack = 0;
pferland 10:1e3e3ab9c29c 43 static uint8_t tx_datarate = mDot::SF_7;
pferland 0:9e88a9018fc0 44
pferland 4:142c85980a6f 45 // deepsleep consumes slightly less current than sleep
pferland 4:142c85980a6f 46 // in sleep mode, IO state is maintained, RAM is retained, and application will resume after waking up
pferland 4:142c85980a6f 47 // in deepsleep mode, IOs float, RAM is lost, and application will start from beginning after waking up
pferland 4:142c85980a6f 48 // if deep_sleep == true, device will enter deepsleep mode
pferland 4:142c85980a6f 49 static bool deep_sleep = false;
pferland 4:142c85980a6f 50
pferland 0:9e88a9018fc0 51 mDot *dot = NULL;
pferland 0:9e88a9018fc0 52
pferland 0:9e88a9018fc0 53 int main()
pferland 0:9e88a9018fc0 54 {
pferland 4:142c85980a6f 55 Serial pc(USBTX, USBRX);
pferland 4:142c85980a6f 56
pferland 4:142c85980a6f 57 /* Instantiate the expansion board */
pferland 4:142c85980a6f 58 X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(I2C_SDA, I2C_SCL, PC_1);
pferland 4:142c85980a6f 59
pferland 4:142c85980a6f 60 /* Retrieve the composing elements of the expansion board */
pferland 4:142c85980a6f 61 GyroSensor *gyroscope = mems_expansion_board->GetGyroscope();
pferland 4:142c85980a6f 62 MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer();
pferland 4:142c85980a6f 63 MagneticSensor *magnetometer = mems_expansion_board->magnetometer;
pferland 4:142c85980a6f 64 HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;
pferland 4:142c85980a6f 65 PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor;
pferland 4:142c85980a6f 66 TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor;
pferland 4:142c85980a6f 67 TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor;
pferland 0:9e88a9018fc0 68 // Custom event handler for automatically displaying RX data
pferland 0:9e88a9018fc0 69 RadioEvent events;
pferland 0:9e88a9018fc0 70 pc.baud(115200);
pferland 0:9e88a9018fc0 71
pferland 0:9e88a9018fc0 72 /* Initialize mDot */
pferland 0:9e88a9018fc0 73 dot = mDot::getInstance();
pferland 8:bfbc3dd47166 74
pferland 8:bfbc3dd47166 75 //dot->setAdr(true);
pferland 4:142c85980a6f 76 mts::MTSLog::setLogLevel(mts::MTSLog::INFO_LEVEL);
pferland 0:9e88a9018fc0 77 dot->setEvents(&events);
pferland 0:9e88a9018fc0 78
pferland 0:9e88a9018fc0 79
pferland 0:9e88a9018fc0 80 if (!dot->getStandbyFlag()) {
pferland 0:9e88a9018fc0 81 logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
pferland 0:9e88a9018fc0 82 // start from a well-known state
pferland 0:9e88a9018fc0 83 logInfo("defaulting Dot configuration");
pferland 0:9e88a9018fc0 84 dot->resetConfig();
pferland 0:9e88a9018fc0 85 dot->resetNetworkSession();
pferland 0:9e88a9018fc0 86
pferland 0:9e88a9018fc0 87 // update configuration if necessary
pferland 0:9e88a9018fc0 88 // in AUTO_OTA mode the session is automatically saved, so saveNetworkSession and restoreNetworkSession are not needed
pferland 0:9e88a9018fc0 89 if (dot->getJoinMode() != mDot::AUTO_OTA) {
pferland 0:9e88a9018fc0 90 logInfo("changing network join mode to AUTO_OTA");
pferland 0:9e88a9018fc0 91 if (dot->setJoinMode(mDot::AUTO_OTA) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 92 logError("failed to set network join mode to AUTO_OTA");
pferland 0:9e88a9018fc0 93 }
pferland 0:9e88a9018fc0 94 }
pferland 8:bfbc3dd47166 95
pferland 8:bfbc3dd47166 96 uint32_t current_tx_datarate = dot->getTxDataRate();
pferland 8:bfbc3dd47166 97 if (current_tx_datarate != tx_datarate) {
pferland 8:bfbc3dd47166 98 logInfo("changing TX datarate from %u to %u", current_tx_datarate, tx_datarate);
pferland 8:bfbc3dd47166 99 if (dot->setTxDataRate(tx_datarate) != mDot::MDOT_OK) {
pferland 8:bfbc3dd47166 100 logError("failed to set TX datarate to %u", tx_datarate);
pferland 8:bfbc3dd47166 101 }
pferland 8:bfbc3dd47166 102 }
pferland 0:9e88a9018fc0 103 // in OTA and AUTO_OTA join modes, the credentials can be passed to the library as a name and passphrase or an ID and KEY
pferland 0:9e88a9018fc0 104 // only one method or the other should be used!
pferland 0:9e88a9018fc0 105 // network ID = crc64(network name)
pferland 10:1e3e3ab9c29c 106 #if defined(SENET) || defined(ACTILITY)
pferland 0:9e88a9018fc0 107 // network KEY = cmac(network passphrase)
pferland 4:142c85980a6f 108 update_ota_config_id_key(network_id, network_key, frequency_sub_band, public_network, ack);
pferland 9:e642e8f9ea37 109 #else
pferland 9:e642e8f9ea37 110 update_ota_config_name_phrase(network_name, network_passphrase, frequency_sub_band, public_network, ack);
pferland 9:e642e8f9ea37 111 #endif
pferland 0:9e88a9018fc0 112
pferland 0:9e88a9018fc0 113 // configure network link checks
pferland 0:9e88a9018fc0 114 // network link checks are a good alternative to requiring the gateway to ACK every packet and should allow a single gateway to handle more Dots
pferland 0:9e88a9018fc0 115 // check the link every count packets
pferland 0:9e88a9018fc0 116 // declare the Dot disconnected after threshold failed link checks
pferland 0:9e88a9018fc0 117 // for count = 3 and threshold = 5, the Dot will be considered disconnected after 15 missed packets in a row
pferland 0:9e88a9018fc0 118 update_network_link_check_config(3, 5);
pferland 0:9e88a9018fc0 119
pferland 0:9e88a9018fc0 120 // save changes to configuration
pferland 0:9e88a9018fc0 121 logInfo("saving configuration");
pferland 0:9e88a9018fc0 122 if (!dot->saveConfig()) {
pferland 0:9e88a9018fc0 123 logError("failed to save configuration");
pferland 0:9e88a9018fc0 124 }
pferland 0:9e88a9018fc0 125
pferland 0:9e88a9018fc0 126 // display configuration
pferland 0:9e88a9018fc0 127 display_config();
pferland 0:9e88a9018fc0 128 } else {
pferland 0:9e88a9018fc0 129 // restore the saved session if the dot woke from deepsleep mode
pferland 0:9e88a9018fc0 130 // useful to use with deepsleep because session info is otherwise lost when the dot enters deepsleep
pferland 0:9e88a9018fc0 131 logInfo("restoring network session from NVM");
pferland 0:9e88a9018fc0 132 dot->restoreNetworkSession();
pferland 0:9e88a9018fc0 133 }
pferland 3:d34798ffcaf8 134
pferland 3:d34798ffcaf8 135
pferland 0:9e88a9018fc0 136
pferland 0:9e88a9018fc0 137 while (true) {
pferland 0:9e88a9018fc0 138 std::vector<uint8_t> tx_data;
pferland 0:9e88a9018fc0 139
pferland 0:9e88a9018fc0 140 // join network if not joined
pferland 0:9e88a9018fc0 141 if (!dot->getNetworkJoinStatus()) {
pferland 0:9e88a9018fc0 142 join_network();
pferland 0:9e88a9018fc0 143 }
pferland 7:d2052933ebcb 144
pferland 9:e642e8f9ea37 145 // Payload structure for mydevices cayenne:
pferland 9:e642e8f9ea37 146 // 1 byte Data1 ID
pferland 9:e642e8f9ea37 147 // 1 Byte Data1 Type
pferland 9:e642e8f9ea37 148 // N Bytes Data1
pferland 9:e642e8f9ea37 149 // 1 byte data 2 ID
pferland 9:e642e8f9ea37 150 // 1 byte data 2 type
pferland 9:e642e8f9ea37 151 // n Bytes data 2
pferland 9:e642e8f9ea37 152 // ...
pferland 9:e642e8f9ea37 153
pferland 9:e642e8f9ea37 154 // formats:
pferland 9:e642e8f9ea37 155 // Temperature sensor:
pferland 9:e642e8f9ea37 156 /*
pferland 9:e642e8f9ea37 157 * IPSO: 3303
pferland 9:e642e8f9ea37 158 * LPP 103
pferland 9:e642e8f9ea37 159 * HEX: 67
pferland 9:e642e8f9ea37 160 * Data size: 2
pferland 9:e642e8f9ea37 161 * Resolution: 0.1 degres C
pferland 9:e642e8f9ea37 162
pferland 9:e642e8f9ea37 163 * Humidity sensor
pferland 9:e642e8f9ea37 164 * IPSO: 3304
pferland 9:e642e8f9ea37 165 * LPP: 104
pferland 9:e642e8f9ea37 166 * Hex: 68
pferland 9:e642e8f9ea37 167 * Datasize: 1
pferland 9:e642e8f9ea37 168 * Resolution: 0.5% unsigned
pferland 9:e642e8f9ea37 169
pferland 9:e642e8f9ea37 170 * Barometer/pressure sensor
pferland 9:e642e8f9ea37 171 * IPSO: 3315
pferland 9:e642e8f9ea37 172 * LPP: 115
pferland 9:e642e8f9ea37 173 * Hex: 73
pferland 9:e642e8f9ea37 174 * Datasize: 2
pferland 9:e642e8f9ea37 175 * Resolution 0.1hPa unsigned MSB
pferland 9:e642e8f9ea37 176
pferland 9:e642e8f9ea37 177 * Accelerometer
pferland 9:e642e8f9ea37 178 * IPSO: 3313
pferland 9:e642e8f9ea37 179 * LPP: 113
pferland 9:e642e8f9ea37 180 * Hex: 71
pferland 9:e642e8f9ea37 181 * Data size: 6
pferland 9:e642e8f9ea37 182 * Resolution: 0.001G signed MSB per axis
pferland 9:e642e8f9ea37 183
pferland 9:e642e8f9ea37 184 * Gyrometer
pferland 9:e642e8f9ea37 185 * IPSO: 3334
pferland 9:e642e8f9ea37 186 * LPP: 134
pferland 9:e642e8f9ea37 187 * Hex: 86
pferland 9:e642e8f9ea37 188 * Data size: 6
pferland 9:e642e8f9ea37 189 * Resolution: 0.01 degrees/s signed msb per axis
pferland 9:e642e8f9ea37 190 */
pferland 9:e642e8f9ea37 191
pferland 0:9e88a9018fc0 192 //temp floats
pferland 0:9e88a9018fc0 193 float value1, value2;
pferland 4:142c85980a6f 194
pferland 0:9e88a9018fc0 195 // HTS221 Humidity sensor
pferland 0:9e88a9018fc0 196 temp_sensor1->GetTemperature(&value1);
pferland 0:9e88a9018fc0 197 humidity_sensor->GetHumidity(&value2);
pferland 4:142c85980a6f 198
pferland 0:9e88a9018fc0 199 //serialize data and append to packet
pferland 9:e642e8f9ea37 200 // Cayenne data: temperature; tag is 0x67, 2 bytes signed, 0.1 C/bit
pferland 9:e642e8f9ea37 201 tx_data.push_back(uint8_t(1)); // data id
pferland 9:e642e8f9ea37 202 tx_data.push_back(uint8_t(0x67)); // data type - temp
pferland 9:e642e8f9ea37 203 int16_t temp = floor(value1*10 + 0.5f);
pferland 9:e642e8f9ea37 204 logInfo("Temp payload: %d", temp);
pferland 9:e642e8f9ea37 205 tx_data.push_back(uint8_t( 0xFF & (temp >> 8)));
pferland 9:e642e8f9ea37 206 tx_data.push_back(uint8_t(0xFF & temp));
pferland 9:e642e8f9ea37 207
pferland 9:e642e8f9ea37 208
pferland 9:e642e8f9ea37 209 tx_data.push_back(uint8_t(2)); // data id
pferland 9:e642e8f9ea37 210 tx_data.push_back(uint8_t(0x68)); // data type - humidity
pferland 9:e642e8f9ea37 211 temp = floor(value2 * 2.0f + 0.5f);
pferland 9:e642e8f9ea37 212 tx_data.push_back(uint8_t(0xFF & temp ));
pferland 9:e642e8f9ea37 213
pferland 4:142c85980a6f 214 logInfo("Temperature data %f", value1);
pferland 9:e642e8f9ea37 215 logInfo("Humidity data: %f", value2);
pferland 4:142c85980a6f 216
pferland 9:e642e8f9ea37 217 pressure_sensor->GetPressure(&value1);
pferland 9:e642e8f9ea37 218 logInfo("PRessure data: %f", value1);
pferland 9:e642e8f9ea37 219 // pressure is reported in mbar, cayenne wants it in 0.1 hPa
pferland 9:e642e8f9ea37 220 // 1mbar = 1 hPa
pferland 9:e642e8f9ea37 221 temp = floor(value1 * 100.0f + 0.5f);
pferland 9:e642e8f9ea37 222 tx_data.push_back(uint8_t(3)); // data id
pferland 9:e642e8f9ea37 223 tx_data.push_back(uint8_t(0x73)); // data type - pressure
pferland 9:e642e8f9ea37 224 temp = floor(value1 / 0.1f + 0.5f);
pferland 9:e642e8f9ea37 225 tx_data.push_back(uint8_t(0xFF & (temp >> 8)));
pferland 9:e642e8f9ea37 226 tx_data.push_back(uint8_t(0xFF & temp));
pferland 9:e642e8f9ea37 227
pferland 9:e642e8f9ea37 228
pferland 9:e642e8f9ea37 229 // Get accelerometer data
pferland 4:142c85980a6f 230 int32_t accel_vector[3];
pferland 9:e642e8f9ea37 231 // returns in mG
pferland 4:142c85980a6f 232 accelerometer->Get_X_Axes(accel_vector);
pferland 4:142c85980a6f 233 logInfo("Acclerometer Z axis: %d", accel_vector[2]);
pferland 4:142c85980a6f 234
pferland 9:e642e8f9ea37 235 tx_data.push_back(uint8_t(4)); // data id
pferland 9:e642e8f9ea37 236 tx_data.push_back(uint8_t(0x71)); // data type - accelerometer
pferland 9:e642e8f9ea37 237 for(int i=0; i<3; i++){
pferland 9:e642e8f9ea37 238 tx_data.push_back(uint8_t(0xFF & accel_vector[i]) >> 8);
pferland 9:e642e8f9ea37 239 tx_data.push_back(uint8_t(0xFF & accel_vector[i]));
pferland 9:e642e8f9ea37 240 }
pferland 9:e642e8f9ea37 241
pferland 9:e642e8f9ea37 242 // Get gyro data
pferland 9:e642e8f9ea37 243 gyroscope->Get_G_Axes(accel_vector);
pferland 9:e642e8f9ea37 244 // gyro reports in milidegrees/sec, cayenne wants centidegrees/sec
pferland 9:e642e8f9ea37 245 tx_data.push_back(uint8_t(5)); //data id
pferland 9:e642e8f9ea37 246 tx_data.push_back(uint8_t(0x86)); // data type - gyrometer
pferland 9:e642e8f9ea37 247 for(int i=0; i<3; i++){
pferland 9:e642e8f9ea37 248 accel_vector[i] /= 10;
pferland 9:e642e8f9ea37 249 tx_data.push_back(uint8_t(0xFF & (accel_vector[i] >> 8)));
pferland 9:e642e8f9ea37 250 tx_data.push_back(uint8_t(0xFF & accel_vector[i]));
pferland 9:e642e8f9ea37 251 }
pferland 9:e642e8f9ea37 252
pferland 9:e642e8f9ea37 253
pferland 0:9e88a9018fc0 254 send_data(tx_data);
pferland 0:9e88a9018fc0 255
pferland 10:1e3e3ab9c29c 256 if(deep_sleep){
pferland 0:9e88a9018fc0 257 // if going into deepsleep mode, save the session so we don't need to join again after waking up
pferland 0:9e88a9018fc0 258 // not necessary if going into sleep mode since RAM is retained
pferland 10:1e3e3ab9c29c 259 logInfo("saving network session to NVM");
pferland 10:1e3e3ab9c29c 260 dot->saveNetworkSession();
pferland 10:1e3e3ab9c29c 261 }
pferland 0:9e88a9018fc0 262
pferland 0:9e88a9018fc0 263
pferland 0:9e88a9018fc0 264 // ONLY ONE of the three functions below should be uncommented depending on the desired wakeup method
pferland 6:9e6ac13de3e9 265 sleep_wake_rtc_only(deep_sleep);
pferland 0:9e88a9018fc0 266 //sleep_wake_interrupt_only(deep_sleep);
pferland 6:9e6ac13de3e9 267 //sleep_wake_rtc_or_interrupt(deep_sleep);
pferland 0:9e88a9018fc0 268
pferland 0:9e88a9018fc0 269 }
pferland 0:9e88a9018fc0 270
pferland 0:9e88a9018fc0 271 return 0;
pferland 0:9e88a9018fc0 272 }