Demonstration program for Multitech System MTDOT-EVB an evaluation board for the mDot LoRa module
Dependencies: DOGS102 ISL29011 MMA845x MPL3115A2 NCP5623B libmDot mbed-rtos mbed
Revision 9:ed86d5ae29cc, committed 2015-11-23
- Comitter:
- falingtrea
- Date:
- Mon Nov 23 14:51:32 2015 +0000
- Parent:
- 7:85445a8cc189
- Commit message:
- 1.05 Changed baud rate for debug from 921k to 115k. Added code to support 868 MHz band operation. Added mutex around certain mDot radio commands. Changed network name and passphrase. Changed pb references to sw to match MTDOT-BOX overlay. Changed func...
Changed in this revision
diff -r 85445a8cc189 -r ed86d5ae29cc DOGS102.lib --- a/DOGS102.lib Wed Oct 28 17:58:55 2015 +0000 +++ b/DOGS102.lib Mon Nov 23 14:51:32 2015 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/teams/Multi-Hackers/code/DOGS102/#4a773f4896c7 +http://developer.mbed.org/teams/Multi-Hackers/code/DOGS102/#a0f69c276cc6
diff -r 85445a8cc189 -r ed86d5ae29cc main.cpp --- a/main.cpp Wed Oct 28 17:58:55 2015 +0000 +++ b/main.cpp Mon Nov 23 14:51:32 2015 +0000 @@ -2,7 +2,7 @@ * @file main.cpp * @brief Main application for mDot-EVB demo * @author Tim Barr MultiTech Systems Inc. - * @version 1.03 + * @version 1.05 * @see * * Copyright (c) 2015 @@ -32,6 +32,11 @@ * public netework setup. Swapped \n and \r in prinf calls because * Windows seems to be picky about the order * + * 1.05 TAB 11/17/15 Changed baud rate for debug from 921k to 115k. Added code to support + * 868 MHz band operation. Added mutex around certain mDot radio commands. + * Changed network name and passphrase. Changed pb references to sw to + * match MTDOT-BOX overlay. Changed function of SW1 from end program to + * cycle through power levels and data rates. */ #include "mbed.h" @@ -76,8 +81,8 @@ //DigitalIn mDot06(PA_8); // GPIO/I2C_SCL //DigitalIn mDot07(PC_9); // GPIO/I2C_SDA -InterruptIn mDot08(PA_12); // GPIO/USB PB S1 on EVB -InterruptIn mDot09(PA_11); // GPIO/USB PB S2 on EVB +InterruptIn mDot08(PA_12); // GPIO/USB PB SW1 on EVB +InterruptIn mDot09(PA_11); // GPIO/USB PB SW2 on EVB //DigitalIn mDot11(PA_7); // GPIO/SPI_MOSI @@ -101,17 +106,13 @@ SPI mDotspi(PA_7,PA_6,PA_5); // mDot external SPI mDot11, mDot4, and mDot18 /* **** replace these values with the proper public or private network settings **** - * config_network_nameand config_network_pass are for private networks. + * config_network_name and config_network_pass are for private networks. */ -//settings for my bench -static std::string config_network_name = "TAB-CubeNet"; -static std::string config_network_pass = "1nt3gral"; -static uint8_t config_frequency_sub_band = 5; //Default network server settings -//static std::string config_network_name = "YOUR-NETWORK-NAME"; -//static std::string config_network_pass = "YOUR-NETWORK-PASSPHRASE"; -//static uint8_t config_frequency_sub_band = 3; +static std::string config_network_name = "Multitech"; +static std::string config_network_pass = "Multitech"; +static uint8_t config_frequency_sub_band = 3; /* config_app_id and config_app_key are for public networks. static uint8_t app_id[8] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D}; @@ -120,15 +121,17 @@ std::vector<uint8_t> config_app_key; */ -uint8_t result, pckt_time=10; +uint8_t result, mdot_freq; +uint8_t pckt_time = 8; +uint16_t xmit_delay = 8; char data; unsigned char test; char txtstr[17]; -int32_t num_whole, mdot_ret; +int32_t num_whole, mdot_ret, join_delay; uint32_t pressure; int16_t num_frac; - -bool exit_program = false; +uint8_t sf_val = mDot::SF_7; +uint8_t pwr_val = 11; // dBm MMA845x_DATA accel_data; MPL3115A2_DATA baro_data; @@ -139,18 +142,20 @@ NCP5623B* evbBackLight; DOGS102* evbLCD; mDot* mdot_radio; +Mutex mdot_mutex; convert32 convertl; convert16 converts; // flags for pushbutton debounce code -bool pb1_low = false; -bool pb2_low = false; +bool sw1_low = false; +bool sw2_low = false; +bool toggle_text = false; -void pb1ISR(void); -void pb2ISR(void); -void pb1_debounce(void const *args); -void pb2_debounce(void const *args); +void sw1ISR(void); +void sw2ISR(void); +void sw1_debounce(void const *args); +void sw2_debounce(void const *args); Thread* thread_3; void log_error(mDot* dot, const char* msg, int32_t retval); @@ -163,12 +168,13 @@ std::vector<uint8_t> mdot_data; std::vector<uint8_t> mdot_EUI; uint16_t i = 0; + uint8_t j =0; - debugUART.baud(921600); + debugUART.baud(115200); // mDotUART.baud(9600); // mdot UART unused but available on external connector - Thread thread_1(pb1_debounce); // threads for de-bouncing pushbutton switches - Thread thread_2(pb2_debounce); + Thread thread_1(sw1_debounce); // threads for de-bouncing pushbutton switches + Thread thread_2(sw2_debounce); thread_3 = new Thread(config_pkt_xmit); // start thread that sends LoRa packet when SW2 pressed @@ -182,7 +188,7 @@ * Setup SW1 as program stop function */ mDot08.disable_irq(); - mDot08.fall(&pb1ISR); + mDot08.fall(&sw1ISR); /* * need to call this function after rise or fall because rise/fall sets @@ -196,7 +202,7 @@ * Setup SW2 as packet time change */ mDot09.disable_irq(); - mDot09.fall(&pb2ISR); + mDot09.fall(&sw2ISR); /* * need to call this function after rise or fall because rise/fall sets @@ -221,21 +227,14 @@ evbLCD->writeBitmap(0,0,MultiTech_Logo); - sprintf(txtstr,"MTDOT"); - evbLCD->writeText(24,3,font_6x8,txtstr,strlen(txtstr)); - sprintf(txtstr,"Evaluation"); - evbLCD->writeText(24,4,font_6x8,txtstr,strlen(txtstr)); - sprintf(txtstr,"Board"); - evbLCD->writeText(24,5,font_6x8,txtstr,strlen(txtstr)); - - evbLCD->endUpdate(); - printf("\r\n setup mdot\r\n"); // get a mDot handle mdot_radio = mDot::getInstance(); if (mdot_radio) { + mdot_mutex.lock(); // lock mdot before setting configuration + // reset to default config so we know what state we're in mdot_radio->resetConfig(); @@ -243,14 +242,31 @@ mdot_radio->setActivityLedPin(PB_0); mdot_radio->setActivityLedEnable(true); - // Read node ID + // Read node ID and frequency band mdot_EUI = mdot_radio->getDeviceId(); + mdot_freq = mdot_radio->getFrequencyBand(); + printf("mDot EUI = "); for (i=0; i<mdot_EUI.size(); i++) { printf("%02x ", mdot_EUI[i]); } printf("\r\n"); + sprintf(txtstr,"MTDOT EVB"); + printf("mDot Frequency = "); + if (mdot_freq == mDot::FB_868) { + printf( "868 MHz\r\n"); + sprintf(txtstr,"%s 868 MHz",txtstr); + } else { + printf("915 MHz\r\n"); + sprintf(txtstr,"%s 915 MHz",txtstr); + } + + evbLCD->writeText(0,3,font_6x8,txtstr,strlen(txtstr)); + sprintf(txtstr,"Sensor Demo"); + evbLCD->writeText(24,4,font_6x8,txtstr,strlen(txtstr)); + + evbLCD->endUpdate(); // Setting up the mDot with network information. @@ -269,9 +285,11 @@ * between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only. * This function can be commented out for EU networks */ - printf("setting frequency sub band\r\n"); - if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) { - log_error(mdot_radio, "failed to set frequency sub band", mdot_ret); + if (mdot_freq == mDot::FB_915) { + printf("setting frequency sub band\r\n"); + if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set frequency sub band", mdot_ret); + } } /* @@ -300,34 +318,68 @@ log_error(mdot_radio, "failed to set network password", mdot_ret); } - // attempt to join the network - printf("joining network\r\n"); - while (((mdot_ret = mdot_radio->joinNetwork()) != mDot::MDOT_OK) && (!exit_program)) { - log_error(mdot_radio,"failed to join network:", mdot_ret); - if (mdot_radio->getFrequencyBand() == mDot::FB_868) { - mdot_ret = mdot_radio->getNextTxMs(); - } else { - mdot_ret = 0; - } - - printf("delay = %lu\r\n",mdot_ret); - osDelay(mdot_ret + 1); + /* + * Setting TX power for radio. Max allowed is +14dBm for EU and +20 dBm for NAM. Default is +11 dBm + */ + printf("setting TX Power Level to %2d dBm\r\n", pwr_val); + if ((mdot_ret = mdot_radio->setTxPower(pwr_val)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set TX power level", mdot_ret); } /* - * Check for PB1 press during network join attempt + * Setting TX data rate for radio. Max allowed is SF_12 for EU and SF10 dBm for NAM. Default is SF_9 */ - if (exit_program) { - printf("Exiting program\r\n"); - evbLCD->clearBuffer(); - sprintf(txtstr,"Exiting Program"); - evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); - exit(1); + printf("setting TX data rate to SF_7\r\n"); + if ((mdot_ret = mdot_radio->setTxDataRate(sf_val)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set TX data rate", mdot_ret); } + mdot_mutex.unlock(); // unlock mdot mutex before join attempt so SW1 can work + + // attempt to join the network + printf("joining network\r\n"); + do { + mdot_mutex.lock(); // lock mdot mutex before join attempt + mdot_ret = mdot_radio->joinNetwork(); + mdot_mutex.unlock(); // unlock mdot mutex after join attempt so SW1 can work + + if (mdot_ret != mDot::MDOT_OK) { + log_error(mdot_radio,"failed to join network:", mdot_ret); + + if (toggle_text) + sprintf(txtstr," > Join Failed <"); + else + sprintf(txtstr," < Join Failed >"); + + evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); + + if (mdot_radio->getFrequencyBand() == mDot::FB_868) { + join_delay = mdot_radio->getNextTxMs(); + } else { + join_delay = 10; + } + printf("delay = %lu\r\n",join_delay); + osDelay(join_delay + 1); + toggle_text = !toggle_text; + } + /* + * Setting TX power and Data Rate for radio just in case user requested by SW2 + */ + mdot_mutex.lock(); // lock mdot mutex before setting change + mdot_radio->setTxPower(pwr_val); + mdot_radio->setTxDataRate(sf_val); + mdot_mutex.unlock(); // unlock mdot mutex after settings change + + } while (mdot_ret != mDot::MDOT_OK); + + sprintf(txtstr,"*Network Joined*"); + evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); + } else { - printf("radio setup failed\r\n"); - //exit(1); + sprintf(txtstr,"Radio Init Failed!"); + evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); + printf("%s\r\n",txtstr); + exit(1); } osDelay(200); @@ -392,25 +444,17 @@ evbBackLight->setLEDCurrent(0); /* - * Check for PB1 press during network join attempt - */ - if (exit_program) { - printf("Exiting program\r\n"); - evbLCD->clearBuffer(); - sprintf(txtstr,"Exiting Program"); - evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); - exit(1); - } - - /* * Main data acquisition loop */ - pckt_time = 10; - i = 0; + i = 0; + do { evbLCD->startUpdate(); - evbLCD->clearBuffer(); + // clear LCD line 0-6 only + sprintf(txtstr, " "); + for (j=0; j<6; j++) + evbLCD->writeText(0,j,font_6x8,txtstr,strlen(txtstr)); /* * Test Accelerometer XYZ data ready bit to see if acquisition complete @@ -425,14 +469,12 @@ */ accel_data = evbAccel->getXYZ(); - sprintf(txtstr,"Accelerometer"); + sprintf(txtstr, "Accel: x = %d", accel_data._x); evbLCD->writeText(0,0,font_6x8,txtstr,strlen(txtstr)); - sprintf(txtstr, "x = %d", accel_data._x); - evbLCD->writeText(20,1,font_6x8,txtstr,strlen(txtstr)); sprintf(txtstr, "y = %d", accel_data._y); - evbLCD->writeText(20,2,font_6x8,txtstr,strlen(txtstr)); + evbLCD->writeText(42,1,font_6x8,txtstr,strlen(txtstr)); sprintf(txtstr, "z = %d", accel_data._z ); - evbLCD->writeText(20,3,font_6x8,txtstr,strlen(txtstr)); + evbLCD->writeText(42,2,font_6x8,txtstr,strlen(txtstr)); /* * Trigger a Pressure reading @@ -456,7 +498,7 @@ num_whole = pressure >> 2; // 18 bit integer significant num_frac = (pressure & 0x3) * 25; // 2 bit fractional 0.25 per bit sprintf(txtstr,"Press=%ld.%02d Pa", num_whole, num_frac); - evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); + evbLCD->writeText(0,3,font_6x8,txtstr,strlen(txtstr)); /* * Trigger a Altitude reading @@ -481,11 +523,11 @@ num_whole = baro_data._baro / 16; // 18 bit signed significant integer num_frac = (baro_data._baro & 0xF) * 625 / 100; // 4 bit fractional .0625 per bit sprintf(txtstr,"Alti=%ld.%02d m", num_whole, num_frac); - evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); + evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); num_whole = baro_data._temp / 16; // 8 bit signed significant integer num_frac = (baro_data._temp & 0x0F) * 625 / 100; // 4 bit fractional .0625 per bit sprintf(txtstr,"Temp=%ld.%03d C", num_whole, num_frac); - evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr)); + evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); /* * retrieve and print out Ambient Light level @@ -494,13 +536,28 @@ num_whole = lux_data * 24 / 100; // 16000 lux full scale .24 lux per bit num_frac = lux_data * 24 % 100; sprintf(txtstr, "Light=%ld.%02d lux", num_whole, num_frac ); - evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); + evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr)); evbLCD->endUpdate(); + printf("finished iteration %d\r\n",(++i)); - if (i % pckt_time == 0) { // check packet counter will send packet every 2-5-10 data collection loops + /* Transmit data packet based on pckt_time setting and result of + * mdot_radio->getNextTxMs() function and mutex available. The getNextTxMs() + * function returns the number of millisecond before another packet can be + * sent in 868 MHz band. This can vary depending on wther the 10%, 1% or 0.1% + * channel is used and the time on air for a specific setup of the radio + */ + + if ((xmit_delay <= i) && (mdot_radio->getNextTxMs() == 0) && (mdot_mutex.trylock())) { + /* + * Setting TX power and Data Rate for radio just in case user requested by SW2 + */ + mdot_radio->setTxPower(pwr_val); + mdot_radio->setTxDataRate(sf_val); + mdot_data.clear(); + mdot_data.push_back(0x1D); // key for start of data mdot_data.push_back(0x0E); // key for Current Acceleration 3-Axis Value converts.f_s = accel_data._x *4; // shift data 2 bits while retaining sign mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value @@ -513,6 +570,24 @@ mdot_data.push_back(convertl.t_u[2]); mdot_data.push_back(convertl.t_u[1]); mdot_data.push_back(convertl.t_u[0]); + + /* for 915 MHz band and SF_10 max packet size is 11 bytes. + * so the payload gets split in two packets here. + */ + if ((mdot_freq == mDot::FB_915) && (sf_val == mDot::SF_10)) { + mdot_ret = mdot_radio->send(mdot_data); + if ( mdot_ret != mDot::MDOT_OK) { + sprintf(txtstr,"mDot Send failed"); + evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); + log_error(mdot_radio, txtstr, mdot_ret); + continue; + } else { + printf("successfully sent packet 1 to gateway\r\n"); + } + mdot_data.clear(); // clear data for next "chunk" + } + + mdot_data.push_back(0x05); // key for Current Ambient Light Value converts.f_u = lux_data; // data is 16 bits unsigned mdot_data.push_back(converts.t_u[1]); @@ -521,14 +596,28 @@ converts.f_s = baro_data._temp; // temperature is signed 12 bit mdot_data.push_back(converts.t_u[1]); mdot_data.push_back(converts.t_u[0]); + mdot_data.push_back(0x1D); // key for end of data - if ((mdot_ret = mdot_radio->send(mdot_data)) != mDot::MDOT_OK) { + mdot_ret = mdot_radio->send(mdot_data); + if (mdot_ret != mDot::MDOT_OK) { log_error(mdot_radio, "failed to send", mdot_ret); + sprintf(txtstr,"PKT Send Failed"); + evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); } else { - printf("successfully sent data to gateway\r\n"); + sprintf(txtstr,"SENT DR=%2d Pwr=%2d",(12 - sf_val),pwr_val); + evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); + printf("%s \r\n",txtstr); } + mdot_mutex.unlock(); // unlock mutex after all data transmitted + xmit_delay = i + pckt_time; + if (mdot_freq == mDot::FB_868) + printf("Next transmit time = %d milliseconds \r\n",mdot_radio->getNextTxMs()); + + } else { + sprintf(txtstr," DR=%2d Pwr=%2d ",(12 - sf_val),pwr_val); + evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); } - } while(!exit_program && (i < 65000)); + } while(i < 65000); evbBaro->triggerOneShot(); @@ -550,71 +639,105 @@ } /* - * Sets pb1_low flag. Slag is cleared in pb1_debounce thread + * Sets sw1_low flag. Slag is cleared in sw1_debounce thread */ -void pb1ISR(void) +void sw1ISR(void) { - if (!pb1_low) - pb1_low = true; + if (!sw1_low) + sw1_low = true; } /* - * Debounces pb1. Also exits program if pushbutton 1 is pressed + * Debounces sw1 changes spreading factor and output power + * Cycles through SF_7-SF_9 for 4 power levels for 915 MHz band + * Cycles through SF_7-SF_12 for 4 power levels for 868 MHz band */ -void pb1_debounce(void const *args) +void sw1_debounce(void const *args) { - static uint8_t count = 0; + static uint8_t test_sf = 0; + static uint8_t test_pwr = 0; while (true) { - if (pb1_low && (mDot08 == 0)) + if (sw1_low && (mDot08 == 0)) count++; else { count = 0; - pb1_low = false; + sw1_low = false; } - if (count == 5) - exit_program = true; + if (count == 5) { + test_sf++; + + if (((test_sf > 3) && (mdot_freq == mDot::FB_915)) || ((test_sf > 5) && (mdot_freq == mDot::FB_868))) { + test_sf = 0; + test_pwr ++; + if (test_pwr > 3) + test_pwr = 0; + } + + // selects power output level using upper bits for select + switch(test_pwr) { + case 0: + pwr_val = 11; + break; + case 1: + pwr_val = 14; + break; + case 2: + pwr_val = 18; + break; + case 3: + pwr_val = 20; + } + + // sets data rate based on lower bits + sf_val = mDot::SF_7 - (test_sf & 0x07); + + sprintf(txtstr," DR=%2d Pwr=%2d ",(12 - sf_val),pwr_val); + evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); + printf("%s \r\n",txtstr); + } Thread::wait(5); } } /* - * Sets pb2_low flag. Flag is cleared in pb2_debounce thread + * Sets sw2_low flag. Flag is cleared in sw2_debounce thread */ -void pb2ISR(void) +void sw2ISR(void) { - if (!pb2_low) - pb2_low = true; + if (!sw2_low) + sw2_low = true; } /* - * Debounces pb2. Also changes packet transmit time to every other, - * every fifth, or every tenth sample when SW2 pushed + * Debounces sw2. Changes packet transmit time to every 2nd, + * 4th, 8th, or 16th sample when SW2 pushed. For 868 MHz mode + * the time for next packet value is also tested. * Also triggers a thread to transmit a configuration packet */ -void pb2_debounce(void const *args) +void sw2_debounce(void const *args) { static uint8_t count = 0; while (true) { - if (pb2_low && (mDot09 == 0)) + if (sw2_low && (mDot09 == 0)) count++; else { count = 0; - pb2_low = false; + sw2_low = false; } if (count == 5) { - if (pckt_time >= 5) + if (pckt_time >= 4) pckt_time /= 2; - else pckt_time = 20; + else pckt_time = 16; thread_3->signal_set(0x10); // signal config_pkt_xmit to send packet } @@ -624,7 +747,7 @@ } /* - * Function that print clear text verion of mDot errors + * Function that prints clear text verion of mDot errors */ void log_error(mDot* dot, const char* msg, int32_t retval) { @@ -638,17 +761,24 @@ { std::vector<uint8_t> data; + uint16_t wait_time; while (true) { - Thread::signal_wait(0x10); // wait for pb2ISR to signal send + Thread::signal_wait(0x10); // wait for sw2ISR to signal send data.clear(); data.push_back(0x0F); // key for Configuration data (packet transmission timer) data.push_back(pckt_time); + + mdot_mutex.lock(); // lock mdot mutex before packet send + + if ((wait_time = mdot_radio->getNextTxMs()) > 0) // wait for next xmit time + osDelay(wait_time); if ((mdot_ret = mdot_radio->send(data)) != mDot::MDOT_OK) { log_error(mdot_radio, "failed to send config data", mdot_ret); } else { printf("sent config data to gateway\r\n"); } + mdot_mutex.unlock(); // unlock mdot mutex after packet send } }
diff -r 85445a8cc189 -r ed86d5ae29cc mbed-rtos.lib --- a/mbed-rtos.lib Wed Oct 28 17:58:55 2015 +0000 +++ b/mbed-rtos.lib Mon Nov 23 14:51:32 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed-rtos/#12552ef4e980 +http://mbed.org/users/mbed_official/code/mbed-rtos/#6d90423c236e
diff -r 85445a8cc189 -r ed86d5ae29cc mbed.bld --- a/mbed.bld Wed Oct 28 17:58:55 2015 +0000 +++ b/mbed.bld Mon Nov 23 14:51:32 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/34e6b704fe68 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/9296ab0bfc11 \ No newline at end of file