Example of using the mDot UDK with the X-NUCLEO-IKS01A1 shield

Dependencies:   mDot_X_NUCLEO_IKS01A1 libmDot-dev-mbed5-deprecated

Hardware

Hardware List

Setup

  • Install the mDot on the developer board.
  • Install the IKS01A1 on the developer board.
  • If using a MTUDK-ST-CELL (white board) plug in the AC power adapter
  • Connect the microusb power to your development PC
    • if using a MTUDK-ST-CELL there are 2 microusb ports. Use the one closest to the serial port.

Your developer board should look like the following:

/media/uploads/pferland/udk_iks01a1.jpg

Software

This example program uses LoRa utility functions from Dot-Examples and the IKS01A1 library from ST Micro.

LoRa Configuration

Senet

By default this program is configured to connect to the Senet network. To connect to Senet you will need to register your mDot's Node ID with the Senet developer portal and change the network_key array in main.cpp.

Others

To connect to a different LoRa gateway change the arrays network_id and network_key. If you are using passphrases, edit the strings network_name and network_key, uncomment the function "update_ota_config_name_phrase" and comment out the function "update_ota_config_id_key".

Committer:
pferland
Date:
Fri Dec 16 04:24:54 2016 +0000
Revision:
8:bfbc3dd47166
Parent:
7:d2052933ebcb
Child:
9:e642e8f9ea37
Updated for Seattle demo

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 0:9e88a9018fc0 6
pferland 4:142c85980a6f 7 // mDot UDK board demo with X-NUCLEO-IKS01A1 sensor card
pferland 4:142c85980a6f 8 // For more examples see the Dot-Examples project:
pferland 4:142c85980a6f 9 // https://developer.mbed.org/teams/MultiTech/code/Dot-Examples/
pferland 4:142c85980a6f 10
pferland 4:142c85980a6f 11 // This triggers an I2C issue in mbed-os 5.1.5
pferland 4:142c85980a6f 12 // Use any other revision to compile. (Tested with libmDot-dev/mbed-os 5.2.2
pferland 4:142c85980a6f 13
pferland 4:142c85980a6f 14 //Replace with settings on your Conduit
pferland 0:9e88a9018fc0 15 static std::string network_name = "TestTest";
pferland 4:142c85980a6f 16 static std::string network_passphrase = "TestTest";
pferland 4:142c85980a6f 17 // Network Id for Senet public network
pferland 4:142c85980a6f 18 static uint8_t network_id[] = {0x00,0x25,0x0C,0x00,0x00,0x01,0x00,0x01};
pferland 4:142c85980a6f 19 // Register at or Sign in to http://portal.senetco.com/ and register your NodeId to receive your AppId
pferland 4:142c85980a6f 20 static uint8_t network_key[] = {0x9F,0x6B,0xD3,0xB2,0xD9,0x3A,0x3B,0x4D,0x7B,0x35,0x62,0xF2,0xB9,0x58,0x05,0x6C};
pferland 4:142c85980a6f 21 // 1 For Senet, configurable on your Conduit
pferland 0:9e88a9018fc0 22 static uint8_t frequency_sub_band = 1;
pferland 4:142c85980a6f 23 // True for Senet, false for your Conduit.
pferland 4:142c85980a6f 24 static bool public_network = true;
pferland 0:9e88a9018fc0 25 static uint8_t ack = 0;
pferland 8:bfbc3dd47166 26 static uint8_t tx_datarate = mDot::DR3;
pferland 0:9e88a9018fc0 27
pferland 4:142c85980a6f 28 // deepsleep consumes slightly less current than sleep
pferland 4:142c85980a6f 29 // in sleep mode, IO state is maintained, RAM is retained, and application will resume after waking up
pferland 4:142c85980a6f 30 // in deepsleep mode, IOs float, RAM is lost, and application will start from beginning after waking up
pferland 4:142c85980a6f 31 // if deep_sleep == true, device will enter deepsleep mode
pferland 4:142c85980a6f 32 static bool deep_sleep = false;
pferland 4:142c85980a6f 33
pferland 0:9e88a9018fc0 34 mDot *dot = NULL;
pferland 0:9e88a9018fc0 35
pferland 0:9e88a9018fc0 36 int main()
pferland 0:9e88a9018fc0 37 {
pferland 4:142c85980a6f 38 Serial pc(USBTX, USBRX);
pferland 4:142c85980a6f 39
pferland 4:142c85980a6f 40 /* Instantiate the expansion board */
pferland 4:142c85980a6f 41 X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(I2C_SDA, I2C_SCL, PC_1);
pferland 4:142c85980a6f 42
pferland 4:142c85980a6f 43 /* Retrieve the composing elements of the expansion board */
pferland 4:142c85980a6f 44 GyroSensor *gyroscope = mems_expansion_board->GetGyroscope();
pferland 4:142c85980a6f 45 MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer();
pferland 4:142c85980a6f 46 MagneticSensor *magnetometer = mems_expansion_board->magnetometer;
pferland 4:142c85980a6f 47 HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;
pferland 4:142c85980a6f 48 PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor;
pferland 4:142c85980a6f 49 TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor;
pferland 4:142c85980a6f 50 TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor;
pferland 0:9e88a9018fc0 51 // Custom event handler for automatically displaying RX data
pferland 0:9e88a9018fc0 52 RadioEvent events;
pferland 0:9e88a9018fc0 53 pc.baud(115200);
pferland 0:9e88a9018fc0 54
pferland 0:9e88a9018fc0 55 /* Initialize mDot */
pferland 0:9e88a9018fc0 56 dot = mDot::getInstance();
pferland 8:bfbc3dd47166 57
pferland 8:bfbc3dd47166 58 //dot->setAdr(true);
pferland 4:142c85980a6f 59 mts::MTSLog::setLogLevel(mts::MTSLog::INFO_LEVEL);
pferland 0:9e88a9018fc0 60 dot->setEvents(&events);
pferland 0:9e88a9018fc0 61
pferland 0:9e88a9018fc0 62
pferland 0:9e88a9018fc0 63 if (!dot->getStandbyFlag()) {
pferland 0:9e88a9018fc0 64 logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
pferland 0:9e88a9018fc0 65 // start from a well-known state
pferland 0:9e88a9018fc0 66 logInfo("defaulting Dot configuration");
pferland 0:9e88a9018fc0 67 dot->resetConfig();
pferland 0:9e88a9018fc0 68 dot->resetNetworkSession();
pferland 0:9e88a9018fc0 69
pferland 0:9e88a9018fc0 70 // update configuration if necessary
pferland 0:9e88a9018fc0 71 // in AUTO_OTA mode the session is automatically saved, so saveNetworkSession and restoreNetworkSession are not needed
pferland 0:9e88a9018fc0 72 if (dot->getJoinMode() != mDot::AUTO_OTA) {
pferland 0:9e88a9018fc0 73 logInfo("changing network join mode to AUTO_OTA");
pferland 0:9e88a9018fc0 74 if (dot->setJoinMode(mDot::AUTO_OTA) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 75 logError("failed to set network join mode to AUTO_OTA");
pferland 0:9e88a9018fc0 76 }
pferland 0:9e88a9018fc0 77 }
pferland 8:bfbc3dd47166 78
pferland 8:bfbc3dd47166 79 uint32_t current_tx_datarate = dot->getTxDataRate();
pferland 8:bfbc3dd47166 80 if (current_tx_datarate != tx_datarate) {
pferland 8:bfbc3dd47166 81 logInfo("changing TX datarate from %u to %u", current_tx_datarate, tx_datarate);
pferland 8:bfbc3dd47166 82 if (dot->setTxDataRate(tx_datarate) != mDot::MDOT_OK) {
pferland 8:bfbc3dd47166 83 logError("failed to set TX datarate to %u", tx_datarate);
pferland 8:bfbc3dd47166 84 }
pferland 8:bfbc3dd47166 85 }
pferland 0:9e88a9018fc0 86 // 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 87 // only one method or the other should be used!
pferland 0:9e88a9018fc0 88 // network ID = crc64(network name)
pferland 0:9e88a9018fc0 89 // network KEY = cmac(network passphrase)
pferland 4:142c85980a6f 90 update_ota_config_id_key(network_id, network_key, frequency_sub_band, public_network, ack);
pferland 4:142c85980a6f 91 // update_ota_config_name_phrase(network_name, network_passphrase, frequency_sub_band, public_network, ack);
pferland 0:9e88a9018fc0 92
pferland 0:9e88a9018fc0 93 // configure network link checks
pferland 0:9e88a9018fc0 94 // 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 95 // check the link every count packets
pferland 0:9e88a9018fc0 96 // declare the Dot disconnected after threshold failed link checks
pferland 0:9e88a9018fc0 97 // for count = 3 and threshold = 5, the Dot will be considered disconnected after 15 missed packets in a row
pferland 0:9e88a9018fc0 98 update_network_link_check_config(3, 5);
pferland 0:9e88a9018fc0 99
pferland 0:9e88a9018fc0 100 // save changes to configuration
pferland 0:9e88a9018fc0 101 logInfo("saving configuration");
pferland 0:9e88a9018fc0 102 if (!dot->saveConfig()) {
pferland 0:9e88a9018fc0 103 logError("failed to save configuration");
pferland 0:9e88a9018fc0 104 }
pferland 0:9e88a9018fc0 105
pferland 0:9e88a9018fc0 106 // display configuration
pferland 0:9e88a9018fc0 107 display_config();
pferland 0:9e88a9018fc0 108 } else {
pferland 0:9e88a9018fc0 109 // restore the saved session if the dot woke from deepsleep mode
pferland 0:9e88a9018fc0 110 // useful to use with deepsleep because session info is otherwise lost when the dot enters deepsleep
pferland 0:9e88a9018fc0 111 logInfo("restoring network session from NVM");
pferland 0:9e88a9018fc0 112 dot->restoreNetworkSession();
pferland 0:9e88a9018fc0 113 }
pferland 3:d34798ffcaf8 114
pferland 3:d34798ffcaf8 115
pferland 0:9e88a9018fc0 116
pferland 0:9e88a9018fc0 117 while (true) {
pferland 0:9e88a9018fc0 118 std::vector<uint8_t> tx_data;
pferland 0:9e88a9018fc0 119
pferland 0:9e88a9018fc0 120 // join network if not joined
pferland 0:9e88a9018fc0 121 if (!dot->getNetworkJoinStatus()) {
pferland 0:9e88a9018fc0 122 join_network();
pferland 0:9e88a9018fc0 123 }
pferland 7:d2052933ebcb 124
pferland 0:9e88a9018fc0 125 //temp floats
pferland 0:9e88a9018fc0 126 float value1, value2;
pferland 4:142c85980a6f 127
pferland 0:9e88a9018fc0 128 // HTS221 Humidity sensor
pferland 0:9e88a9018fc0 129 temp_sensor1->GetTemperature(&value1);
pferland 0:9e88a9018fc0 130 humidity_sensor->GetHumidity(&value2);
pferland 4:142c85980a6f 131
pferland 0:9e88a9018fc0 132 //serialize data and append to packet
pferland 0:9e88a9018fc0 133 tx_data.push_back(uint8_t(0xFF & *((uint32_t*)(&value1))));
pferland 0:9e88a9018fc0 134 tx_data.push_back(uint8_t((0xFF << 2 ) & *((uint32_t*)(&value1))));
pferland 0:9e88a9018fc0 135 tx_data.push_back(uint8_t((0xFF << 4 ) & *((uint32_t*)(&value1))));
pferland 0:9e88a9018fc0 136 tx_data.push_back(uint8_t((0xFF << 6 ) & *((uint32_t*)(&value1))));
pferland 4:142c85980a6f 137 logInfo("Temperature data %f", value1);
pferland 4:142c85980a6f 138
pferland 4:142c85980a6f 139 // Get accelerometer data, but we're only interested in the Z.
pferland 4:142c85980a6f 140 int32_t accel_vector[3];
pferland 4:142c85980a6f 141 accelerometer->Get_X_Axes(accel_vector);
pferland 4:142c85980a6f 142 logInfo("Acclerometer Z axis: %d", accel_vector[2]);
pferland 4:142c85980a6f 143
pferland 4:142c85980a6f 144 tx_data.push_back(uint8_t(0xFF & accel_vector[2]));
pferland 4:142c85980a6f 145 tx_data.push_back(uint8_t((0xFF << 2 ) & accel_vector[2]));
pferland 4:142c85980a6f 146 tx_data.push_back(uint8_t((0xFF << 4 ) & accel_vector[2]));
pferland 4:142c85980a6f 147 tx_data.push_back(uint8_t((0xFF << 6 ) & accel_vector[2]));
pferland 4:142c85980a6f 148
pferland 0:9e88a9018fc0 149 send_data(tx_data);
pferland 0:9e88a9018fc0 150
pferland 0:9e88a9018fc0 151 // if going into deepsleep mode, save the session so we don't need to join again after waking up
pferland 0:9e88a9018fc0 152 // not necessary if going into sleep mode since RAM is retained
pferland 0:9e88a9018fc0 153 logInfo("saving network session to NVM");
pferland 0:9e88a9018fc0 154 dot->saveNetworkSession();
pferland 0:9e88a9018fc0 155
pferland 0:9e88a9018fc0 156
pferland 0:9e88a9018fc0 157 // ONLY ONE of the three functions below should be uncommented depending on the desired wakeup method
pferland 6:9e6ac13de3e9 158 sleep_wake_rtc_only(deep_sleep);
pferland 0:9e88a9018fc0 159 //sleep_wake_interrupt_only(deep_sleep);
pferland 6:9e6ac13de3e9 160 //sleep_wake_rtc_or_interrupt(deep_sleep);
pferland 0:9e88a9018fc0 161
pferland 0:9e88a9018fc0 162 }
pferland 0:9e88a9018fc0 163
pferland 0:9e88a9018fc0 164 return 0;
pferland 0:9e88a9018fc0 165 }