Custom "Installer Assistant" software. Modified Single Sweep Mode. Goes right into single sweep mode upon power-up and displays signal strength. Works with mbed-os 5.1.2 and mdot lib 5.1.5

Dependencies:   DOGS102 GpsParser ISL29011 MMA845x MPL3115A2 MTS-Serial NCP5623B libmDot-dev-mbed5-deprecated

Fork of MTDOT-BOX-EVB-Factory-Firmware by MultiTech

Files at this revision

API Documentation at this revision

Comitter:
ScottHoppeMultitech
Date:
Thu Dec 28 21:35:48 2017 +0000
Parent:
11:19ce32436b9b
Commit message:
Custom mDotBox software -modified single sweep mode - goes straight into a single sweep mode and display signal strength. Works With mbed-os 5.1.2 and mdot lib 5.1.5

Changed in this revision

Layout/Layout.cpp Show annotated file Show diff for this revision Revisions of this file
Layout/Layout.h Show annotated file Show diff for this revision Revisions of this file
Layout/LayoutJoin.cpp Show annotated file Show diff for this revision Revisions of this file
Layout/LayoutSurveySuccess.cpp Show annotated file Show diff for this revision Revisions of this file
LoRaHandler/LoRaHandler.cpp Show annotated file Show diff for this revision Revisions of this file
Mode/ModeSingle.cpp Show annotated file Show diff for this revision Revisions of this file
dotbox_version.h Show annotated file Show diff for this revision Revisions of this file
libmDot-dev-mbed5.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
diff -r 19ce32436b9b -r 671b15182260 Layout/Layout.cpp
--- a/Layout/Layout.cpp	Thu Nov 10 22:10:58 2016 +0000
+++ b/Layout/Layout.cpp	Thu Dec 28 21:35:48 2017 +0000
@@ -79,7 +79,6 @@
 bool Layout::writeField(const Field& field, const char* value, size_t size, bool apply) {
     bool ret;
     char buf[32];
-
     // fill the whole length with blank space in case the previous value was longer than this one
     memset(buf, ' ', sizeof(buf));
 
diff -r 19ce32436b9b -r 671b15182260 Layout/Layout.h
--- a/Layout/Layout.h	Thu Nov 10 22:10:58 2016 +0000
+++ b/Layout/Layout.h	Thu Dec 28 21:35:48 2017 +0000
@@ -53,14 +53,14 @@
     public:
         Layout(DOGS102* lcd);
         ~Layout();
-
+        bool writeLabel(const Label& label);
         virtual void display() = 0;
         
     protected:
         void clear();
         void startUpdate();
         void endUpdate();
-        bool writeLabel(const Label& label);
+        //bool writeLabel(const Label& label);
         bool writeField(const Field& field, const std::string& value, bool apply = false);
         bool writeField(const Field& field, const char* value, size_t size, bool apply = false);
         bool writeImage(const Image& image, bool apply = false);
diff -r 19ce32436b9b -r 671b15182260 Layout/LayoutJoin.cpp
--- a/Layout/LayoutJoin.cpp	Thu Nov 10 22:10:58 2016 +0000
+++ b/Layout/LayoutJoin.cpp	Thu Dec 28 21:35:48 2017 +0000
@@ -116,7 +116,8 @@
 void LayoutJoin::displayCancel(bool display) {
     std::string str;
     if (display)
-        str = "Cancel";
+        //str = "Cancel";   //I CHANGED THIs, got rid of the cancel because theres no point, it wont do anything from within the process/behavior in single sweep
+        str = "";
     else
         str = string(17, ' ');
 
diff -r 19ce32436b9b -r 671b15182260 Layout/LayoutSurveySuccess.cpp
--- a/Layout/LayoutSurveySuccess.cpp	Thu Nov 10 22:10:58 2016 +0000
+++ b/Layout/LayoutSurveySuccess.cpp	Thu Dec 28 21:35:48 2017 +0000
@@ -42,13 +42,15 @@
 
 LayoutSurveySuccess::~LayoutSurveySuccess() {}
 
+
+
 void LayoutSurveySuccess::display() {
     clear();
     startUpdate();
 
-    writeLabel(_lId);
-    writeLabel(_lDr);
-    writeLabel(_lPwr);
+    //writeLabel(_lId);
+   // writeLabel(_lDr);
+   // writeLabel(_lPwr);
     writeLabel(_lUp);
     writeLabel(_lDown);
 
@@ -60,7 +62,7 @@
     size_t size;
 
     size = snprintf(buf, sizeof(buf), "%lu", id);
-    writeField(_fId, buf, size, true);
+    //writeField(_fId, buf, size, true);
 }
 
 void LayoutSurveySuccess::updateRate(std::string rate) {
@@ -72,7 +74,7 @@
     size_t size;
 
     size = snprintf(buf, sizeof(buf), "%lu", power);
-    writeField(_fPwr, buf, size, true);
+    //writeField(_fPwr, buf, size, true);
 }
 
 void LayoutSurveySuccess::updateStats(LoRaHandler::LoRaLink link) {
@@ -80,7 +82,7 @@
     size_t size;
 
     startUpdate();
-
+//__________________________________________________RSSI HERER!!!!_______________________________________________________
     size = snprintf(buf, sizeof(buf), "%d", link.up.dBm);
     writeField(_fUpMargin, buf, size);
 
diff -r 19ce32436b9b -r 671b15182260 LoRaHandler/LoRaHandler.cpp
--- a/LoRaHandler/LoRaHandler.cpp	Thu Nov 10 22:10:58 2016 +0000
+++ b/LoRaHandler/LoRaHandler.cpp	Thu Dec 28 21:35:48 2017 +0000
@@ -29,6 +29,8 @@
 
 uint8_t cmd = l_none;
 std::vector<uint8_t> send_data;
+bool successLED = false;
+bool failLED = false;
 
 void l_worker(void const* argument) {
     LoRaHandler* l = (LoRaHandler*)argument;
@@ -58,13 +60,25 @@
                         l->_mutex.unlock();
                         l->_link.down.rssi = rs.last;
                         l->_link.down.snr = ss.last;
+                        successLED = true;
                         l->_status = LoRaHandler::link_check_success;
+                        
                     } else {
+                        failLED = true;
                         l->_status = LoRaHandler::link_check_failure;
                     }
                     osSignalSet(l->_main, loraSignal);
                     l->_tick.detach();
-                    l->_activity_led = LoRaHandler::green;
+                    
+                    if(successLED == true){ 
+                        successLED = false;
+                        l->_activity_led = LoRaHandler::green;
+                    }
+                    if(failLED == true){
+                        failLED = false;
+                        l->_activity_led = LoRaHandler::red;
+                        }
+
                     break;
                 
                 case l_send:
@@ -185,3 +199,5 @@
 }
 
 
+
+
diff -r 19ce32436b9b -r 671b15182260 Mode/ModeSingle.cpp
--- a/Mode/ModeSingle.cpp	Thu Nov 10 22:10:58 2016 +0000
+++ b/Mode/ModeSingle.cpp	Thu Dec 28 21:35:48 2017 +0000
@@ -15,10 +15,13 @@
  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
-
+//THIS CUSTOM INSTALLER ASSISTANT, WORKS WITH mbed-os 5.1.2 and mdot lib 5.1.5
 #include "ModeSingle.h"
 #include "MTSLog.h"
 
+#include "font_6x8.h"
+#include <string>
+#include <sstream>
 ModeSingle::ModeSingle(DOGS102* lcd, ButtonHandler* buttons, mDot* dot, LoRaHandler* lora, GPSPARSER* gps, SensorHandler* sensors)
   : Mode(lcd, buttons, dot, lora, gps, sensors),
     _help(lcd),
@@ -28,11 +31,11 @@
     _success(lcd),
     _failure(lcd)
 {}
-
 ModeSingle::~ModeSingle() {}
 
 bool ModeSingle::start() {
-    bool data_file = false;
+
+    
     bool send_link_check = false;
     bool send_data = false;
     bool no_channel_link_check = false;
@@ -40,31 +43,59 @@
 
     // clear any stale signals
     osSignalClear(_main_id, buttonSignal | loraSignal);
-
+    
     _initial_data_rate = _dot->getTxDataRate();
     _initial_power = _dot->getTxPower();
 
     // see if we're supposed to send the data packet after success
     // that item is stored in the mDot::StartUpMode config field
-    _send_data = _dot->getStartUpMode();
+   // _send_data = _dot->getStartUpMode();
+
+
+//           Stating Start up Values for the Power, DataRate and State
+//________________________________________________________________________________________________________
+_power = 20;                //Hard setting the power, user dose not need to change it so we state it here
+_data_rate = mDot::DR0;     //setting the data rate, going to be increasead by 1 increments
+_state = 4;                 //setting the state so it goes right into success behavior off the start
+
 
-    // see if survey data file exists
-    std::vector<mDot::mdot_file> files = _dot->listUserFiles();
-    for (std::vector<mDot::mdot_file>::iterator it = files.begin(); it != files.end(); it++) {
-        if (strcmp(it->name, file_name) == 0) {
-            logInfo("found survey data file");
-            data_file = true;
-            break;
-        }
-    }
-    if (data_file) {
-        _state = check_file;
-        _file.display();
-    } else {
-        _state = show_help;
-        _index = 0;
-        displayHelp();
-    }
+//Initalizing Variables for converting the RSSI int value into a string
+//_____________________________________________________________________
+ string rssiStringHolder;
+ int rssiIntHolder;
+ ostringstream rssiConverter;
+ Label rssiLabel(0,3,"RSSI");
+ 
+ string dataRateStringHolder;
+ int dataRateIntHolder;
+ ostringstream dataRateConverter;
+ Label dataRateLabel(0,6,"Data");
+ 
+ string marginStringHolder;
+ int marginIntHolder;
+ ostringstream marginConverter;
+ Label marginLabel(0,2,"Margin1");
+
+//          Initial Settings for the LCD Display
+//________________________________________________________________________________________________________
+_lcd->startUpdate();    
+_lcd->clearBuffer();        //Clears the LCD
+_lcd->writeText(0*6, 0, font_6x8, "    Installer    ", 17);
+_lcd->writeText(0*6, 1, font_6x8, "    Assistant    ", 17);
+_lcd->writeText(0*6, 5, font_6x8, "Power=20         ", 17);
+
+dataRateIntHolder = _data_rate;
+dataRateConverter.str("");
+dataRateConverter.clear();
+dataRateConverter << dataRateIntHolder;
+dataRateStringHolder = dataRateConverter.str();
+dataRateLabel._value = "DataRate=" + dataRateStringHolder;
+_success.writeLabel(dataRateLabel);
+//_success.updateInfo(formatRatePower()); //This Displays the updated DataRate value, it changes so we cant just display the number itsself
+
+_lcd->endUpdate();
+_success.updateSw1("DataRate");
+_success.updateSw2("Survey");
 
     while (true) {
         osEvent e = Thread::signal_wait(0, 250);
@@ -75,54 +106,50 @@
                 switch (_be) {
                     case ButtonHandler::sw1_press:
                         switch (_state) {
-                            case check_file:
-                                _state = show_help;
-                                _index = getIndex(single);
-                                displayHelp();
-                                break;
-                            case confirm:
-                                _state = check_file;
-                                _file.display();
-                                break;
-                            case show_help:
-                                incrementRatePower();
-                                _help.updateMsg(formatRatePower());
-                                break;
                             case success:
                                 incrementRatePower();
-                                _success.updateInfo(formatRatePower());
+                                
+                                logInfo("\n\r\n\r I am within the DataRate button press! \n\r");
+                                
+                                dataRateIntHolder = _data_rate;
+                                dataRateConverter.str("");
+                                dataRateConverter.clear();
+                                dataRateConverter << dataRateIntHolder;
+                                dataRateStringHolder = dataRateConverter.str();
+                                
+                                dataRateLabel._value = "DataRate=" + dataRateStringHolder;
+                                
+                                
+                                _lcd->startUpdate();  
+                                _success.writeLabel(dataRateLabel);
+                                _lcd->endUpdate();
+
+                
                                 break;
                             case failure:
                                 incrementRatePower();
-                                _failure.updateInfo(formatRatePower());
+                                
+                                dataRateIntHolder = _data_rate;
+                                dataRateConverter.str("");
+                                dataRateConverter.clear();
+                                dataRateConverter << dataRateIntHolder;
+                                dataRateStringHolder = dataRateConverter.str();
+                                
+                                dataRateLabel._value = "DataRate=" + dataRateStringHolder;
+                                
+                                
+                                _lcd->startUpdate();  
+                                _success.writeLabel(dataRateLabel);
+                                _lcd->endUpdate();
                                 break;
                         }
                         break;
 
                     case ButtonHandler::sw2_press:
                         switch (_state) {
-                            case check_file:
-                                _state = confirm;
-                                _confirm.display();
-                                break;
-                            case confirm:
-                                _state = show_help;
-                                logInfo("deleting survey data file");
-                                _dot->deleteUserFile(file_name);
-                                _index = 0;
-                                displayHelp();
-                                break;
-                            case show_help:
-                                _state = in_progress;
-                                _progress.display();
-                                if (_dot->getNextTxMs() > 0)
-                                    no_channel_link_check = true;
-                                else 
-                                    send_link_check = true;
-                                break;
                             case success:
                                 _state = in_progress;
-                                _progress.display();
+                                _progress.display(); //this is where the survey in progress is located
                                 if (_dot->getNextTxMs() > 0)
                                     no_channel_link_check = true;
                                 else 
@@ -138,35 +165,65 @@
                                 break;
                         }
                         break;
-                    case ButtonHandler::sw1_hold:
-                        _dot->setTxDataRate(_initial_data_rate);
-                        _dot->setTxPower(_initial_power);
-                        return true;
                 }
             }
             if (e.value.signals & loraSignal) {
                 _ls = _lora->getStatus();
                 switch (_ls) {
                     case LoRaHandler::link_check_success:
+                    
                         switch (_state) {
                             case in_progress:
-                                _link_check_result = _lora->getLinkCheckResults();
-                                displaySuccess();
+                                _link_check_result = _lora->getLinkCheckResults();//Where the RSSI value lies
+                                //converting the RSSI int value to a string and then creating a new label that can be written to the LCD
+                                //______________________________________________________________________________
+                                rssiIntHolder = _link_check_result.down.rssi;
+                                rssiConverter.str("");
+                                rssiConverter.clear();
+                                rssiConverter << rssiIntHolder;
+                                rssiStringHolder = rssiConverter.str();
+                                rssiStringHolder = "Rssi= " + rssiStringHolder + "dBm";
+        
+                                rssiLabel._value = rssiStringHolder;
+                                
+                                
+                                marginIntHolder = _link_check_result.up.dBm;
+                                marginConverter.str("");
+                                marginConverter.clear();
+                                marginConverter << marginIntHolder;
+                                marginStringHolder = marginConverter.str();
+                                marginStringHolder = "Margin= " + marginStringHolder + "dBm";
+        
+                                marginLabel._value = marginStringHolder;
+                                
+                                
+                                dataRateIntHolder = _data_rate;
+                                dataRateConverter.str("");
+                                dataRateConverter.clear();
+                                dataRateConverter << dataRateIntHolder;
+                                dataRateStringHolder = dataRateConverter.str();
+                                
+                                dataRateLabel._value = "DataRate=" + dataRateStringHolder;
+                               
+                                //writing to the LCD the RSSI value as well as the other information
+                                //_________________________________________________________________
+                                _lcd->startUpdate();
+                                _lcd->clearBuffer();
+                                _lcd->writeText(0*6, 0, font_6x8, "    Installer    ", 17);
+                                _lcd->writeText(0*6, 1, font_6x8, "    Assistant    ", 17);
+                                _lcd->writeText(0*6, 5, font_6x8, "Power=20         ", 17);
+                                
+                               // _success.updateInfo(formatRatePower());
+                                _success.writeLabel(rssiLabel);
+                                _success.writeLabel(marginLabel);
+                                _success.writeLabel(dataRateLabel);
+                                _lcd->endUpdate();
+                                
                                 logInfo("link check successful\tMargin %ld\tRSSI %d dBm\tSNR %2.3f", _link_check_result.up.dBm, _link_check_result.down.rssi, (float)_link_check_result.down.snr / 10.0);
-                                updateData(_data, single, true);
-                                appendDataFile(_data);
-                                if (_send_data) {
-                                    _state = data;
-                                    if (_dot->getNextTxMs() > 0)
-                                        no_channel_data = true;
-                                    else
-                                        send_data = true;
-                                } else {
-                                    _state = success;
-                                    _success.updateSw1("  DR/PWR");
-                                    _success.updateSw2("Survey");
-                                }
-                                break;
+
+                                _state = success;
+                                _success.updateSw1("DataRate");
+                                _success.updateSw2("Survey");
                         }
                         break;
 
@@ -174,85 +231,37 @@
                         switch (_state) {
                             case in_progress:
                                 _state = failure;
-                                _failure.display();
-                                _failure.updateId(_index);
-                                // mDot::DataRateStr returns format DRXX - we only want to display the XX part
-                                _failure.updateRate(_dot->DataRateStr(_data_rate).substr(2));
-                                updateData(_data, single, false);
-                                appendDataFile(_data);
-                                _failure.updatePower(_power);
-                                if (_gps_available && _gps->getLockStatus()) {
-                                    GPSPARSER::latitude lat = _gps->getLatitude();
-                                    GPSPARSER::longitude lon = _gps->getLongitude();
-                                    struct tm time = _gps->getTimestamp();
-                                    _failure.updateGpsLatitude(lat);
-                                    _failure.updateGpsLongitude(lon);
-                                    _failure.updateGpsTime(time);
-                                } else {
-                                    _failure.updateGpsLatitude("No GPS Lock");
-                                }
-                                _failure.updateSw1("  DR/PWR");
-                                _failure.updateSw2("Survey");
+                                
+                                dataRateIntHolder = _data_rate;
+                                dataRateConverter.str("");
+                                dataRateConverter.clear();
+                                dataRateConverter << dataRateIntHolder;
+                                dataRateStringHolder = dataRateConverter.str();
+                                
+                                dataRateLabel._value = "DataRate=" + dataRateStringHolder;
+                                
+                                //writing to the LCD the RSSI value as well as the other information
+                                //_________________________________________________________________
+                                _lcd->startUpdate();                                
+                                _lcd->clearBuffer();
+                                _lcd->writeText(0*6, 0, font_6x8, "    Installer    ", 17);
+                                _lcd->writeText(0*6, 1, font_6x8, "    Assistant    ", 17);
+                                _lcd->writeText(0*6, 5, font_6x8, "Power=20         ", 17);
+                                _lcd->writeText(0*6, 3, font_6x8, "Unable to Connect", 17);
+                                _lcd->endUpdate();
+                               // _success.updateInfo(formatRatePower());
+                               
+                                _success.writeLabel(dataRateLabel);
+                                _failure.updateSw1("DataRate");
+                                _failure.updateSw2("Survey");              
                                 logInfo("link check failed");
                                 break;
                         }
                         break;
-
-                    case LoRaHandler::send_success:
-                        switch (_state) {
-                            case data:
-                                _state = success;
-                                _success.updateInfo("                 ");
-                                _success.updateSw1("  DR/PWR");
-                                _success.updateSw2("Survey");
-                                // turn acks and receive windows back on
-                                _dot->setAck(1);
-                                _dot->setTxWait(true);
-                                logInfo("data send success");
-                                break;
-                        }
-                        break;
-
-                    case LoRaHandler::send_failure:
-                        switch (_state) {
-                            case data:
-                                _state = success;
-                                _success.updateInfo("                 ");
-                                _success.updateSw1("  DR/PWR");
-                                _success.updateSw2("Survey");
-                                // turn acks and receive windows back on
-                                _dot->setAck(1);
-                                _dot->setTxWait(true);
-                                logInfo("data send failed");
-                                break;
-                        }
-                        break;
                 }
             }
         }
 
-        if (no_channel_link_check) {
-            uint32_t t = _dot->getNextTxMs();
-            if (t > 0) {
-                logInfo("next tx %lu ms", t);
-                _progress.updateCountdown(t / 1000);
-            } else {
-                _progress.display();
-                no_channel_link_check = false;
-                send_link_check = true;
-            }
-        }
-        if (no_channel_data) {
-            uint32_t t = _dot->getNextTxMs();
-            if (t > 0) {
-                logInfo("next tx %lu ms", t);
-                _success.updateCountdown(t / 1000);
-            } else {
-                displaySuccess();
-                no_channel_data = false;
-                send_data = true;
-            }
-        }
         if (send_link_check) {
             logInfo("sending link check %s %d", _dot->DataRateStr(_data_rate).c_str(), _power);
             send_link_check = false;
@@ -261,78 +270,20 @@
             _lora->linkCheck();
             _index++;
         }
-        if (send_data) {
-            std::vector<uint8_t> s_data = formatSurveyData(_data);
-            logInfo("sending data %s %d", _dot->DataRateStr(_data_rate).c_str(), _power);
-            send_data = false;
-            _success.updateInfo("Data Sending...");
-            _dot->setTxDataRate(_data_rate);
-            _dot->setTxPower(_power);
-            // we don't care if the server actually gets this packet or not
-            // we won't retry anyway
-            _dot->setAck(0);
-            _dot->setTxWait(false);
-            _lora->send(s_data);
-            osDelay(500);
-        }
     }
-}
 
-void ModeSingle::displayHelp() {
-    _help.display();
-    _help.updateMode("Survey Single");
-    _help.updateSw1("  DR/PWR");
-    _help.updateSw2("Survey");
-    _help.updateMsg(formatRatePower());
 }
 
-void ModeSingle::displaySuccess() {
-    uint8_t fix = _gps->getFixStatus();
-    _success.display();
-    _success.updateId(_index);
-    // mDot::DataRateStr returns format SF_XX - we only want to display the XX part
-    _success.updateRate(_dot->DataRateStr(_data_rate).substr(2));
-    _success.updatePower(_power);
-    _success.updateStats(_link_check_result);
-    if (_gps_available && _gps->getLockStatus()) {
-        GPSPARSER::latitude lat = _gps->getLatitude();
-        GPSPARSER::longitude lon = _gps->getLongitude();
-        struct tm time = _gps->getTimestamp();
-        _success.updateGpsLatitude(lat);
-        _success.updateGpsLongitude(lon);
-        _success.updateGpsTime(time);
-    } else {
-        _success.updateGpsLatitude("No GPS Lock");
-    }
-}
+
 
-std::string ModeSingle::formatRatePower() {
-    std::string msg;
-    char buf[8];
-    size_t size;
-
-    msg += "DR=";
-    msg += _dot->DataRateStr(_data_rate).substr(2);
-    msg += " P=";
-    size = snprintf(buf, sizeof(buf), "%u", _power);
-    msg.append(buf, size);
-
-    return msg;
-}
-
+//Cycles the datarates through from DR0-DR4
 void ModeSingle::incrementRatePower() {
-    if (_power == 20) {
-        _power = 2;
-        _data_rate++;        
-        if ((_band == mDot::FB_US915 && _data_rate > mDot::DR4) ||
-            (_band == mDot::FB_AU915 && _data_rate > mDot::DR4) ||
-            (_band == mDot::FB_EU868 && _data_rate > mDot::DR6)) {
-             _data_rate = mDot::DR0;       
+    if(_data_rate == mDot::DR4){
+        _data_rate = mDot::DR0;
         }
-    } else {
-        _power += 3;
-    }
-
+    else{
+        _data_rate++;
+        }
     logInfo("new data rate %s, power %lu", mDot::DataRateStr(_data_rate).c_str(), _power);
 }
 
diff -r 19ce32436b9b -r 671b15182260 dotbox_version.h
--- a/dotbox_version.h	Thu Nov 10 22:10:58 2016 +0000
+++ b/dotbox_version.h	Thu Dec 28 21:35:48 2017 +0000
@@ -1,6 +1,6 @@
 #ifndef __VERSION_H__
 #define __VERSION_H__
 
-#define MTDOT_BOX_VERSION "2.1.2"
+#define MTDOT_BOX_VERSION ".CUSTOM"
 
-#endif
+#endif
diff -r 19ce32436b9b -r 671b15182260 libmDot-dev-mbed5.lib
--- a/libmDot-dev-mbed5.lib	Thu Nov 10 22:10:58 2016 +0000
+++ b/libmDot-dev-mbed5.lib	Thu Dec 28 21:35:48 2017 +0000
@@ -1,1 +1,1 @@
-http://developer.mbed.org/teams/MultiTech/code/libmDot-dev-mbed5/#60e21ba8350a
+http://developer.mbed.org/teams/MultiTech/code/libmDot-dev-mbed5/#1fa7fd385088
diff -r 19ce32436b9b -r 671b15182260 main.cpp
--- a/main.cpp	Thu Nov 10 22:10:58 2016 +0000
+++ b/main.cpp	Thu Dec 28 21:35:48 2017 +0000
@@ -186,9 +186,9 @@
         lora_handler->resetActivityLed();
 
         LayoutScrollSelect menu(lcd, items, product, menu_strings[0]);
-        menu.display();
+       // menu.display();
 
-        while (! mode_selected) {
+        /*while (! mode_selected) {
             osEvent e = Thread::signal_wait(buttonSignal);
             if (e.status == osEventSignal) {
                 ButtonHandler::ButtonEvent ev = buttons->getButtonEvent();
@@ -206,7 +206,9 @@
                         break;
                 }
             }
-        }
+        }*/
+
+        selected = menu_strings[single];
         if (selected == menu_strings[demo]) {
             if (modeJoin->start())
                 modeDemo->start();
@@ -214,6 +216,7 @@
             modeConfig->start();
         } else if (selected == menu_strings[single]) {
             if (modeJoin->start())
+             
                 modeSingle->start();
         } else if (selected == menu_strings[sweep]) {
             if (modeJoin->start())
@@ -228,6 +231,8 @@
         } 
 
         mode_selected = false;
+        
+
     }
 }
 
diff -r 19ce32436b9b -r 671b15182260 mbed-os.lib
--- a/mbed-os.lib	Thu Nov 10 22:10:58 2016 +0000
+++ b/mbed-os.lib	Thu Dec 28 21:35:48 2017 +0000
@@ -1,1 +1,1 @@
-https://github.com/ARMmbed/mbed-os/#a1c0840b3d69060e5eb708edb18358e424a40f51
+https://github.com/ARMmbed/mbed-os/#d2202045ac8f2fc63836a5b7131c9b56ac58f06a