Multi-Tech Dot Example for using AnalogIn

Committer:
bdavis
Date:
Wed May 20 15:11:33 2020 +0000
Revision:
0:13355db43bfa
Tested with Dot 3.3.5 library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bdavis 0:13355db43bfa 1 #include "mbed.h"
bdavis 0:13355db43bfa 2 #include "mDot.h"
bdavis 0:13355db43bfa 3 #include "ChannelPlans.h"
bdavis 0:13355db43bfa 4 #include "MTSLog.h"
bdavis 0:13355db43bfa 5 #include "MTSText.h"
bdavis 0:13355db43bfa 6
bdavis 0:13355db43bfa 7
bdavis 0:13355db43bfa 8 // Set GPIO1 for AnalogIn (used to measure analog voltage)
bdavis 0:13355db43bfa 9 AnalogIn tVin(GPIO1);
bdavis 0:13355db43bfa 10
bdavis 0:13355db43bfa 11
bdavis 0:13355db43bfa 12 // Create variables with settings you want.
bdavis 0:13355db43bfa 13 static std::string network_name = "MultiTech";
bdavis 0:13355db43bfa 14 static std::string network_passphrase = "MultiTech";
bdavis 0:13355db43bfa 15 static uint8_t frequency_sub_band = 1;
bdavis 0:13355db43bfa 16 static lora::NetworkType network_type = lora::PUBLIC_LORAWAN;
bdavis 0:13355db43bfa 17 static uint8_t join_delay = 5;
bdavis 0:13355db43bfa 18 static uint8_t ack = 0;
bdavis 0:13355db43bfa 19 static bool adr = true;
bdavis 0:13355db43bfa 20
bdavis 0:13355db43bfa 21
bdavis 0:13355db43bfa 22 // mDot Object
bdavis 0:13355db43bfa 23 mDot* dot = NULL;
bdavis 0:13355db43bfa 24 // Channel Plan object
bdavis 0:13355db43bfa 25 lora::ChannelPlan* plan = NULL;
bdavis 0:13355db43bfa 26
bdavis 0:13355db43bfa 27
bdavis 0:13355db43bfa 28 // Setup the debug port
bdavis 0:13355db43bfa 29 Serial pc(USBTX, USBRX);
bdavis 0:13355db43bfa 30
bdavis 0:13355db43bfa 31
bdavis 0:13355db43bfa 32 void join_network() {
bdavis 0:13355db43bfa 33 int32_t j_attempts = 0;
bdavis 0:13355db43bfa 34 int32_t ret = mDot::MDOT_ERROR;
bdavis 0:13355db43bfa 35
bdavis 0:13355db43bfa 36 // attempt to join the network
bdavis 0:13355db43bfa 37 while (ret != mDot::MDOT_OK) {
bdavis 0:13355db43bfa 38 logInfo("attempt %d to join network", ++j_attempts);
bdavis 0:13355db43bfa 39 logInfo("do Join attempt");
bdavis 0:13355db43bfa 40 ret = dot->joinNetwork();
bdavis 0:13355db43bfa 41 logInfo("Join attempt done");
bdavis 0:13355db43bfa 42 if (ret != mDot::MDOT_OK) {
bdavis 0:13355db43bfa 43 logError("failed to join network %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
bdavis 0:13355db43bfa 44 // in some frequency bands we need to wait until another channel is available before transmitting again
bdavis 0:13355db43bfa 45 uint32_t delay_s = (dot->getNextTxMs() / 1000) + 1;
bdavis 0:13355db43bfa 46 if (delay_s < 5) {
bdavis 0:13355db43bfa 47 logInfo("waiting %lu s until next free channel", delay_s);
bdavis 0:13355db43bfa 48 wait(delay_s);
bdavis 0:13355db43bfa 49 } else {
bdavis 0:13355db43bfa 50 logInfo("sleeping %lu s until next free channel", delay_s);
bdavis 0:13355db43bfa 51 dot->sleep(delay_s, mDot::RTC_ALARM, false);
bdavis 0:13355db43bfa 52 }
bdavis 0:13355db43bfa 53 }
bdavis 0:13355db43bfa 54 }
bdavis 0:13355db43bfa 55 }
bdavis 0:13355db43bfa 56
bdavis 0:13355db43bfa 57 void wait_to_send() {
bdavis 0:13355db43bfa 58 while(!mDot::getInstance()->getIsIdle() ||
bdavis 0:13355db43bfa 59 mDot::getInstance()->getNextTxMs() != 0 ) {
bdavis 0:13355db43bfa 60
bdavis 0:13355db43bfa 61 if (mDot::getInstance()->getNextTxMs() > 1000)
bdavis 0:13355db43bfa 62 wait_ms(mDot::getInstance()->getNextTxMs());
bdavis 0:13355db43bfa 63 else
bdavis 0:13355db43bfa 64 wait_ms(1000);
bdavis 0:13355db43bfa 65 }
bdavis 0:13355db43bfa 66 }
bdavis 0:13355db43bfa 67
bdavis 0:13355db43bfa 68
bdavis 0:13355db43bfa 69 // Function to handle LoRa transmissions
bdavis 0:13355db43bfa 70 void send_packet(std::vector<uint8_t> vData) {
bdavis 0:13355db43bfa 71 // join network if not joined
bdavis 0:13355db43bfa 72 if (!dot->getNetworkJoinStatus()) {
bdavis 0:13355db43bfa 73 logInfo("Joining network");
bdavis 0:13355db43bfa 74 join_network();
bdavis 0:13355db43bfa 75 logInfo("Send Blank Packet");
bdavis 0:13355db43bfa 76 std::vector<uint8_t> tx_blank;
bdavis 0:13355db43bfa 77 wait_to_send();
bdavis 0:13355db43bfa 78 dot->send(tx_blank);
bdavis 0:13355db43bfa 79 }
bdavis 0:13355db43bfa 80 wait_to_send();
bdavis 0:13355db43bfa 81 dot->send(vData);
bdavis 0:13355db43bfa 82 }
bdavis 0:13355db43bfa 83
bdavis 0:13355db43bfa 84 void send_string_packet(std::string sendStr)
bdavis 0:13355db43bfa 85 {
bdavis 0:13355db43bfa 86 std::vector<uint8_t> tx_data;
bdavis 0:13355db43bfa 87 for (std::string::iterator it = sendStr.begin(); it != sendStr.end(); it++)
bdavis 0:13355db43bfa 88 tx_data.push_back((uint8_t) *it);
bdavis 0:13355db43bfa 89 send_packet(tx_data);
bdavis 0:13355db43bfa 90 }
bdavis 0:13355db43bfa 91
bdavis 0:13355db43bfa 92 int main() {
bdavis 0:13355db43bfa 93 // Set baud rate for debug port.
bdavis 0:13355db43bfa 94 pc.baud(115200);
bdavis 0:13355db43bfa 95
bdavis 0:13355db43bfa 96 mts::MTSLog::setLogLevel(mts::MTSLog::INFO_LEVEL);
bdavis 0:13355db43bfa 97
bdavis 0:13355db43bfa 98 // Create new channel plan object
bdavis 0:13355db43bfa 99 plan = new lora::ChannelPlan_US915();
bdavis 0:13355db43bfa 100 assert(plan);
bdavis 0:13355db43bfa 101
bdavis 0:13355db43bfa 102 // Create a mDot object that uses that plan
bdavis 0:13355db43bfa 103 dot = mDot::getInstance(plan);
bdavis 0:13355db43bfa 104 assert(dot);
bdavis 0:13355db43bfa 105
bdavis 0:13355db43bfa 106 // You can now start calling mDot functions using that mDot object dot->function()
bdavis 0:13355db43bfa 107
bdavis 0:13355db43bfa 108 // Default settings and session to start from a well-known state
bdavis 0:13355db43bfa 109 logInfo("defaulting Dot configuration");
bdavis 0:13355db43bfa 110 dot->resetConfig();
bdavis 0:13355db43bfa 111 dot->resetNetworkSession();
bdavis 0:13355db43bfa 112
bdavis 0:13355db43bfa 113 // make sure library logging is turned on
bdavis 0:13355db43bfa 114 dot->setLogLevel(mts::MTSLog::INFO_LEVEL);
bdavis 0:13355db43bfa 115
bdavis 0:13355db43bfa 116 // Configure settings
bdavis 0:13355db43bfa 117
bdavis 0:13355db43bfa 118 // Configure the Join mode to OTA
bdavis 0:13355db43bfa 119 if (dot->setJoinMode(mDot::OTA) != mDot::MDOT_OK) {
bdavis 0:13355db43bfa 120 logError("failed to set network join mode to OTA");
bdavis 0:13355db43bfa 121 }
bdavis 0:13355db43bfa 122
bdavis 0:13355db43bfa 123 // Configure Network Name. If using a Network ID (App-EUI) then use setNetworkId(network_id) instead.
bdavis 0:13355db43bfa 124 if (dot->setNetworkName(network_name) != mDot::MDOT_OK) {
bdavis 0:13355db43bfa 125 logError("failed to set network name to \"%s\"", network_name.c_str());
bdavis 0:13355db43bfa 126 }
bdavis 0:13355db43bfa 127
bdavis 0:13355db43bfa 128 // Configure Network Passphrase. If using a Network Key (App-Key) use setNetworkKey(network_key) instead.
bdavis 0:13355db43bfa 129 if (dot->setNetworkPassphrase(network_passphrase) != mDot::MDOT_OK) {
bdavis 0:13355db43bfa 130 logError("failed to set network passphrase to \"%s\"", network_passphrase.c_str());
bdavis 0:13355db43bfa 131 }
bdavis 0:13355db43bfa 132
bdavis 0:13355db43bfa 133 if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) {
bdavis 0:13355db43bfa 134 logError("failed to set frequency sub band to %u", frequency_sub_band);
bdavis 0:13355db43bfa 135 }
bdavis 0:13355db43bfa 136
bdavis 0:13355db43bfa 137 if (dot->setPublicNetwork(network_type) != mDot::MDOT_OK) {
bdavis 0:13355db43bfa 138 logError("failed to set network type");
bdavis 0:13355db43bfa 139 }
bdavis 0:13355db43bfa 140
bdavis 0:13355db43bfa 141 if (dot->setAck(ack) != mDot::MDOT_OK) {
bdavis 0:13355db43bfa 142 logError("failed to set acks to %u", ack);
bdavis 0:13355db43bfa 143 }
bdavis 0:13355db43bfa 144
bdavis 0:13355db43bfa 145 // enable or disable Adaptive Data Rate
bdavis 0:13355db43bfa 146 dot->setAdr(adr);
bdavis 0:13355db43bfa 147
bdavis 0:13355db43bfa 148 // Configure the join delay
bdavis 0:13355db43bfa 149 dot->setJoinDelay(join_delay);
bdavis 0:13355db43bfa 150
bdavis 0:13355db43bfa 151
bdavis 0:13355db43bfa 152 // save changes to configuration
bdavis 0:13355db43bfa 153 logInfo("saving configuration");
bdavis 0:13355db43bfa 154 if (!dot->saveConfig()) {
bdavis 0:13355db43bfa 155 logError("failed to save configuration");
bdavis 0:13355db43bfa 156 }
bdavis 0:13355db43bfa 157
bdavis 0:13355db43bfa 158
bdavis 0:13355db43bfa 159 int sleep_secs = 10;
bdavis 0:13355db43bfa 160 while (true) {
bdavis 0:13355db43bfa 161 std::vector<uint8_t> tx_data;
bdavis 0:13355db43bfa 162
bdavis 0:13355db43bfa 163 // Read AnalogIn value and calculate voltage.
bdavis 0:13355db43bfa 164 // Max read_u16() value is 65535, and reference voltage is v3.0
bdavis 0:13355db43bfa 165 // voltage = (read_u16() /65535) * 3.0
bdavis 0:13355db43bfa 166 float Vin_Volt = ((float)tVin.read_u16()/65535.0) * 3.0;
bdavis 0:13355db43bfa 167 logInfo("Vin : %u, Voltage: %f", tVin.read_u16(), Vin_Volt);
bdavis 0:13355db43bfa 168
bdavis 0:13355db43bfa 169 // Send Raw AnalogIn Read as 2 bytes
bdavis 0:13355db43bfa 170 uint16_t RawData = tVin.read_u16();
bdavis 0:13355db43bfa 171 tx_data.push_back((RawData >> 8) & 0xFF);
bdavis 0:13355db43bfa 172 tx_data.push_back(RawData & 0xFF);
bdavis 0:13355db43bfa 173 logInfo("Sending Raw AnalogIn Data: [0x%04X]", RawData);
bdavis 0:13355db43bfa 174 send_packet(tx_data);
bdavis 0:13355db43bfa 175
bdavis 0:13355db43bfa 176 tx_data.clear();
bdavis 0:13355db43bfa 177 // Send Float as Bytes
bdavis 0:13355db43bfa 178 unsigned long d = *(unsigned long *)&Vin_Volt;
bdavis 0:13355db43bfa 179 tx_data.push_back((d >> 24) & 0xFF);
bdavis 0:13355db43bfa 180 tx_data.push_back((d >> 16) & 0xFF);
bdavis 0:13355db43bfa 181 tx_data.push_back((d >> 8) & 0xFF);
bdavis 0:13355db43bfa 182 tx_data.push_back(d & 0xFF);
bdavis 0:13355db43bfa 183 logInfo("Sending Float as 4 bytes: [0x%08X]", d);
bdavis 0:13355db43bfa 184 send_packet(tx_data);
bdavis 0:13355db43bfa 185
bdavis 0:13355db43bfa 186
bdavis 0:13355db43bfa 187 // Send Vin as a readable string
bdavis 0:13355db43bfa 188 std::string strVin = std::to_string(Vin_Volt);
bdavis 0:13355db43bfa 189 logInfo("Sending Voltage as String: %s", strVin.c_str());
bdavis 0:13355db43bfa 190 send_string_packet(strVin);
bdavis 0:13355db43bfa 191
bdavis 0:13355db43bfa 192
bdavis 0:13355db43bfa 193 // sleep
bdavis 0:13355db43bfa 194 // Wait for mDot to become idle before sleeping
bdavis 0:13355db43bfa 195 while (true) {
bdavis 0:13355db43bfa 196 if (dot->getIsIdle()) {
bdavis 0:13355db43bfa 197 break;
bdavis 0:13355db43bfa 198 }
bdavis 0:13355db43bfa 199 wait_ms(10);
bdavis 0:13355db43bfa 200 }
bdavis 0:13355db43bfa 201 logInfo("Sleeping for %d seconds.", sleep_secs);
bdavis 0:13355db43bfa 202 dot->sleep(10, mDot::RTC_ALARM, false); // Deepsleep not currently supported on mDot
bdavis 0:13355db43bfa 203 }
bdavis 0:13355db43bfa 204
bdavis 0:13355db43bfa 205 return 0;
bdavis 0:13355db43bfa 206 }