Demonstrates how to connect to Senet LoRaWAN Network and send data
Dependencies: libmDot mbed-rtos mbed
main.cpp@1:cf44cafafa48, 2016-05-20 (annotated)
- Committer:
- shaunkrnelson
- Date:
- Fri May 20 13:22:39 2016 +0000
- Revision:
- 1:cf44cafafa48
- Parent:
- 0:b6af80e4feef
Update dev portal URL
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
shaunkrnelson | 0:b6af80e4feef | 1 | |
shaunkrnelson | 0:b6af80e4feef | 2 | /*************************************************************************************************************** |
shaunkrnelson | 0:b6af80e4feef | 3 | * Senet is the leading IoT network services provider for low cost, long range IoT applications. * |
shaunkrnelson | 0:b6af80e4feef | 4 | * Senet provides network services for application developers who are searching for an affordable IoT * |
shaunkrnelson | 0:b6af80e4feef | 5 | * network to launch and scale their solutions. * |
shaunkrnelson | 0:b6af80e4feef | 6 | * * |
shaunkrnelson | 0:b6af80e4feef | 7 | * This program demonstrates how to connect to Senet's public network with an mDot and sends some data * |
shaunkrnelson | 0:b6af80e4feef | 8 | * * |
shaunkrnelson | 0:b6af80e4feef | 9 | * On the Senet Developer Portal website you can view device transactions and even configure forwarding * |
shaunkrnelson | 0:b6af80e4feef | 10 | * to IoT data collection and analysis services. * |
shaunkrnelson | 0:b6af80e4feef | 11 | * * |
shaunkrnelson | 1:cf44cafafa48 | 12 | * Get started by registering for a Senet Developer Portal account at http://portal.senetco.com * |
shaunkrnelson | 0:b6af80e4feef | 13 | ****************************************************************************************************************/ |
shaunkrnelson | 0:b6af80e4feef | 14 | |
shaunkrnelson | 0:b6af80e4feef | 15 | #include "mbed.h" |
shaunkrnelson | 0:b6af80e4feef | 16 | #include "mDot.h" |
shaunkrnelson | 0:b6af80e4feef | 17 | #include "MTSLog.h" |
shaunkrnelson | 0:b6af80e4feef | 18 | #include <string> |
shaunkrnelson | 0:b6af80e4feef | 19 | #include <vector> |
shaunkrnelson | 0:b6af80e4feef | 20 | #include <algorithm> |
shaunkrnelson | 0:b6af80e4feef | 21 | |
shaunkrnelson | 0:b6af80e4feef | 22 | // Senet Developer Portal Application EUI |
shaunkrnelson | 0:b6af80e4feef | 23 | static uint8_t senetDevPortalAppEUI[8] = {0x00,0x25,0x0C,0x00,0x00,0x01,0x00,0x01}; |
shaunkrnelson | 0:b6af80e4feef | 24 | |
shaunkrnelson | 0:b6af80e4feef | 25 | // Your Device's application key provided by Senet on the Device setup page |
shaunkrnelson | 0:b6af80e4feef | 26 | static uint8_t senetDevPortalAppKey[16] = {0xCA,0x40,0x36,0xB8,0xB2,0xB3,0x9F,0x4F,0xAB,0x84,0xD7,0xB3,0x65,0x8C,0x80,0xD3}; |
shaunkrnelson | 0:b6af80e4feef | 27 | |
shaunkrnelson | 0:b6af80e4feef | 28 | // Helper macro to initialize std::vector from array |
shaunkrnelson | 0:b6af80e4feef | 29 | #define INIT_FROM_ARRAY(ar) ar, ar + sizeof(ar) / sizeof(ar[0]) |
shaunkrnelson | 0:b6af80e4feef | 30 | |
shaunkrnelson | 0:b6af80e4feef | 31 | // Uncomment this line if using a full sized UDK2.0 instead of a Micro UDK |
shaunkrnelson | 0:b6af80e4feef | 32 | #define UDK2 1 |
shaunkrnelson | 0:b6af80e4feef | 33 | #ifdef UDK2 |
shaunkrnelson | 0:b6af80e4feef | 34 | DigitalOut led(LED1); |
shaunkrnelson | 0:b6af80e4feef | 35 | DigitalOut tx_led(PA_1); |
shaunkrnelson | 0:b6af80e4feef | 36 | #else |
shaunkrnelson | 0:b6af80e4feef | 37 | DigitalOut led(XBEE_RSSI); |
shaunkrnelson | 0:b6af80e4feef | 38 | #endif |
shaunkrnelson | 0:b6af80e4feef | 39 | |
shaunkrnelson | 0:b6af80e4feef | 40 | // Led blink ticker |
shaunkrnelson | 0:b6af80e4feef | 41 | Ticker tick; |
shaunkrnelson | 0:b6af80e4feef | 42 | |
shaunkrnelson | 0:b6af80e4feef | 43 | // LED states |
shaunkrnelson | 0:b6af80e4feef | 44 | #define OFF 1 |
shaunkrnelson | 0:b6af80e4feef | 45 | #define ON 0 |
shaunkrnelson | 0:b6af80e4feef | 46 | |
shaunkrnelson | 0:b6af80e4feef | 47 | // Ticker callback function to change LED state |
shaunkrnelson | 0:b6af80e4feef | 48 | void blink() { |
shaunkrnelson | 0:b6af80e4feef | 49 | led = !led; |
shaunkrnelson | 0:b6af80e4feef | 50 | } |
shaunkrnelson | 0:b6af80e4feef | 51 | |
shaunkrnelson | 0:b6af80e4feef | 52 | |
shaunkrnelson | 0:b6af80e4feef | 53 | int main() { |
shaunkrnelson | 0:b6af80e4feef | 54 | int32_t ret; |
shaunkrnelson | 0:b6af80e4feef | 55 | mDot* dot; |
shaunkrnelson | 0:b6af80e4feef | 56 | std::vector<uint8_t> data; |
shaunkrnelson | 0:b6af80e4feef | 57 | std::string data_str = "hello!"; |
shaunkrnelson | 0:b6af80e4feef | 58 | std::vector<uint8_t> appEUI(INIT_FROM_ARRAY(senetDevPortalAppEUI)); |
shaunkrnelson | 0:b6af80e4feef | 59 | std::vector<uint8_t> appKey(INIT_FROM_ARRAY(senetDevPortalAppKey)); |
shaunkrnelson | 0:b6af80e4feef | 60 | |
shaunkrnelson | 0:b6af80e4feef | 61 | // configure the Ticker to blink the LED on 500ms interval while joining network |
shaunkrnelson | 0:b6af80e4feef | 62 | led = OFF; |
shaunkrnelson | 0:b6af80e4feef | 63 | tx_led = OFF; |
shaunkrnelson | 0:b6af80e4feef | 64 | tick.attach(&blink, 0.5); |
shaunkrnelson | 0:b6af80e4feef | 65 | |
shaunkrnelson | 0:b6af80e4feef | 66 | // get a mDot handle |
shaunkrnelson | 0:b6af80e4feef | 67 | dot = mDot::getInstance(); |
shaunkrnelson | 0:b6af80e4feef | 68 | |
shaunkrnelson | 0:b6af80e4feef | 69 | //******************************************* |
shaunkrnelson | 0:b6af80e4feef | 70 | // configuration |
shaunkrnelson | 0:b6af80e4feef | 71 | //******************************************* |
shaunkrnelson | 0:b6af80e4feef | 72 | // reset to default config so we know what state we're in |
shaunkrnelson | 0:b6af80e4feef | 73 | dot->resetConfig(); |
shaunkrnelson | 0:b6af80e4feef | 74 | |
shaunkrnelson | 0:b6af80e4feef | 75 | // Turn on mDot logging - output is on the debug UART at 9600 baud |
shaunkrnelson | 0:b6af80e4feef | 76 | dot->setLogLevel(mts::MTSLog::INFO_LEVEL); |
shaunkrnelson | 0:b6af80e4feef | 77 | |
shaunkrnelson | 0:b6af80e4feef | 78 | // set up the mDot with our network information: frequency sub band, application, application encryption key |
shaunkrnelson | 0:b6af80e4feef | 79 | // these can all be saved in NVM so they don't need to be set every time - see mDot::saveConfig() |
shaunkrnelson | 0:b6af80e4feef | 80 | |
shaunkrnelson | 0:b6af80e4feef | 81 | // Senet is a Public Network |
shaunkrnelson | 0:b6af80e4feef | 82 | if ((ret = dot->setPublicNetwork(true))!= mDot::MDOT_OK) { |
shaunkrnelson | 0:b6af80e4feef | 83 | logError("failed to set public network %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 84 | } |
shaunkrnelson | 0:b6af80e4feef | 85 | |
shaunkrnelson | 0:b6af80e4feef | 86 | // frequency sub band is only applicable in the 915 (US) frequency band |
shaunkrnelson | 0:b6af80e4feef | 87 | // if using a gateway that only supports the first 8 channels, use sub band 1 (channels 1 - 8) |
shaunkrnelson | 0:b6af80e4feef | 88 | // if using a gateway that supports all 64 channels, use sub band 0 - the mDot will use all 64 channels |
shaunkrnelson | 0:b6af80e4feef | 89 | static uint8_t config_frequency_sub_band = 1; |
shaunkrnelson | 0:b6af80e4feef | 90 | logInfo("setting frequency sub band"); |
shaunkrnelson | 0:b6af80e4feef | 91 | if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) { |
shaunkrnelson | 0:b6af80e4feef | 92 | logError("failed to set frequency sub band %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 93 | } |
shaunkrnelson | 0:b6af80e4feef | 94 | |
shaunkrnelson | 0:b6af80e4feef | 95 | // Set Application Id to Senet Developer Portal |
shaunkrnelson | 0:b6af80e4feef | 96 | logInfo("setting application EUI"); |
shaunkrnelson | 0:b6af80e4feef | 97 | if ((ret = dot->setNetworkId(appEUI)) != mDot::MDOT_OK) { |
shaunkrnelson | 0:b6af80e4feef | 98 | logError("failed to set application EUI %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 99 | } |
shaunkrnelson | 0:b6af80e4feef | 100 | |
shaunkrnelson | 0:b6af80e4feef | 101 | // Set AES-128 Application secret key |
shaunkrnelson | 0:b6af80e4feef | 102 | logInfo("setting application key"); |
shaunkrnelson | 0:b6af80e4feef | 103 | if ((ret = dot->setNetworkKey(appKey)) != mDot::MDOT_OK) { |
shaunkrnelson | 0:b6af80e4feef | 104 | logError("failed to set network key %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 105 | } |
shaunkrnelson | 0:b6af80e4feef | 106 | |
shaunkrnelson | 0:b6af80e4feef | 107 | // a higher spreading factor allows for longer range but lower throughput |
shaunkrnelson | 0:b6af80e4feef | 108 | // in the 915 (US) frequency band, spreading factors 7 - 10 are available |
shaunkrnelson | 0:b6af80e4feef | 109 | logInfo("setting TX spreading factor"); |
shaunkrnelson | 0:b6af80e4feef | 110 | if ((ret = dot->setTxDataRate(mDot::SF_10)) != mDot::MDOT_OK) { |
shaunkrnelson | 0:b6af80e4feef | 111 | logError("failed to set TX datarate %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 112 | } |
shaunkrnelson | 0:b6af80e4feef | 113 | |
shaunkrnelson | 0:b6af80e4feef | 114 | // Enable Adaptive Data Rate Control so that the Network server can optimize our data rate and |
shaunkrnelson | 0:b6af80e4feef | 115 | // transmit power for the network |
shaunkrnelson | 0:b6af80e4feef | 116 | if((ret = dot->setAdr(true)) != mDot::MDOT_OK){ |
shaunkrnelson | 0:b6af80e4feef | 117 | logError("failed to set ADR %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 118 | } |
shaunkrnelson | 0:b6af80e4feef | 119 | // Set Join byte order to LSB |
shaunkrnelson | 0:b6af80e4feef | 120 | if((ret = dot->setJoinByteOrder(mDot::LSB)) != mDot::MDOT_OK){ |
shaunkrnelson | 0:b6af80e4feef | 121 | logError("failed to set join LSB byte order %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 122 | } |
shaunkrnelson | 0:b6af80e4feef | 123 | |
shaunkrnelson | 0:b6af80e4feef | 124 | // Set Over The Air Join mode |
shaunkrnelson | 0:b6af80e4feef | 125 | if((ret = dot->setJoinMode(mDot::OTA)) != mDot::MDOT_OK){ |
shaunkrnelson | 0:b6af80e4feef | 126 | logError("failed to set join OTA mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 127 | } |
shaunkrnelson | 0:b6af80e4feef | 128 | |
shaunkrnelson | 0:b6af80e4feef | 129 | // save this configuration to the mDot's NVM |
shaunkrnelson | 0:b6af80e4feef | 130 | logInfo("saving config"); |
shaunkrnelson | 0:b6af80e4feef | 131 | if (! dot->saveConfig()) { |
shaunkrnelson | 0:b6af80e4feef | 132 | logError("failed to save configuration"); |
shaunkrnelson | 0:b6af80e4feef | 133 | } |
shaunkrnelson | 0:b6af80e4feef | 134 | //******************************************* |
shaunkrnelson | 0:b6af80e4feef | 135 | // end of configuration |
shaunkrnelson | 0:b6af80e4feef | 136 | //******************************************* |
shaunkrnelson | 0:b6af80e4feef | 137 | |
shaunkrnelson | 0:b6af80e4feef | 138 | // attempt to join the network |
shaunkrnelson | 0:b6af80e4feef | 139 | logInfo("joining network"); |
shaunkrnelson | 0:b6af80e4feef | 140 | while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) { |
shaunkrnelson | 0:b6af80e4feef | 141 | logError("failed to join network %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 142 | osDelay(5000); |
shaunkrnelson | 0:b6af80e4feef | 143 | } |
shaunkrnelson | 0:b6af80e4feef | 144 | |
shaunkrnelson | 0:b6af80e4feef | 145 | // Detach ticker led callback |
shaunkrnelson | 0:b6af80e4feef | 146 | tick.detach(); |
shaunkrnelson | 0:b6af80e4feef | 147 | |
shaunkrnelson | 0:b6af80e4feef | 148 | // Leave led ON |
shaunkrnelson | 0:b6af80e4feef | 149 | led = ON; |
shaunkrnelson | 0:b6af80e4feef | 150 | |
shaunkrnelson | 0:b6af80e4feef | 151 | // format data to send |
shaunkrnelson | 0:b6af80e4feef | 152 | for (std::string::iterator it = data_str.begin(); it != data_str.end(); it++) |
shaunkrnelson | 0:b6af80e4feef | 153 | data.push_back((uint8_t) *it); |
shaunkrnelson | 0:b6af80e4feef | 154 | |
shaunkrnelson | 0:b6af80e4feef | 155 | while (true) { |
shaunkrnelson | 0:b6af80e4feef | 156 | // send data |
shaunkrnelson | 0:b6af80e4feef | 157 | tx_led = ON; |
shaunkrnelson | 0:b6af80e4feef | 158 | if ((ret = dot->send(data)) != mDot::MDOT_OK) { |
shaunkrnelson | 0:b6af80e4feef | 159 | logError("failed to send", ret, mDot::getReturnCodeString(ret).c_str()); |
shaunkrnelson | 0:b6af80e4feef | 160 | } else { |
shaunkrnelson | 0:b6af80e4feef | 161 | logInfo("successfully sent data on Senet network"); |
shaunkrnelson | 0:b6af80e4feef | 162 | } |
shaunkrnelson | 0:b6af80e4feef | 163 | tx_led = OFF; |
shaunkrnelson | 0:b6af80e4feef | 164 | |
shaunkrnelson | 0:b6af80e4feef | 165 | // Wait before transmitting again |
shaunkrnelson | 0:b6af80e4feef | 166 | osDelay(60000); |
shaunkrnelson | 0:b6af80e4feef | 167 | } |
shaunkrnelson | 0:b6af80e4feef | 168 | } |