Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: libmDot-dev-mbed2-deprecated mbed-rtos mbed
Fork of mDot_LoRa_PEER_TO_PEER by
This example will setup a peer to peer node, copy program to two dots Uplink packets will be sent every 5 seconds, however communication is half-duplex An mDot cannot receive while transmitting
This example also demonstrates asynchronous receive through libmDot using the event framework.
Received packets will be sent to the Serial port on pins 2 and 3 baud rate for serial ports is set to 115200
main.cpp@6:ebaf55285f73, 2016-07-15 (annotated)
- Committer:
- jreiss
- Date:
- Fri Jul 15 13:55:27 2016 +0000
- Revision:
- 6:ebaf55285f73
- Parent:
- 5:1ad91719506b
- Child:
- 7:30602a4a9902
modify to peer to peer example
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| mfiore | 0:5ec8b39fcf53 | 1 | #include "mbed.h" |
| mfiore | 0:5ec8b39fcf53 | 2 | #include "mDot.h" |
| jreiss | 5:1ad91719506b | 3 | #include "mDotEvent.h" |
| mfiore | 4:ac599fe6bc41 | 4 | #include "MTSLog.h" |
| mfiore | 0:5ec8b39fcf53 | 5 | #include <string> |
| mfiore | 0:5ec8b39fcf53 | 6 | #include <vector> |
| mfiore | 4:ac599fe6bc41 | 7 | #include <algorithm> |
| mfiore | 0:5ec8b39fcf53 | 8 | |
| jreiss | 6:ebaf55285f73 | 9 | // This example will setup a peer to peer node, copy program to two dots |
| jreiss | 6:ebaf55285f73 | 10 | // Uplink packets will be sent every 5 seconds |
| jreiss | 5:1ad91719506b | 11 | // Received packets will be sent to the Serial port on pins 2 and 3 |
| jreiss | 5:1ad91719506b | 12 | // baud rate for serial ports is set to 115200 |
| jreiss | 5:1ad91719506b | 13 | |
| jreiss | 5:1ad91719506b | 14 | |
| jreiss | 5:1ad91719506b | 15 | Serial _serial(XBEE_DOUT, XBEE_DIN); |
| jreiss | 5:1ad91719506b | 16 | Serial debug(USBTX, USBRX); |
| jreiss | 5:1ad91719506b | 17 | |
| jreiss | 6:ebaf55285f73 | 18 | static uint8_t config_network_addr[] = { 0x01, 0x02, 0x03, 0x04 }; |
| jreiss | 6:ebaf55285f73 | 19 | static uint8_t config_network_nskey[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }; |
| jreiss | 6:ebaf55285f73 | 20 | static uint8_t config_network_dskey[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }; |
| jreiss | 6:ebaf55285f73 | 21 | |
| jreiss | 5:1ad91719506b | 22 | // Custom event handler for receiving Class C packets |
| jreiss | 5:1ad91719506b | 23 | |
| jreiss | 5:1ad91719506b | 24 | class RadioEvent : public mDotEvent |
| jreiss | 5:1ad91719506b | 25 | { |
| jreiss | 5:1ad91719506b | 26 | |
| jreiss | 5:1ad91719506b | 27 | |
| jreiss | 5:1ad91719506b | 28 | public: |
| jreiss | 5:1ad91719506b | 29 | RadioEvent() {} |
| jreiss | 5:1ad91719506b | 30 | |
| jreiss | 5:1ad91719506b | 31 | virtual ~RadioEvent() {} |
| jreiss | 5:1ad91719506b | 32 | |
| jreiss | 5:1ad91719506b | 33 | /*! |
| jreiss | 5:1ad91719506b | 34 | * MAC layer event callback prototype. |
| jreiss | 5:1ad91719506b | 35 | * |
| jreiss | 5:1ad91719506b | 36 | * \param [IN] flags Bit field indicating the MAC events occurred |
| jreiss | 5:1ad91719506b | 37 | * \param [IN] info Details about MAC events occurred |
| jreiss | 5:1ad91719506b | 38 | */ |
| jreiss | 5:1ad91719506b | 39 | virtual void MacEvent(LoRaMacEventFlags* flags, LoRaMacEventInfo* info) { |
| mfiore | 0:5ec8b39fcf53 | 40 | |
| jreiss | 5:1ad91719506b | 41 | if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) { |
| jreiss | 5:1ad91719506b | 42 | std::string msg = "OK"; |
| jreiss | 5:1ad91719506b | 43 | switch (info->Status) { |
| jreiss | 5:1ad91719506b | 44 | case LORAMAC_EVENT_INFO_STATUS_ERROR: |
| jreiss | 5:1ad91719506b | 45 | msg = "ERROR"; |
| jreiss | 5:1ad91719506b | 46 | break; |
| jreiss | 5:1ad91719506b | 47 | case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT: |
| jreiss | 5:1ad91719506b | 48 | msg = "TX_TIMEOUT"; |
| jreiss | 5:1ad91719506b | 49 | break; |
| jreiss | 5:1ad91719506b | 50 | case LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT: |
| jreiss | 5:1ad91719506b | 51 | msg = "RX_TIMEOUT"; |
| jreiss | 5:1ad91719506b | 52 | break; |
| jreiss | 5:1ad91719506b | 53 | case LORAMAC_EVENT_INFO_STATUS_RX_ERROR: |
| jreiss | 5:1ad91719506b | 54 | msg = "RX_ERROR"; |
| jreiss | 5:1ad91719506b | 55 | break; |
| jreiss | 5:1ad91719506b | 56 | case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL: |
| jreiss | 5:1ad91719506b | 57 | msg = "JOIN_FAIL"; |
| jreiss | 5:1ad91719506b | 58 | break; |
| jreiss | 5:1ad91719506b | 59 | case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL: |
| jreiss | 5:1ad91719506b | 60 | msg = "DOWNLINK_FAIL"; |
| jreiss | 5:1ad91719506b | 61 | break; |
| jreiss | 5:1ad91719506b | 62 | case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL: |
| jreiss | 5:1ad91719506b | 63 | msg = "ADDRESS_FAIL"; |
| jreiss | 5:1ad91719506b | 64 | break; |
| jreiss | 5:1ad91719506b | 65 | case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL: |
| jreiss | 5:1ad91719506b | 66 | msg = "MIC_FAIL"; |
| jreiss | 5:1ad91719506b | 67 | break; |
| jreiss | 5:1ad91719506b | 68 | default: |
| jreiss | 5:1ad91719506b | 69 | break; |
| jreiss | 5:1ad91719506b | 70 | } |
| jreiss | 5:1ad91719506b | 71 | logTrace("Event: %s", msg.c_str()); |
| jreiss | 5:1ad91719506b | 72 | |
| jreiss | 5:1ad91719506b | 73 | logTrace("Flags Tx: %d Rx: %d RxData: %d RxSlot: %d LinkCheck: %d JoinAccept: %d", |
| jreiss | 5:1ad91719506b | 74 | flags->Bits.Tx, flags->Bits.Rx, flags->Bits.RxData, flags->Bits.RxSlot, flags->Bits.LinkCheck, flags->Bits.JoinAccept); |
| jreiss | 5:1ad91719506b | 75 | logTrace("Info: Status: %d ACK: %d Retries: %d TxDR: %d RxPort: %d RxSize: %d RSSI: %d SNR: %d Energy: %d Margin: %d Gateways: %d", |
| jreiss | 5:1ad91719506b | 76 | info->Status, info->TxAckReceived, info->TxNbRetries, info->TxDatarate, info->RxPort, info->RxBufferSize, |
| jreiss | 5:1ad91719506b | 77 | info->RxRssi, info->RxSnr, info->Energy, info->DemodMargin, info->NbGateways); |
| jreiss | 5:1ad91719506b | 78 | } |
| jreiss | 5:1ad91719506b | 79 | |
| jreiss | 5:1ad91719506b | 80 | if (flags->Bits.Rx) { |
| jreiss | 6:ebaf55285f73 | 81 | |
| jreiss | 5:1ad91719506b | 82 | logDebug("Rx %d bytes", info->RxBufferSize); |
| jreiss | 5:1ad91719506b | 83 | if (info->RxBufferSize > 0) { |
| jreiss | 6:ebaf55285f73 | 84 | |
| jreiss | 5:1ad91719506b | 85 | for (int i = 0; i < info->RxBufferSize; i++) { |
| jreiss | 5:1ad91719506b | 86 | _serial.putc(info->RxBuffer[i]); |
| jreiss | 5:1ad91719506b | 87 | } |
| jreiss | 5:1ad91719506b | 88 | } |
| jreiss | 6:ebaf55285f73 | 89 | |
| jreiss | 5:1ad91719506b | 90 | delete[] info->RxBuffer; |
| jreiss | 5:1ad91719506b | 91 | } |
| jreiss | 5:1ad91719506b | 92 | } |
| jreiss | 5:1ad91719506b | 93 | }; |
| jreiss | 5:1ad91719506b | 94 | |
| jreiss | 5:1ad91719506b | 95 | |
| jreiss | 5:1ad91719506b | 96 | int main() |
| jreiss | 5:1ad91719506b | 97 | { |
| mfiore | 0:5ec8b39fcf53 | 98 | int32_t ret; |
| mfiore | 0:5ec8b39fcf53 | 99 | mDot* dot; |
| mfiore | 0:5ec8b39fcf53 | 100 | std::vector<uint8_t> data; |
| mfiore | 4:ac599fe6bc41 | 101 | std::string data_str = "hello!"; |
| jreiss | 5:1ad91719506b | 102 | |
| jreiss | 5:1ad91719506b | 103 | RadioEvent events; |
| jreiss | 5:1ad91719506b | 104 | |
| jreiss | 5:1ad91719506b | 105 | debug.baud(115200); |
| jreiss | 5:1ad91719506b | 106 | _serial.baud(115200); |
| jreiss | 5:1ad91719506b | 107 | |
| mfiore | 0:5ec8b39fcf53 | 108 | // get a mDot handle |
| mfiore | 0:5ec8b39fcf53 | 109 | dot = mDot::getInstance(); |
| jreiss | 5:1ad91719506b | 110 | |
| jreiss | 5:1ad91719506b | 111 | // Set custom events handler for receiving Class C packets |
| jreiss | 5:1ad91719506b | 112 | dot->setEvents(&events); |
| jreiss | 5:1ad91719506b | 113 | |
| mfiore | 0:5ec8b39fcf53 | 114 | // print library version information |
| mfiore | 0:5ec8b39fcf53 | 115 | logInfo("version: %s", dot->getId().c_str()); |
| mfiore | 0:5ec8b39fcf53 | 116 | |
| jreiss | 6:ebaf55285f73 | 117 | //******************************************* |
| jreiss | 6:ebaf55285f73 | 118 | // configuration |
| jreiss | 6:ebaf55285f73 | 119 | //******************************************* |
| jreiss | 6:ebaf55285f73 | 120 | // reset to default config so we know what state we're in |
| jreiss | 6:ebaf55285f73 | 121 | dot->resetConfig(); |
| jreiss | 5:1ad91719506b | 122 | |
| jreiss | 6:ebaf55285f73 | 123 | dot->setLogLevel(mts::MTSLog::TRACE_LEVEL); |
| jreiss | 5:1ad91719506b | 124 | |
| jreiss | 6:ebaf55285f73 | 125 | // set up the mDot with our network information: Network Address and Session Keys must match on each device |
| jreiss | 6:ebaf55285f73 | 126 | // these can all be saved in NVM so they don't need to be set every time - see mDot::saveConfig() |
| jreiss | 6:ebaf55285f73 | 127 | std::vector<uint8_t> temp; |
| jreiss | 5:1ad91719506b | 128 | |
| jreiss | 6:ebaf55285f73 | 129 | for (int i = 0; i < 4; i++) { |
| jreiss | 6:ebaf55285f73 | 130 | temp.push_back(config_network_addr[i]); |
| jreiss | 6:ebaf55285f73 | 131 | } |
| jreiss | 6:ebaf55285f73 | 132 | |
| jreiss | 6:ebaf55285f73 | 133 | logInfo("setting network addr"); |
| jreiss | 6:ebaf55285f73 | 134 | if ((ret = dot->setNetworkAddress(temp)) != mDot::MDOT_OK) { |
| jreiss | 6:ebaf55285f73 | 135 | logError("failed to set network name %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
| jreiss | 6:ebaf55285f73 | 136 | } |
| jreiss | 5:1ad91719506b | 137 | |
| jreiss | 6:ebaf55285f73 | 138 | temp.clear(); |
| jreiss | 6:ebaf55285f73 | 139 | for (int i = 0; i < 16; i++) { |
| jreiss | 6:ebaf55285f73 | 140 | temp.push_back(config_network_nskey[i]); |
| jreiss | 6:ebaf55285f73 | 141 | } |
| jreiss | 5:1ad91719506b | 142 | |
| jreiss | 6:ebaf55285f73 | 143 | logInfo("setting network password"); |
| jreiss | 6:ebaf55285f73 | 144 | if ((ret = dot->setNetworkSessionKey(temp)) != mDot::MDOT_OK) { |
| jreiss | 6:ebaf55285f73 | 145 | logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
| jreiss | 6:ebaf55285f73 | 146 | } |
| mfiore | 1:f2e840f754c8 | 147 | |
| jreiss | 6:ebaf55285f73 | 148 | temp.clear(); |
| jreiss | 6:ebaf55285f73 | 149 | for (int i = 0; i < 16; i++) { |
| jreiss | 6:ebaf55285f73 | 150 | temp.push_back(config_network_dskey[i]); |
| jreiss | 6:ebaf55285f73 | 151 | } |
| jreiss | 5:1ad91719506b | 152 | |
| jreiss | 6:ebaf55285f73 | 153 | logInfo("setting network password"); |
| jreiss | 6:ebaf55285f73 | 154 | if ((ret = dot->setDataSessionKey(temp)) != mDot::MDOT_OK) { |
| jreiss | 6:ebaf55285f73 | 155 | logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
| jreiss | 6:ebaf55285f73 | 156 | } |
| jreiss | 6:ebaf55285f73 | 157 | |
| jreiss | 6:ebaf55285f73 | 158 | logInfo("setting TX frequency"); |
| jreiss | 6:ebaf55285f73 | 159 | if ((ret = dot->setTxFrequency(915500000)) != mDot::MDOT_OK) { |
| jreiss | 6:ebaf55285f73 | 160 | logError("failed to set TX frequency %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
| jreiss | 6:ebaf55285f73 | 161 | } |
| jreiss | 5:1ad91719506b | 162 | |
| jreiss | 6:ebaf55285f73 | 163 | // a higher spreading factor allows for longer range but lower throughput |
| jreiss | 6:ebaf55285f73 | 164 | // in the 915 (US) frequency band, DR8-DR13 |
| jreiss | 6:ebaf55285f73 | 165 | logInfo("setting TX spreading factor"); |
| jreiss | 6:ebaf55285f73 | 166 | if ((ret = dot->setTxDataRate(mDot::DR13)) != mDot::MDOT_OK) { |
| jreiss | 6:ebaf55285f73 | 167 | logError("failed to set TX datarate %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
| jreiss | 6:ebaf55285f73 | 168 | } |
| jreiss | 5:1ad91719506b | 169 | |
| jreiss | 6:ebaf55285f73 | 170 | // set join mode to AUTO_OTA so the mDot doesn't have to rejoin after sleeping |
| jreiss | 6:ebaf55285f73 | 171 | logInfo("setting join mode to AUTO_OTA"); |
| jreiss | 6:ebaf55285f73 | 172 | if ((ret = dot->setJoinMode(mDot::PEER_TO_PEER)) != mDot::MDOT_OK) { |
| jreiss | 6:ebaf55285f73 | 173 | logError("failed to set join mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
| jreiss | 6:ebaf55285f73 | 174 | } |
| jreiss | 5:1ad91719506b | 175 | |
| jreiss | 6:ebaf55285f73 | 176 | // save this configuration to the mDot's NVM |
| jreiss | 6:ebaf55285f73 | 177 | logInfo("saving config"); |
| jreiss | 6:ebaf55285f73 | 178 | if (! dot->saveConfig()) { |
| jreiss | 6:ebaf55285f73 | 179 | logError("failed to save configuration"); |
| jreiss | 6:ebaf55285f73 | 180 | } |
| jreiss | 5:1ad91719506b | 181 | |
| mfiore | 1:f2e840f754c8 | 182 | //******************************************* |
| mfiore | 1:f2e840f754c8 | 183 | // end of configuration |
| mfiore | 1:f2e840f754c8 | 184 | //******************************************* |
| mfiore | 0:5ec8b39fcf53 | 185 | |
| mfiore | 0:5ec8b39fcf53 | 186 | // format data for sending to the gateway |
| mfiore | 0:5ec8b39fcf53 | 187 | for (std::string::iterator it = data_str.begin(); it != data_str.end(); it++) |
| mfiore | 0:5ec8b39fcf53 | 188 | data.push_back((uint8_t) *it); |
| mfiore | 0:5ec8b39fcf53 | 189 | |
| jreiss | 5:1ad91719506b | 190 | while(true) { |
| jreiss | 6:ebaf55285f73 | 191 | // send the data |
| jreiss | 6:ebaf55285f73 | 192 | if ((ret = dot->send(data)) != mDot::MDOT_OK) { |
| jreiss | 6:ebaf55285f73 | 193 | logError("failed to send %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
| jreiss | 6:ebaf55285f73 | 194 | } else { |
| jreiss | 6:ebaf55285f73 | 195 | logInfo("successfully sent data to peer"); |
| jreiss | 5:1ad91719506b | 196 | } |
| jreiss | 5:1ad91719506b | 197 | |
| jreiss | 6:ebaf55285f73 | 198 | wait(5.0); |
| mfiore | 0:5ec8b39fcf53 | 199 | } |
| mfiore | 0:5ec8b39fcf53 | 200 | |
| mfiore | 0:5ec8b39fcf53 | 201 | return 0; |
| mfiore | 0:5ec8b39fcf53 | 202 | } |
