A multifunctional and modular Firmware for Multitech's mDot based on ARM mBed provides a widerange of functionality for several Sensors such as MAX44009, BME280, MPU9250, SI1143 and uBlox. It allows you to quickly build a Sensornode that measures specific data with its sensors and sends it via LoRaWAN.

Dependencies:   mDot_LoRa_Sensornode_Flowmeter_impl mbed-rtos mbed

LoRa-Sensornode Firmware for Multitech mDot

A multifunctional and modular Firmware for Multitech's mDot which provides a widerange of functionality for several Sensors. It allows you to quickly build a Sensornode that measures specific data with its sensors and sends it via LoRaWAN.

/media/uploads/mitea1/logo-lora-600x370.png /media/uploads/mitea1/mt_mdot_family_642px.png

Supported Sensors

Idea

The Firmware has some predefined Application Modes running different Tasks(Measurements). Each mode can be used in a different Scenario. Application_Modes define which sensors are used, how often they aquire data and how often the data has to be sent via LoRa. Lets say you just want to measure the Light then you choose an Application_Mode (or define one) that only runs TaskLight for light measurement. As a standard all measurements are taken every second and sent via LoRa but you can change that interval depending on your usage Scenario

Committer:
mitea1
Date:
Fri Aug 12 11:19:14 2016 +0000
Revision:
1:fe242f3e341b
Parent:
0:f2815503561f
added OTAA Join Mode for LoRa Connection

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mitea1 0:f2815503561f 1 /*
mitea1 0:f2815503561f 2 * LoRa.cpp
mitea1 0:f2815503561f 3 *
mitea1 0:f2815503561f 4 * Created on: May 31, 2016
mitea1 0:f2815503561f 5 * Author: Adrian
mitea1 0:f2815503561f 6 */
mitea1 0:f2815503561f 7
mitea1 0:f2815503561f 8 #include "LoRa.h"
mitea1 0:f2815503561f 9
mitea1 0:f2815503561f 10 LoRa::LoRa(mDot* dot,RawSerial* debugSerial) {
mitea1 0:f2815503561f 11 this->dot = dot;
mitea1 0:f2815503561f 12 this->debugSerial = debugSerial;
mitea1 0:f2815503561f 13 this->config = new LoRaConfig();
mitea1 0:f2815503561f 14 this->dot->setActivityLedPin(PA_0);
mitea1 0:f2815503561f 15 this->dot->setActivityLedEnable(true);
mitea1 0:f2815503561f 16 }
mitea1 0:f2815503561f 17
mitea1 0:f2815503561f 18 LoRa::~LoRa() {
mitea1 0:f2815503561f 19 // TODO Auto-generated destructor stub
mitea1 0:f2815503561f 20 }
mitea1 0:f2815503561f 21
mitea1 0:f2815503561f 22 void LoRa::init(LORA_MODE desiredMode){
mitea1 0:f2815503561f 23 config->build(desiredMode);
mitea1 0:f2815503561f 24
mitea1 0:f2815503561f 25 resetConfig();
mitea1 1:fe242f3e341b 26
mitea1 0:f2815503561f 27 setNetworkName();
mitea1 0:f2815503561f 28 setNetworkPassphrase();
mitea1 1:fe242f3e341b 29 setAppEUI();
mitea1 1:fe242f3e341b 30 setAppKey();
mitea1 1:fe242f3e341b 31 setFrequencySubBand();
mitea1 1:fe242f3e341b 32 setPublicNetwork();
mitea1 0:f2815503561f 33 setSpreadingFactor();
mitea1 0:f2815503561f 34 setAckRetries();
mitea1 0:f2815503561f 35 setTxPower();
mitea1 1:fe242f3e341b 36 setJoinMode();
mitea1 0:f2815503561f 37
mitea1 0:f2815503561f 38 saveConfig();
mitea1 0:f2815503561f 39
mitea1 0:f2815503561f 40 if(config->isActiv()){
mitea1 0:f2815503561f 41 joinNetwork();
mitea1 0:f2815503561f 42 }
mitea1 0:f2815503561f 43
mitea1 0:f2815503561f 44 }
mitea1 0:f2815503561f 45
mitea1 0:f2815503561f 46 int32_t LoRa::setPublicNetwork(){
mitea1 0:f2815503561f 47 int32_t ret;
mitea1 0:f2815503561f 48 bool publicity = config->isPublic();
mitea1 0:f2815503561f 49
mitea1 0:f2815503561f 50 if ((ret = dot->setPublicNetwork(publicity)) != mDot::MDOT_OK) {
mitea1 0:f2815503561f 51 debugSerial->printf("failed to set public network %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 0:f2815503561f 52 }
mitea1 0:f2815503561f 53
mitea1 0:f2815503561f 54 return ret;
mitea1 0:f2815503561f 55 }
mitea1 0:f2815503561f 56
mitea1 0:f2815503561f 57 int32_t LoRa::setFrequencySubBand(){
mitea1 0:f2815503561f 58 int32_t ret;
mitea1 0:f2815503561f 59 uint8_t subBand = config->getFrequencySubBand();
mitea1 0:f2815503561f 60
mitea1 0:f2815503561f 61 debugSerial->printf("setting frequency sub band\n");
mitea1 0:f2815503561f 62
mitea1 0:f2815503561f 63 if ((ret = dot->setFrequencySubBand(subBand)) != mDot::MDOT_OK) {
mitea1 0:f2815503561f 64 debugSerial->printf("failed to set frequency sub band %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 0:f2815503561f 65 }
mitea1 0:f2815503561f 66
mitea1 0:f2815503561f 67 return ret;
mitea1 0:f2815503561f 68 }
mitea1 0:f2815503561f 69
mitea1 0:f2815503561f 70 int32_t LoRa::setNetworkName(){
mitea1 0:f2815503561f 71 int32_t ret;
mitea1 0:f2815503561f 72 std::string networkName = config->getNetworkName();
mitea1 0:f2815503561f 73
mitea1 0:f2815503561f 74 debugSerial->printf("setting network name\n");
mitea1 0:f2815503561f 75
mitea1 0:f2815503561f 76 if ((ret = dot->setNetworkName(networkName)) != mDot::MDOT_OK) {
mitea1 0:f2815503561f 77 debugSerial->printf("failed to set network name %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 0:f2815503561f 78 }
mitea1 0:f2815503561f 79
mitea1 0:f2815503561f 80 return ret;
mitea1 0:f2815503561f 81 }
mitea1 0:f2815503561f 82
mitea1 0:f2815503561f 83 int32_t LoRa::setNetworkPassphrase(){
mitea1 0:f2815503561f 84 int32_t ret;
mitea1 0:f2815503561f 85 std::string networkPassphrase = config->getNetworkPassphrase();
mitea1 0:f2815503561f 86 debugSerial->printf("setting network password\n");
mitea1 0:f2815503561f 87
mitea1 0:f2815503561f 88 if ((ret = dot->setNetworkPassphrase(networkPassphrase)) != mDot::MDOT_OK) {
mitea1 0:f2815503561f 89 debugSerial->printf("failed to set network password %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 0:f2815503561f 90 }
mitea1 0:f2815503561f 91
mitea1 0:f2815503561f 92 return ret;
mitea1 0:f2815503561f 93 }
mitea1 0:f2815503561f 94
mitea1 1:fe242f3e341b 95 int32_t LoRa::setAppEUI(){
mitea1 1:fe242f3e341b 96 int32_t ret;
mitea1 1:fe242f3e341b 97 std::vector<uint8_t> appEUI = config->getAppEUI();
mitea1 1:fe242f3e341b 98
mitea1 1:fe242f3e341b 99 debugSerial->printf("setting App EUI\n");
mitea1 1:fe242f3e341b 100
mitea1 1:fe242f3e341b 101 if ((ret = dot->setNetworkId(appEUI)) != mDot::MDOT_OK) {
mitea1 1:fe242f3e341b 102 debugSerial->printf("failed to set App EUI %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 1:fe242f3e341b 103 }
mitea1 1:fe242f3e341b 104
mitea1 1:fe242f3e341b 105 return ret;
mitea1 1:fe242f3e341b 106
mitea1 1:fe242f3e341b 107 }
mitea1 1:fe242f3e341b 108
mitea1 1:fe242f3e341b 109 int32_t LoRa::setAppKey(){
mitea1 1:fe242f3e341b 110 int32_t ret;
mitea1 1:fe242f3e341b 111 std::vector<uint8_t> appKey = config->getAppKey();
mitea1 1:fe242f3e341b 112
mitea1 1:fe242f3e341b 113 debugSerial->printf("setting App Key\n");
mitea1 1:fe242f3e341b 114
mitea1 1:fe242f3e341b 115 if ((ret = dot->setNetworkKey(appKey)) != mDot::MDOT_OK) {
mitea1 1:fe242f3e341b 116 debugSerial->printf("failed to set App Key %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 1:fe242f3e341b 117 }
mitea1 1:fe242f3e341b 118
mitea1 1:fe242f3e341b 119 return ret;
mitea1 1:fe242f3e341b 120 }
mitea1 1:fe242f3e341b 121
mitea1 1:fe242f3e341b 122
mitea1 1:fe242f3e341b 123
mitea1 1:fe242f3e341b 124 int32_t LoRa::setJoinMode(){
mitea1 1:fe242f3e341b 125 int32_t ret;
mitea1 1:fe242f3e341b 126 JOIN_MODE joinMode = config->getJOIN_MODE();
mitea1 1:fe242f3e341b 127
mitea1 1:fe242f3e341b 128 debugSerial->printf("setting join mode\n");
mitea1 1:fe242f3e341b 129
mitea1 1:fe242f3e341b 130 if(joinMode == OTA){
mitea1 1:fe242f3e341b 131 if ((ret = dot->setJoinMode(mDot::OTA)) != mDot::MDOT_OK) {
mitea1 1:fe242f3e341b 132 debugSerial->printf("failed to set network address %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 1:fe242f3e341b 133 }
mitea1 1:fe242f3e341b 134 }
mitea1 1:fe242f3e341b 135 else if(joinMode == ABP){
mitea1 1:fe242f3e341b 136 if ((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) {
mitea1 1:fe242f3e341b 137 debugSerial->printf("failed to set network address %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 1:fe242f3e341b 138 }
mitea1 1:fe242f3e341b 139 }
mitea1 1:fe242f3e341b 140
mitea1 1:fe242f3e341b 141 return ret;
mitea1 1:fe242f3e341b 142 }
mitea1 1:fe242f3e341b 143
mitea1 0:f2815503561f 144 int32_t LoRa::setSpreadingFactor(){
mitea1 0:f2815503561f 145 int32_t ret;
mitea1 0:f2815503561f 146
mitea1 0:f2815503561f 147 spreadingFactor = config->getSpreadingFactor();
mitea1 0:f2815503561f 148 mDot::DataRates spreadingFactorMdot;
mitea1 0:f2815503561f 149
mitea1 0:f2815503561f 150 switch(spreadingFactor){
mitea1 0:f2815503561f 151 case LORA_SPREADING_FACTOR_7:
mitea1 0:f2815503561f 152 spreadingFactorMdot = mDot::SF_7;
mitea1 0:f2815503561f 153 break;
mitea1 0:f2815503561f 154
mitea1 0:f2815503561f 155 case LORA_SPREADING_FACTOR_8:
mitea1 0:f2815503561f 156 spreadingFactorMdot = mDot::SF_8;
mitea1 0:f2815503561f 157 break;
mitea1 0:f2815503561f 158
mitea1 0:f2815503561f 159 case LORA_SPREADING_FACTOR_9:
mitea1 0:f2815503561f 160 spreadingFactorMdot = mDot::SF_9;
mitea1 0:f2815503561f 161 break;
mitea1 0:f2815503561f 162
mitea1 0:f2815503561f 163 case LORA_SPREADING_FACTOR_10:
mitea1 0:f2815503561f 164 spreadingFactorMdot = mDot::SF_10;
mitea1 0:f2815503561f 165 break;
mitea1 0:f2815503561f 166
mitea1 0:f2815503561f 167 case LORA_SPREADING_FACTOR_11:
mitea1 0:f2815503561f 168 spreadingFactorMdot = mDot::SF_11;
mitea1 0:f2815503561f 169 break;
mitea1 0:f2815503561f 170
mitea1 0:f2815503561f 171 case LORA_SPREADING_FACTOR_12:
mitea1 0:f2815503561f 172 spreadingFactorMdot = mDot::SF_12;
mitea1 0:f2815503561f 173 break;
mitea1 0:f2815503561f 174
mitea1 0:f2815503561f 175 default:
mitea1 0:f2815503561f 176 spreadingFactorMdot = mDot::SF_12;
mitea1 0:f2815503561f 177 break;
mitea1 0:f2815503561f 178 }
mitea1 0:f2815503561f 179
mitea1 0:f2815503561f 180 debugSerial->printf("setting TX spreading factor\n");
mitea1 0:f2815503561f 181 if ((ret = dot->setTxDataRate(spreadingFactorMdot)) != mDot::MDOT_OK) {
mitea1 0:f2815503561f 182 debugSerial->printf("failed to set TX datarate %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 0:f2815503561f 183 }
mitea1 0:f2815503561f 184
mitea1 0:f2815503561f 185 return ret;
mitea1 0:f2815503561f 186 }
mitea1 0:f2815503561f 187
mitea1 0:f2815503561f 188 int32_t LoRa::setTxPower(){
mitea1 0:f2815503561f 189 txPowerdBm = config->getTxPowerdBm();
mitea1 0:f2815503561f 190 dot->setTxPower(txPowerdBm);
mitea1 0:f2815503561f 191 }
mitea1 0:f2815503561f 192
mitea1 0:f2815503561f 193 int32_t LoRa::setAckRetries(){
mitea1 0:f2815503561f 194 int32_t ret;
mitea1 0:f2815503561f 195 uint8_t retries = config->getAcknowledgeRetries();
mitea1 0:f2815503561f 196
mitea1 0:f2815503561f 197 debugSerial->printf("enabling ACKs\n");
mitea1 0:f2815503561f 198 if ((ret = dot->setAck(retries)) != mDot::MDOT_OK) {
mitea1 0:f2815503561f 199 debugSerial->printf("failed to enable ACKs %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 0:f2815503561f 200 }
mitea1 0:f2815503561f 201
mitea1 0:f2815503561f 202 return ret;
mitea1 0:f2815503561f 203 }
mitea1 0:f2815503561f 204
mitea1 0:f2815503561f 205 void LoRa::resetConfig(){
mitea1 0:f2815503561f 206 dot->resetConfig();
mitea1 0:f2815503561f 207 }
mitea1 0:f2815503561f 208
mitea1 0:f2815503561f 209 void LoRa::saveConfig(){
mitea1 0:f2815503561f 210 debugSerial->printf("saving config\n");
mitea1 0:f2815503561f 211 if (! dot->saveConfig()) {
mitea1 0:f2815503561f 212 debugSerial->printf("failed to save configuration\n");
mitea1 0:f2815503561f 213 }
mitea1 0:f2815503561f 214 }
mitea1 0:f2815503561f 215
mitea1 0:f2815503561f 216
mitea1 0:f2815503561f 217 int32_t LoRa::send(std::vector<uint8_t>& data){
mitea1 0:f2815503561f 218 int32_t ret = mDot::MDOT_NOT_JOINED;
mitea1 0:f2815503561f 219
mitea1 0:f2815503561f 220 if(config->isActiv()){
mitea1 0:f2815503561f 221 ret=dot->send(data);
mitea1 0:f2815503561f 222 if (ret != mDot::MDOT_OK) {
mitea1 0:f2815503561f 223 debugSerial->printf("failed to send\n");
mitea1 0:f2815503561f 224 debugSerial->printf(mDot::getReturnCodeString(ret).c_str());
mitea1 0:f2815503561f 225 debugSerial->printf("\n");
mitea1 0:f2815503561f 226 } else {
mitea1 0:f2815503561f 227 debugSerial->printf("successfully sent data to gateway\n");
mitea1 0:f2815503561f 228 }
mitea1 0:f2815503561f 229 }
mitea1 0:f2815503561f 230
mitea1 0:f2815503561f 231 return ret;
mitea1 0:f2815503561f 232 }
mitea1 0:f2815503561f 233
mitea1 0:f2815503561f 234 int32_t LoRa::recv(std::vector<uint8_t>& data){
mitea1 0:f2815503561f 235 int32_t ret = mDot::MDOT_NOT_JOINED;
mitea1 0:f2815503561f 236 if(config->isActiv()){
mitea1 0:f2815503561f 237 ret = dot->recv(data);
mitea1 0:f2815503561f 238 }
mitea1 0:f2815503561f 239 return ret;
mitea1 0:f2815503561f 240 }
mitea1 0:f2815503561f 241
mitea1 0:f2815503561f 242 int16_t LoRa::getLastRssi(){
mitea1 0:f2815503561f 243 return dot->getRssiStats().last;
mitea1 0:f2815503561f 244 }
mitea1 0:f2815503561f 245
mitea1 0:f2815503561f 246 int16_t LoRa::getLastSnr(){
mitea1 0:f2815503561f 247 return snr;
mitea1 0:f2815503561f 248 }
mitea1 0:f2815503561f 249
mitea1 0:f2815503561f 250 uint8_t LoRa::getSpreadingFactor(){
mitea1 0:f2815503561f 251 return spreadingFactor;
mitea1 0:f2815503561f 252 }
mitea1 0:f2815503561f 253
mitea1 0:f2815503561f 254 uint8_t LoRa::getTxPowerdBm(){
mitea1 0:f2815503561f 255 return txPowerdBm;
mitea1 0:f2815503561f 256 }
mitea1 0:f2815503561f 257
mitea1 0:f2815503561f 258 void LoRa::ping(){
mitea1 0:f2815503561f 259 mDot::ping_response response = dot->ping();
mitea1 0:f2815503561f 260 }
mitea1 0:f2815503561f 261
mitea1 1:fe242f3e341b 262 uint32_t LoRa::getNextTxMs(){
mitea1 1:fe242f3e341b 263 return dot->getNextTxMs();
mitea1 1:fe242f3e341b 264 }
mitea1 1:fe242f3e341b 265
mitea1 0:f2815503561f 266
mitea1 0:f2815503561f 267 void LoRa::joinNetwork(){
mitea1 0:f2815503561f 268 int32_t ret;
mitea1 0:f2815503561f 269 // attempt to join the network
mitea1 0:f2815503561f 270 debugSerial->printf("joining network\n");
mitea1 0:f2815503561f 271 while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
mitea1 0:f2815503561f 272 debugSerial->printf("failed to join network %d:%s\n", ret, mDot::getReturnCodeString(ret).c_str());
mitea1 0:f2815503561f 273 // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again
mitea1 0:f2815503561f 274 osDelay(std::max((uint32_t)1000, (uint32_t)dot->getNextTxMs()));
mitea1 0:f2815503561f 275 }
mitea1 0:f2815503561f 276 debugSerial->printf("Network joined\n");
mitea1 0:f2815503561f 277 }
mitea1 0:f2815503561f 278