most functionality to splashdwon, find neutral and start mission. short timeouts still in code for testing, will adjust to go directly to sit_idle after splashdown

Dependencies:   mbed MODSERIAL FATFileSystem

Revision:
73:f6f378311c8d
Parent:
72:250b2665755c
Child:
74:d281aaef9766
--- a/StateMachine/StateMachine.cpp	Mon Jul 02 14:28:22 2018 +0000
+++ b/StateMachine/StateMachine.cpp	Mon Jul 30 16:48:48 2018 +0000
@@ -19,15 +19,13 @@
     //new commands
     
     _neutral_timer        = 0;                  //timer used in FIND_NEUTRAL sub-FSM
- 
+////////////////////////////// 
     _state = SIT_IDLE;                          // select starting state here
     _isTimeoutRunning = false;                  // default timer to not running
     _isSubStateTimerRunning = false;            // default timer to not running
-    
+/////////////////////////////    
     _multi_dive_counter = 0;
     
-    _neutral_sub_state_active = false;
-    
     _depth_KP = depthLoop().getControllerP();  // load current depth value
     _depth_KI = depthLoop().getControllerI();  // load current depth value
     _depth_KD = depthLoop().getControllerD();  // load current depth value
@@ -57,21 +55,26 @@
     
     _max_recorded_auto_neutral_depth = -99;
     
-    _file_closed = true;
+    _debug_menu_on = false;                     //toggle between debug and simple menu screens
     
-    _debug_menu_on = false;                     //toggle between debug and simple menu screens
+    //new file stuff
+    _pitch_filter_freq = pitchLoop().getFilterFrequency();
+    _pitch_deadband = pitchLoop().getDeadband();
+    
+    _depth_filter_freq = depthLoop().getFilterFrequency();
+    _depth_deadband = depthLoop().getDeadband();
 }
  
 //Finite State Machine (FSM)
-int StateMachine::runStateMachine() {       
-    //static int transmit_packet_number = 1;  //for data transmission
-
+int StateMachine::runStateMachine() {
     // finite state machine ... each state has at least one exit criteria
     switch (_state) {
     case SIT_IDLE :
-    case KEYBOARD:    
+    case KEYBOARD :
         // there actually is no timeout for SIT_IDLE, but this enables some one-shot actions
         if (!_isTimeoutRunning) {
+            //tare pressure sensor
+            depth().tare(); // tares to ambient (do on surface)
             
             if (_debug_menu_on)
                 printDebugMenu();
@@ -86,9 +89,6 @@
                      
             //reset sub FSM
             _isSubStateTimerRunning = false;
-            
-            //close the MBED file
-            _file_closed = true;
         }
         
         // how exit?
@@ -99,8 +99,8 @@
         // start local state timer and init any other one-shot actions
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: CHECK_TUNING\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             // what needs to be started?
@@ -115,16 +115,13 @@
             
             pc().printf("CHECK_TUNING: BCE cmd: %3.1f (BCE current position: %3.1f)\r\n", bce().getSetPosition_mm(), bce().getPosition_mm());
             pc().printf("CHECK_TUNING: BATT cmd: %3.1f (BATT current position: %3.1f)\r\n", batt().getSetPosition_mm(), bce().getPosition_mm());
-            
-            //triggers logger array
-            _is_log_timer_running = false; // reset the sub state timer to do one-shot actions again
         }
     
         // how exit?
-        if (timer > _timeout) {
+        if (_fsm_timer > _timeout) {
             pc().printf("CHECK_TUNING: timed out!\r\n");
             _state = FLOAT_BROADCAST;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         
@@ -132,7 +129,7 @@
         // the inner loop position controls are maintaining the positions of the linear actuators
         
         //print status to screen continuously
-        pc().printf("CHECK_TUNING: BCE_position: %0.1f, BATT_position: %0.1f (BCE_cmd: %0.1f, BATT_cmd: %0.1f)(depth: %0.1f ft, pitch: %0.1f deg) [%0.1f sec]\r",bce().getPosition_mm(),batt().getPosition_mm(),bce().getSetPosition_mm(),batt().getSetPosition_mm(),depthLoop().getPosition(),pitchLoop().getPosition(),timer.read());
+        pc().printf("CHECK_TUNING: BCE_position: %0.1f, BATT_position: %0.1f (BCE_cmd: %0.1f, BATT_cmd: %0.1f)(depth: %0.1f ft, pitch: %0.1f deg, heading: %0.1f)     [%0.1f sec]\r",bce().getPosition_mm(),batt().getPosition_mm(),bce().getSetPosition_mm(),batt().getSetPosition_mm(),depthLoop().getPosition(),pitchLoop().getPosition(),imu().getHeading(),_fsm_timer.read());
         
         checkMotorPositions();
         
@@ -142,8 +139,8 @@
         // start local state timer and init any other one-shot actions
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: EMERGENCY_CLIMB\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             // what needs to be started?
@@ -152,28 +149,25 @@
  
             // what are the commands?
             bce().setPosition_mm(bce().getTravelLimit());
-            batt().setPosition_mm(10.0);    //pull nose up (0.0 was sketchy)
-            
-            //triggers logger array
-            _is_log_timer_running = true; // reset the sub state timer to do one-shot actions again
+            batt().setPosition_mm(10.0);    //pull nose up (0.0 was sketchy)    
         }
         
         // how exit?
-        if (timer > _timeout) {
+        if (_fsm_timer > _timeout) {
             pc().printf("EC: timed out\r\n");
             _state = FLOAT_BROADCAST;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         else if (depthLoop().getPosition() < 2.0) { //if the depth is greater than 0.2 feet, go to float broadcast
             _state = FLOAT_BROADCAST;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         
         //WHAT IS ACTIVE?
         //print status to screen continuously
-        pc().printf("EC: depth: %3.1f, pitch: %0.1f deg [BCE:%0.1f (cmd: %0.1f) BMM:%0.1f (cmd: %0.1f)] [%0.1f sec]\r",depthLoop().getPosition(),pitchLoop().getPosition(),bce().getPosition_mm(), bce().getSetPosition_mm(),batt().getPosition_mm(), batt().getSetPosition_mm(),timer.read());
+        pc().printf("EC: depth: %3.1f, pitch: %0.1f deg [BCE:%0.1f (cmd: %0.1f) BMM:%0.1f (cmd: %0.1f)] [%0.1f sec]\r",depthLoop().getPosition(),pitchLoop().getPosition(),bce().getPosition_mm(), bce().getSetPosition_mm(),batt().getPosition_mm(), batt().getSetPosition_mm(),_fsm_timer.read());
         
         break;
  
@@ -181,8 +175,8 @@
         // start local state timer and init any other one-shot actions
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: FIND_NEUTRAL\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true;
             
             // what needs to be started?
@@ -201,16 +195,13 @@
             _substate_array_counter++;     
                    
             runNeutralStateMachine(); 
-
-            //triggers logger array
-            _is_log_timer_running = true; // reset the sub state timer to do one-shot actions again     
         }
  
         // how exit? (exit with the timer, if timer still running continue processing sub FSM)
-        if (timer > _timeout) {
-            pc().printf("FN: timed out [time: %0.1f sec]\r\n", timer.read());
+        if (_fsm_timer > _timeout) {
+            pc().printf("FN: timed out [time: %0.1f sec]\r\n", _fsm_timer.read());
             _state = EMERGENCY_CLIMB;         //new behavior (if this times out it emergency surfaces)
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
             
             //record this to the NEUTRAL sub-FSM tracker
@@ -234,8 +225,8 @@
                
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: DIVE\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             // what needs to be started?
@@ -251,30 +242,24 @@
             
             //reset max dive depth
             _max_recorded_depth_dive = -99;            //float to record max depth
-            
-            //create the log file (works only if the file is closed)
-            //createNewFile();
-            
-            //triggers logger array
-            _is_log_timer_running = false; // reset the sub state timer to do one-shot actions again
         }
  
         // how exit?
-        if (timer.read() > _timeout) {
+        if (_fsm_timer.read() > _timeout) {
             pc().printf("DIVE: timed out\r\n\n");
             _state = RISE; //new behavior 11/17/2017
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         else if (depthLoop().getPosition() > depthLoop().getCommand() - 0.5) { // including offset for low momentum approaches
             pc().printf("DIVE: actual depth: %3.1f (cmd: %3.1f)\r\n", depthLoop().getPosition(), depthLoop().getCommand());
             _state = RISE;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
  
         // WHAT IS ACTIVE?
-        pc().printf("DIVE: bce pos: %3.1f mm, batt pos: %3.1f mm (depth: %3.1f ft) (pitch: %3.1f deg)[%0.2f sec] (CMD BCE: %0.1f BATT: %0.1f)\r", bce().getPosition_mm(), batt().getPosition_mm(), depthLoop().getPosition(), pitchLoop().getPosition(), timer.read(),bce().getSetPosition_mm(),batt().getSetPosition_mm());
+        pc().printf("DIVE: bce pos: %3.1f mm, batt pos: %3.1f mm (depth: %3.1f ft) (pitch: %3.1f deg)[%0.2f sec] (CMD BCE: %0.1f BATT: %0.1f)\r", bce().getPosition_mm(), batt().getPosition_mm(), depthLoop().getPosition(), pitchLoop().getPosition(), _fsm_timer.read(),bce().getSetPosition_mm(),batt().getSetPosition_mm());
         bce().setPosition_mm(depthLoop().getOutput());  //constantly checking the Outer Loop output to move the motors
         batt().setPosition_mm(pitchLoop().getOutput());
         
@@ -291,8 +276,8 @@
         
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: RISE\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             // what needs to be started?
@@ -305,19 +290,13 @@
                         
             pc().printf("RISE: depth cmd: %0.1f\r\n",depthLoop().getCommand());
             pc().printf("RISE: pitch cmd: %0.1f\r\n",pitchLoop().getCommand());
-            
-            //create the log file (works only if the file is closed)
-            //createNewFile();
-            
-            //triggers logger array
-            _is_log_timer_running = false; // reset the sub state timer to do one-shot actions again
         }
  
         // how exit?
-        if (timer.read() > _timeout) {
+        if (_fsm_timer.read() > _timeout) {
             pc().printf("RISE: timed out\r\n");
             _state = EMERGENCY_CLIMB;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         
@@ -326,12 +305,12 @@
         else if (depthLoop().getPosition() < 0.5) {
             pc().printf("RISE: actual depth: %3.1f (cmd: %3.1f)\r\n", depthLoop().getPosition(), depthLoop().getCommand());
             _state = FLOAT_BROADCAST;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
  
         // WHAT IS ACTIVE?
-        pc().printf("RISE: bce pos: %3.1f mm, batt pos: %3.1f mm (depthLoop POS: %3.1f ft) (pitch: %3.1f deg)[%0.2f sec] (CMD BCE: %0.1f BATT: %0.1f)\r", bce().getPosition_mm(), batt().getPosition_mm(), depthLoop().getPosition(), pitchLoop().getPosition(), timer.read(),bce().getSetPosition_mm(),batt().getSetPosition_mm());
+        pc().printf("RISE: bce pos: %3.1f mm, batt pos: %3.1f mm (depthLoop POS: %3.1f ft) (pitch: %3.1f deg)[%0.2f sec] (CMD BCE: %0.1f BATT: %0.1f)\r", bce().getPosition_mm(), batt().getPosition_mm(), depthLoop().getPosition(), pitchLoop().getPosition(), _fsm_timer.read(),bce().getSetPosition_mm(),batt().getSetPosition_mm());
         bce().setPosition_mm(depthLoop().getOutput());  //constantly checking the Outer Loop output to move the motors
         batt().setPosition_mm(pitchLoop().getOutput());
          
@@ -344,8 +323,8 @@
         // start local state timer and init any other one-shot actions
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: POSITION DIVE\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             // what needs to be started?
@@ -367,17 +346,14 @@
             
             //reset max dive depth
             _max_recorded_depth_dive = -99;            //float to record max depth
-            
-            //triggers logger array
-            _is_log_timer_running = false; // reset the sub state timer to do one-shot actions again
         }
  
         // how exit?
         // timer runs out goes to POSITION_RISE
-        if (timer.read() > _timeout) {
+        if (_fsm_timer.read() > _timeout) {
             pc().printf("PD: timed out\r\n\n");
             _state = POSITION_RISE; //new behavior 11/17/2017
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         
@@ -385,12 +361,12 @@
         else if (depthLoop().getPosition() > depthLoop().getCommand() - 0.5) { // including offset for low momentum approaches
             pc().printf("PD: actual depth: %3.1f (cmd: %3.1f)\r\n", depthLoop().getPosition(), depthLoop().getCommand());
             _state = POSITION_RISE;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
  
         // what is active?
-        pc().printf("PD: bce pos (cmd pos): %3.1f mm (%0.1f), batt pos: %3.1f mm (%0.1f), rudder: %f (depth: %3.1f ft, pitch: %3.1f, heading: %3.1f [cmd: %0.1f])[%0.2f sec] [imu heading: %0.1f]                                         \r", bce().getPosition_mm(),bce().getSetPosition_mm(), batt().getPosition_mm(),batt().getSetPosition_mm(), rudder().getPosition_pwm(), depthLoop().getPosition(), pitchLoop().getPosition(), headingLoop().getPosition(), headingLoop().getOutput(), timer.read(), imu().getHeading());
+        pc().printf("PD: bce pos (cmd pos): %3.1f mm (%0.1f), batt pos: %3.1f mm (%0.1f), rudder: %f (depth: %3.1f ft, pitch: %3.1f, heading: %3.1f [cmd: %0.1f])[%0.2f sec] [imu heading: %0.1f]                                         \r", bce().getPosition_mm(),bce().getSetPosition_mm(), batt().getPosition_mm(),batt().getSetPosition_mm(), rudder().getPosition_pwm(), depthLoop().getPosition(), pitchLoop().getPosition(), headingLoop().getPosition(), headingLoop().getOutput(), _fsm_timer.read(), imu().getHeading());
         
         if (depthLoop().getPosition() > _max_recorded_depth_dive) {
             _max_recorded_depth_dive = depthLoop().getPosition();    //new max depth recorded when it is larger than previous values
@@ -408,8 +384,8 @@
         
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: POSITION RISE\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             // what needs to be started?
@@ -428,27 +404,24 @@
             pc().printf("PR: BATT cmd: %3.1f\r\n",batt().getSetPosition_mm());  //get the actual commanded position
             pc().printf("PR: BCE cmd: %3.1f\r\n",bce().getSetPosition_mm());    //get the actual commanded position
             pc().printf("PR: heading cmd: %3.1f\r\n",headingLoop().getCommand());
-            
-            //triggers logger array
-            _is_log_timer_running = false; // reset the sub state timer to do one-shot actions again
         }
  
         // how exit?
-        if (timer.read() > _timeout) {
+        if (_fsm_timer.read() > _timeout) {
             pc().printf("PR: timed out\r\n");
             _state = EMERGENCY_CLIMB;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         else if (depthLoop().getPosition() < 0.5) {
             pc().printf("PR: actual depth: %3.1f (cmd: %3.1f)\r\n", depthLoop().getPosition(), depthLoop().getCommand());
             _state = FLOAT_BROADCAST;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
  
         // what is active?
-        pc().printf("PR: bce pos (cmd pos): %3.1f mm (%0.1f), batt pos: %3.1f mm (%0.1f), rudder: %0.1f (depth: %3.1f ft, pitch: %3.1f, heading: %3.1f [cmd: %0.1f])[%0.2f sec] [imu heading: %0.1f]        \r", bce().getPosition_mm(),bce().getSetPosition_mm(), batt().getPosition_mm(),batt().getSetPosition_mm(), rudder().getPosition_pwm(), depthLoop().getPosition(), pitchLoop().getPosition(), headingLoop().getPosition(), headingLoop().getOutput(), timer.read(), imu().getHeading());
+        pc().printf("PR: bce pos (cmd pos): %3.1f mm (%0.1f), batt pos: %3.1f mm (%0.1f), rudder: %0.1f (depth: %3.1f ft, pitch: %3.1f, heading: %3.1f [cmd: %0.1f])[%0.2f sec] [imu heading: %0.1f]        \r", bce().getPosition_mm(),bce().getSetPosition_mm(), batt().getPosition_mm(),batt().getSetPosition_mm(), rudder().getPosition_pwm(), depthLoop().getPosition(), pitchLoop().getPosition(), headingLoop().getPosition(), headingLoop().getOutput(), _fsm_timer.read(), imu().getHeading());
         
         // ACTIVE RUDDER CONTROL
         rudder().setPosition_deg(headingLoop().getOutput());
@@ -462,8 +435,8 @@
         // start local state timer and init any other one-shot actions
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: FLOAT_LEVEL\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             // what needs to be started?
@@ -473,30 +446,24 @@
             // what are the commands?
             bce().setPosition_mm(_bceFloatPosition);
             pitchLoop().setCommand(0.0);
-            
-            //create the log file (works only if the file is closed)
-            //createNewFile();
-            
-            //triggers logger array
-            _is_log_timer_running = true; // reset the sub state timer to do one-shot actions again
         }
         
         // how exit?
-        if (timer > _timeout) {
+        if (_fsm_timer > _timeout) {
             pc().printf("FL: timed out\r\n");
             _state = FLOAT_BROADCAST;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         else if (fabs(imu().getPitch() - pitchLoop().getCommand()) < fabs(_pitchTolerance)) {         //current tolerance is 5 degrees
             pc().printf("FL: pitch: %3.1f mm, set pos: %3.1f mm, deadband: %3.1f mm\r\n",imu().getPitch(), pitchLoop().getCommand(), _pitchTolerance);
             _state = FLOAT_BROADCAST;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         
         // what is active?
-        pc().printf("FL: pitchLoop output: %3.1f, batt pos: %3.1f, piston pos: %3.1f [%0.1f sec]\r", pitchLoop().getOutput(), batt().getPosition_mm(), bce().getPosition_mm(), timer.read());
+        pc().printf("FL: pitchLoop output: %3.1f, batt pos: %3.1f, piston pos: %3.1f [%0.1f sec]\r", pitchLoop().getOutput(), batt().getPosition_mm(), bce().getPosition_mm(), _fsm_timer.read());
         batt().setPosition_mm(pitchLoop().getOutput());
         
         break;
@@ -505,8 +472,8 @@
         // start local state timer and init any other one-shot actions
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: FLOAT_BROADCAST\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             // what needs to be started?
@@ -516,19 +483,13 @@
             // what are the commands?
             bce().setPosition_mm(_bceFloatPosition);        // 320.0
             batt().setPosition_mm(_battFloatPosition);      // 73.0
-            
-            //create the log file (works only if the file is closed)
-            //createNewFile();
-            
-            //triggers logger array
-            _is_log_timer_running = false; // reset the sub state timer to do one-shot actions again
         }
         
         // how exit?
-        if (timer > _timeout) {
+        if (_fsm_timer > _timeout) {
             pc().printf("FB: timed out\r\n");
             _state = SIT_IDLE;
-            timer.reset();
+            _fsm_timer.reset();
             
             //stop recording data
             //mbedLogger().closeFile();
@@ -539,7 +500,7 @@
                   (fabs(batt().getPosition_mm() - batt().getSetPosition_mm()) < batt().getDeadband()) ) {
             pc().printf("FB: position: %3.1f mm, set pos: %3.1f mm, deadband: %3.1f mm\r\n",bce().getPosition_mm(), bce().getSetPosition_mm(), bce().getDeadband());
             _state = SIT_IDLE;
-            timer.reset();
+            _fsm_timer.reset();
             
             //stop recording data
             //mbedLogger().closeFile();
@@ -548,7 +509,7 @@
         }
         
         // what is active?
-        pc().printf("FB: bce pos: %0.1f mm, batt pos: %0.1f mm, heading(IMU): %0.1f (depthLoop POS: %3.1f ft) [%0.1f sec] (CMD BCE: %0.1f BATT: %0.1f)\r", bce().getPosition_mm(), batt().getPosition_mm(), imu().getHeading(), depthLoop().getPosition(), timer.read(), bce().getSetPosition_mm(),batt().getSetPosition_mm());
+        pc().printf("FB: bce pos: %0.1f mm, batt pos: %0.1f mm, heading(IMU): %0.1f (depthLoop POS: %3.1f ft) [%0.1f sec] (CMD BCE: %0.1f BATT: %0.1f)\r", bce().getPosition_mm(), batt().getPosition_mm(), imu().getHeading(), depthLoop().getPosition(), _fsm_timer.read(), bce().getSetPosition_mm(),batt().getSetPosition_mm());
         
         break;
         
@@ -556,8 +517,8 @@
         // start local state timer and init any other one-shot actions        
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: MULTI-DIVE\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
                 
             // what needs to be started?
@@ -574,27 +535,24 @@
             pc().printf("MULTI-DIVE: depth cmd: %3.1f ft, pitch cmd: %3.1f deg\r\n",depthLoop().getCommand(), pitchLoop().getCommand());
             
             //no max depth recording right now
-            
-            //triggers logger array
-            _is_log_timer_running = false; // reset the sub state timer to do one-shot actions again
         }
         
         // how exit?
-        if (timer > _timeout) {
-            pc().printf("\r\n\nMULTI-DIVE: timed out [time: %0.1f]\r\n\n", timer.read());
+        if (_fsm_timer > _timeout) {
+            pc().printf("\r\n\nMULTI-DIVE: timed out [time: %0.1f]\r\n\n", _fsm_timer.read());
             _state = MULTI_RISE; //new behavior 11/17/2017
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         else if (depthLoop().getPosition() > depthLoop().getCommand()) {
             pc().printf("MULTI-DIVE: depth: %3.1f, cmd: %3.1f\r\n", depthLoop().getPosition(), depthLoop().getCommand());
             _state = MULTI_RISE;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         
         // WHAT IS ACTIVE?
-        pc().printf("MULTI-DIVE: bce pos: %3.1f mm, batt pos: %3.1f mm (depthLoop POS: %3.1f ft) [%0.1f sec]\r", bce().getPosition_mm(), batt().getPosition_mm(), depthLoop().getPosition(), timer.read());
+        pc().printf("MULTI-DIVE: bce pos: %3.1f mm, batt pos: %3.1f mm (depthLoop POS: %3.1f ft) [%0.1f sec]\r", bce().getPosition_mm(), batt().getPosition_mm(), depthLoop().getPosition(), _fsm_timer.read());
         bce().setPosition_mm(depthLoop().getOutput());
         batt().setPosition_mm(pitchLoop().getOutput());
         
@@ -606,8 +564,8 @@
         // start local state timer and init any other one-shot actions
         if (!_isTimeoutRunning) {
             pc().printf("\r\n\nstate: MULTI-RISE\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             // what needs to be started?
@@ -625,19 +583,13 @@
             depthLoop().setCommand(0.5);
             pitchLoop().setCommand(-sequence_pitch_command);            
             pc().printf("MULTI-RISE: depth cmd: 0.0 ft, pitch cmd: %3.1f deg\r\n",depthLoop().getCommand(), pitchLoop().getCommand());
-            
-            //create the log file (works only if the file is closed)
-            //createNewFile();
-            
-            //triggers logger array
-            _is_log_timer_running = false; // reset the sub state timer to do one-shot actions again
         }
         
         // how exit?
-        if (timer > _timeout) {
-            pc().printf("MULTI-RISE: timed out [time: %0.1f]\r\n\n", timer.read());
+        if (_fsm_timer > _timeout) {
+            pc().printf("MULTI-RISE: timed out [time: %0.1f]\r\n\n", _fsm_timer.read());
             _state = EMERGENCY_CLIMB;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
             
             //reset multi-dive sequence to start
@@ -674,7 +626,7 @@
         }
         
         // WHAT IS ACTIVE?
-        pc().printf("MULTI-RISE: bce pos: %3.1f mm, batt pos: %3.1f mm (depthLoop POS: %3.1f ft) [%0.1f sec]\r", bce().getPosition_mm(), batt().getPosition_mm(), depthLoop().getPosition(), timer.read());
+        pc().printf("MULTI-RISE: bce pos: %3.1f mm, batt pos: %3.1f mm (depthLoop POS: %3.1f ft) [%0.1f sec]\r", bce().getPosition_mm(), batt().getPosition_mm(), depthLoop().getPosition(), _fsm_timer.read());
         bce().setPosition_mm(depthLoop().getOutput());  //constantly checking the Outer Loop output to move the motors
         batt().setPosition_mm(pitchLoop().getOutput()); 
         
@@ -685,8 +637,8 @@
     case TX_MBED_LOG:        
         if (!_isTimeoutRunning) {            
             pc().printf("\r\n\nstate: TX_MBED_LOG\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
             
             //mbedLogger().openFileForTransmit();     //starts _fp file pointer at the beginning of the file
@@ -695,28 +647,43 @@
             
             //function to read the file and get number of lines (packets to transmit)
             _timeout = mbedLogger().getNumberOfPacketsInCurrentLog();
-            //transmit_packet_number = mbedLogger().getNumberOfPackets();     //for comparison to end transmit sequence from python program
             
             mbedLogger().setTransmitPacketNumber(0); //reset to zero
         }
         
     //TIMED OUT
-        if (timer.read() > _timeout) {
+        if (_fsm_timer.read() > _timeout) {
             pc().printf("\r\nTX_MBED_LOG: timed out!\r\n");
             
             //STATE
             _state = SIT_IDLE;
             
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
             
-            mbedLogger().closeLogFile();
+            //mbedLogger().closeLogFile();
             pc().printf("\r\n\nstate: TX_MBED_LOG (log filed closed)\r\n");
         }
         
+    //received end transmission packet (if this is true)
+        if (mbedLogger().endTransmitPacket()) {
+             //STATE
+             led3() = !led3();
+             
+            _state = SIT_IDLE;
+            
+            //reset timer
+            _fsm_timer.reset();
+            
+            //mbedLogger().closeLogFile();
+            
+            pc().printf("\r\n\nTX_MBED_LOG: Received end transmission packet.)\r\n");
+        }
+        
         //What is active?
-        mbedLogger().fsmTransmitData();
+        //mbedLogger().fsmTransmitData();
         mbedLogger().checkForPythonTransmitRequest();
+        led1() = !led1();
         
         break; 
         
@@ -725,15 +692,15 @@
     
         if (!_isTimeoutRunning) {
             pc().printf("RECEIVE_SEQUENCE _isTimeoutRunning\r\n");
-            timer.reset(); // timer goes back to zero
-            timer.start(); // background timer starts running
+            _fsm_timer.reset(); // timer goes back to zero
+            _fsm_timer.start(); // background timer starts running
             _isTimeoutRunning = true; 
         }
         
-        if (timer.read() > _timeout) {
+        if (_fsm_timer.read() > _timeout) {
             pc().printf("RECEIVE_SEQUENCE: timed out!\r\n");
             _state = SIT_IDLE;
-            timer.reset();
+            _fsm_timer.reset();
             _isTimeoutRunning = false;
         }
         
@@ -756,80 +723,69 @@
     }
     
     return _state;
-//    //if the state is SIT_IDLE, return 0 / false (for recording)
-//    if (_state == SIT_IDLE)
-//        return 0;
-//    else
-//        return 1;   //return true to indicate that you're recording
-}
+}   /* end of runStateMachine */
  
 // output the keyboard menu for user's reference
 void StateMachine::printSimpleMenu() {   
-    pc().printf("\r\r\n\nSIMPLE KEYBOARD MENU (06/27/2018):\r\r\n");        //make sure depth sensor tares itself on startup
-    pc().printf(" Neutral Positions BCE: %0.1f BMM: %0.1f \r\n", _neutral_bce_pos_mm, _neutral_batt_pos_mm);
+    pc().printf("\r\r\n\nSIMPLE KEYBOARD MENU (07/26/2018):\r\r\n");        //make sure depth sensor tares itself on startup
+    pc().printf(" Neutral Positions BCE: %0.1f BMM: %0.1f (LIMIT: BCE: %0.1f BATT: %0.1f)\r\n\n", _neutral_bce_pos_mm, _neutral_batt_pos_mm, bce().getTravelLimit(),batt().getTravelLimit());
     
-    pc().printf(" V to POSITION DIVE (initiate motor position-based dive cycle)\r\n");
-    pc().printf(" J to float level\r\n");
-    pc().printf(" B to float at broadcast pitch\r\n");
-    pc().printf(" E to initiate emergency climb\r\n");
-    pc().printf(" P to print the current log file.\r\n");
-    pc().printf(" G to TX_MBED_LOG\r\n");
-    pc().printf(" ~ to erase mbed log file. (clear before logging more than a few runs)\r\n");
+    pc().printf("  V to POSITION DIVE (initiate motor position-based dive cycle)\r\n");
+    pc().printf("  J to float level\r\n");
+    pc().printf("  B to float at broadcast pitch\r\n");
+    pc().printf("  E to initiate emergency climb\r\n");
+    pc().printf("  P to print the current log file.\r\n");
+    pc().printf("  G to transmit MBED log file (60 second timeout)\r\n");
+    pc().printf("  ~ to erase mbed log file. (clear before logging more than a few runs)\r\n");
     
-    pc().printf("9/0 to decrease/increase heading setpoint: %0.1f deg\r\n",_heading_command);
-    pc().printf("A/S to decrease/increase depth setpoint: %3.1f (Current depth: %0.1f ft)\r\n",_depth_command, depthLoop().getPosition());
-    
-    pc().printf("T to enter in the timeout (default is 60 seconds): %d s\r\n",_timeout);    
+    pc().printf("Q to TYPE in the BMM offset: %0.1f (BMM Dive POS: %0.1f, Rise POS: %0.1f)\r\n",_BMM_dive_offset, _neutral_batt_pos_mm - _BMM_dive_offset, _neutral_batt_pos_mm + _BMM_dive_offset);  
+    pc().printf("A to TYPE in the BCE offset: %0.1f (BCE Dive POS: %0.1f, Rise POS: %0.1f)\r\n",_BCE_dive_offset, _neutral_bce_pos_mm - _BCE_dive_offset, _neutral_bce_pos_mm + _BCE_dive_offset);
+    pc().printf("W to TYPE in the heading command: %0.1f deg (imu heading: %0.1f)\r\n",_heading_command,imu().getHeading());
+    pc().printf("S to TYPE in depth setpoint: %0.1f (Current depth: %0.1f ft)\r\n",_depth_command, depthLoop().getPosition());
+    pc().printf("T to TYPE in the timeout (default is 60 seconds): %d s\r\n",_timeout);    
     
-    pc().printf(" C See sensor readings (and max recorded depth of dive & neutral sequences)\r\n");
-    pc().printf(" 8 STREAM SENSOR STATUS (and channel readings)\r\n");
+    pc().printf("  C See sensor readings (and max recorded depth of dive & neutral sequences)\r\n");
+    pc().printf("  8 STREAM SENSOR STATUS (and channel readings)\r\n");
     
-    pc().printf(" '|' to tare the depth sensor (vertical bar)\r\n");
+    pc().printf("  '|' to tare the depth sensor (vertical bar)\r\n");
     
-    pc().printf(" ? to reset mbed\r\n");
-    pc().printf(" * (asterisk) to go to DEBUG keyboard menu\r\n");
+    pc().printf("  ? to reset mbed\r\n");
+    pc().printf("  * (asterisk) to go to DEBUG keyboard menu\r\n");
 }
 
 void StateMachine::printDebugMenu() {
-    pc().printf("\r\r\n\nDEBUG KEYBOARD MENU (06/27/2018):\r\r\n");
-    pc().printf(" Y to go into CHECK NEUTRAL TUNING (This is on a timer! Uses NEUTRAL positions!)\r\n");
-    pc().printf(" V to POSITION DIVE (initiate motor position-based dive cycle)\r\n");
-    pc().printf(" N to find neutral\r\n");
-    pc().printf(" M to initiate multi-dive cycle\r\n");
-    pc().printf(" D to initiate dive cycle\r\n");
-    pc().printf(" R to initiate rise\r\n");
-    pc().printf(" J to float level\r\n");
-    pc().printf(" B to float at broadcast pitch\r\n");
-    pc().printf(" E to initiate emergency climb\r\n");
-    pc().printf(" '|' to tare the depth sensor (vertical bar)\r\n");
-    pc().printf(" Z to show FSM and sub-FSM states.\r\n");
-    pc().printf(" P to print the current log file.\r\n");
-    pc().printf(" X to print the list of log files.\r\n");
-    pc().printf(" I to receive data.\r\n");
-    pc().printf(" O to transmit data.\r\n");
-    pc().printf(" ~ to erase mbed log file. (clear before logging more than a few runs)\r\n");
-    pc().printf("[/] to change bce neutral position: %0.1f\r\n", _neutral_bce_pos_mm);
-    pc().printf("</> to change batt neutral position: %0.1f\r\n", _neutral_batt_pos_mm);
-    pc().printf("Q/W to decrease/increase pitch setpoint: %3.1f\r\n",_pitch_command);
-    pc().printf("A/S to decrease/increase depth setpoint: %3.1f (Current depth: %0.1f ft)\r\n",_depth_command, depthLoop().getPosition());
-    pc().printf("9/0 to decrease/increase heading setpoint: %0.1f deg\r\n",_heading_command);
-    pc().printf("k/l to decrease/increase BCE offset: %3.1f (Dive POS: %0.1f, Rise POS: %0.1f)\r\n",_BCE_dive_offset, _neutral_bce_pos_mm - _BCE_dive_offset, _neutral_bce_pos_mm + _BCE_dive_offset);
-    pc().printf(";/' to decrease/increase BMM offset: %3.1f (Dive POS: %0.1f, Rise POS: %0.1f)\r\n",_BMM_dive_offset, _neutral_batt_pos_mm - _BMM_dive_offset, _neutral_batt_pos_mm + _BMM_dive_offset);  
+    pc().printf("\r\r\n\nDEBUG KEYBOARD MENU (07/26/2018):\r\r\n");
+    pc().printf("  Y to go into CHECK NEUTRAL TUNING (This is on a timer! Uses NEUTRAL positions!)\r\n");
+    pc().printf("  V to POSITION DIVE (initiate motor position-based dive cycle)\r\n");
+    pc().printf("  N to find neutral\r\n");
+    pc().printf("  M to initiate multi-dive cycle\r\n");
+    pc().printf("  D to initiate dive cycle\r\n");
+    pc().printf("  R to initiate rise\r\n");
+    pc().printf("  J to float level\r\n");
+    pc().printf("  B to float at broadcast pitch\r\n");
+    pc().printf("  E to initiate emergency climb\r\n");
+    pc().printf("  '|' to tare the depth sensor (vertical bar)\r\n");
+    pc().printf("  Z to show FSM and sub-FSM states.\r\n");
+    pc().printf("  P to print the current log file.\r\n");
+    pc().printf("  X to print the list of log files.\r\n");
+    pc().printf("  I to receive data.\r\n");
+    pc().printf("  G to transmit MBED log file (60 second timeout)\r\n");
+    pc().printf("  ~ to erase mbed log file. (clear before logging more than a few runs)\r\n");
+    pc().printf("; or : to TYPE in the BCE neutral position: %0.1f\r\n", _neutral_bce_pos_mm);
+    pc().printf("[ or { to TYPE in the BMM neutral position: %0.1f\r\n", _neutral_batt_pos_mm);
+    pc().printf("Q to TYPE in pitch setpoint: %0.1f (Current IMU pitch: %0.1f deg)\r\n",_pitch_command,imu().getPitch());
+    pc().printf("A to TYPE in depth setpoint: %0.1f (Current depth: %0.1f ft)\r\n",_depth_command, depthLoop().getPosition());
+    pc().printf("W to TYPE in the heading command: %0.1f deg (imu heading: %0.1f)\r\n",_heading_command,imu().getHeading());
     pc().printf("T to enter in the timeout (default is 60 seconds): %d s\r\n",_timeout);
-    
-// FIXED WITH NEW CODE
-    pc().printf(" 1 BCE PID sub-menu\r\n");
-    pc().printf(" 2 BATT PID sub-menu\r\n");
-    pc().printf(" 3 Depth PID sub-menu\r\n");
-    pc().printf(" 4 Pitch PID sub-menu\r\n");
-    pc().printf(" 5 Rudder (servo) sub-menu\r\n");
-    pc().printf(" 6 HEADING PID sub-menu\r\n");
-    pc().printf(" 7 MANUAL_TUNING sub-menu (does not have a timer!)  *** MOTORS ARE ACTIVE ***\r\n");
-    //pc().printf(" 8 VIEW_OUTPUTS sub-menu (does not a have a timer!)\r\n");
-    pc().printf(" 8 STREAM SENSOR STATUS (and channel readings)\r\n");
-    
-// FIXED WITH NEW CODE
 
+    pc().printf("  1 BCE PID sub-menu (type in inputs)\r\n");
+    pc().printf("  2 BATT PID sub-menu (type in inputs)\r\n");
+    pc().printf("  3 Depth PID sub-menu (type in inputs)\r\n");
+    pc().printf("  4 Pitch PID sub-menu (type in inputs)\r\n");
+    pc().printf("  5 Rudder (servo) sub-menu\r\n");
+    pc().printf("  6 HEADING PID sub-menu (type in inputs)\r\n");
+    pc().printf("  7 MANUAL_TUNING sub-menu (does not have a timer!)  *** MOTORS ARE ACTIVE ***\r\n");
+    pc().printf("  8 STREAM SENSOR STATUS (and channel readings)\r\n");
     
     pc().printf(" C See sensor readings (and max recorded depth of dive & neutral sequences)\r\n");
     pc().printf(" ? to reset mbed\r\n");
@@ -844,9 +800,9 @@
         case NEUTRAL_SINKING :
             //start the 10 second timer
             if (!_isSubStateTimerRunning) {                
-                _neutral_timer = timer.read() + 5; //record the time when this block is first entered and add 5 seconds
+                _neutral_timer = _fsm_timer.read() + 5; //record the time when this block is first entered and add 5 seconds
                 
-                pc().printf("\r\n\nNEUTRAL_SINKING: Next retraction at %0.1f sec [current time: %0.1f] (pitch: %0.1f) (getSetPosition: %0.1f)\r\n", _neutral_timer, timer.read(), pitchLoop().getPosition(), bce().getSetPosition_mm());
+                pc().printf("\r\n\nNEUTRAL_SINKING: Next retraction at %0.1f sec [current time: %0.1f] (pitch: %0.1f) (getSetPosition: %0.1f)\r\n", _neutral_timer, _fsm_timer.read(), pitchLoop().getPosition(), bce().getSetPosition_mm());
                 
                 // what are the commands? (BCE linear actuator active, no pitch movement)
                 bce().setPosition_mm(bce().getSetPosition_mm() - 2.5);  //Troy: There is some strange error where this has to be a hardcoded number.
@@ -871,8 +827,8 @@
  
             // what is active?
             //once the 10 second timer is complete, reset the timeout so the state one-shot entry will move the setpoint
-            if (timer.read() >= _neutral_timer) {
-                pc().printf("\r\n\n NEUTRAL_SINKING TIMER COMPLETE! [current time: %0.1f]\r\n", timer.read());
+            if (_fsm_timer.read() >= _neutral_timer) {
+                pc().printf("\r\n\n NEUTRAL_SINKING TIMER COMPLETE! [current time: %0.1f]\r\n", _fsm_timer.read());
                 
                 _isSubStateTimerRunning = false; // reset the sub state timer to do one-shot actions again
             }
@@ -885,9 +841,9 @@
             
         case NEUTRAL_SLOWLY_RISE:
             if (!_isSubStateTimerRunning) {                                
-                _neutral_timer = timer.read()+ 5; //record the time when this block is first entered and add 5 seconds
+                _neutral_timer = _fsm_timer.read()+ 5; //record the time when this block is first entered and add 5 seconds
                 
-                pc().printf("\r\n\nNEUTRAL_SLOWLY_RISE: Next extension at %0.1f sec) [current time: %0.1f]\r\n",_neutral_timer,timer.read());
+                pc().printf("\r\n\nNEUTRAL_SLOWLY_RISE: Next extension at %0.1f sec) [current time: %0.1f]\r\n",_neutral_timer,_fsm_timer.read());
                 
                 // what are the commands?
                 //move piston at start of sequence (default: extend 2.0 mm)
@@ -909,15 +865,15 @@
             }
             //depth rate or sink rate < 0 ft/s, go to the next substate the next iteration
             else if (depthLoop().getVelocity() < 0) { //less than zero ft/s
-                pc().printf("\r\n\nNEUTRAL_SLOWLY_RISE: Sink Rate < 0 ft/s [time: %0.1f]\r\n", timer.read());
+                pc().printf("\r\n\nNEUTRAL_SLOWLY_RISE: Sink Rate < 0 ft/s [time: %0.1f]\r\n", _fsm_timer.read());
                 _substate = NEUTRAL_CHECK_PITCH;
                 _isSubStateTimerRunning = false; // reset the sub state timer
             }
             
             // what is active?
             //once 5 second timer complete, reset the timeout so the state one-shot entry will move the setpoint
-            if (timer.read() >= _neutral_timer) {
-                pc().printf("\r\n\n NEUTRAL_SLOWLY_RISE TIMER COMPLETE! [timer: %0.1f]\r\n", timer.read());
+            if (_fsm_timer.read() >= _neutral_timer) {
+                pc().printf("\r\n\n NEUTRAL_SLOWLY_RISE TIMER COMPLETE! [timer: %0.1f]\r\n", _fsm_timer.read());
    
                 _isSubStateTimerRunning = false; // reset the sub state timer to do one-shot actions again
             }
@@ -933,8 +889,8 @@
             // start local state timer and init any other one-shot actions
             
             if (!_isSubStateTimerRunning) {                    
-                _neutral_timer = timer.read() + 10; // record time when this block is entered and add several seconds
-                pc().printf("\r\nNEUTRAL_CHECK_PITCH: Next move in %0.1f sec \r\n",_neutral_timer - timer.read());
+                _neutral_timer = _fsm_timer.read() + 10; // record time when this block is entered and add several seconds
+                pc().printf("\r\nNEUTRAL_CHECK_PITCH: Next move in %0.1f sec \r\n",_neutral_timer - _fsm_timer.read());
                 
                 // what are the commands? (default: retract or extend 0.5 mm)
                 if (pitchLoop().getPosition() > 2) { // nose is high
@@ -971,9 +927,10 @@
                     pitchLoop().setOutputOffset(_neutral_batt_pos_mm);
                     
                     // save into the depth.txt and pitch.txt files
-                    configFileIO().savePitchData(_pitch_KP, _pitch_KI, _pitch_KD, _neutral_batt_pos_mm); //P,I,D,batt zeroOffset
-                    configFileIO().saveDepthData(_depth_KP, _depth_KI, _depth_KD, _neutral_bce_pos_mm); //P,I,D, bce zeroOffset
-                    
+       
+                    configFileIO().savePitchData(_pitch_KP, _pitch_KI, _pitch_KD, _neutral_batt_pos_mm, _pitch_filter_freq, _pitch_deadband); //P,I,D,batt zeroOffset
+                    configFileIO().saveDepthData(_depth_KP, _depth_KI, _depth_KD, _neutral_bce_pos_mm, _depth_filter_freq, _depth_deadband); //P,I,D, bce zeroOffset
+
                     pc().printf("\r\n\n>>> Saving Positions: BCE: %0.1f mm, BATT: %0.1f <<<\r\n\n",_neutral_bce_pos_mm,_neutral_batt_pos_mm);
                     
                     _substate = NEUTRAL_EXIT;
@@ -988,9 +945,9 @@
             
             // what is active?
             //once timer complete, reset the timeout so the state one-shot entry will move the setpoint
-            if (timer.read() >= _neutral_timer) {
+            if (_fsm_timer.read() >= _neutral_timer) {
                 pc().printf("\r\n\nlevel timer COMPLETE!");
-                pc().printf("\r\n\n (BATT POS: %0.1f) moving 1 mm [timer: %0.1f]\r\n", batt().getPosition_mm(), timer.read());
+                pc().printf("\r\n\n (BATT POS: %0.1f) moving 1 mm [timer: %0.1f]\r\n", batt().getPosition_mm(), _fsm_timer.read());
                 _isSubStateTimerRunning = false; // reset the sub state timer to do one-shot actions again
             }
             
@@ -1072,6 +1029,36 @@
             pc().printf(">> Please enter the heading (deg).\r\n");
             _heading_command = getFloatUserInput();
         }
+        
+//////////////////// TEST                   
+//        else if (user_input == 'l') {
+//            pc().printf("CUT OFF RUDDER SERVO????\n\r");
+//            rudder().pwm_pulse_off();
+//        }
+//////////////////// TEST
+        
+        else if (user_input == 'U') {
+            pc().printf("(U) TRANSMIT MULTIPLE PACKETS \n\r");
+                        
+            mbedLogger().transmitMultiplePackets();
+        }
+        
+        else if (user_input == 'H') {
+            pc().printf("(H) BLAST DATA AND MULTIPLE PACKETS! \n\r");
+            wait(1);
+            mbedLogger().blastData();
+            
+            mbedLogger().transmitMultiplePackets(); 
+        }
+        
+        else if (user_input == 'G') {
+            pc().printf("(G) BLAST DATA TEST! \n\r");
+            wait(1);
+            mbedLogger().blastData();
+            
+            _keyboard_state = TX_MBED_LOG;
+        }
+        
         else if (user_input == '8') {
             keyboard_menu_STREAM_STATUS();
         }
@@ -1095,6 +1082,45 @@
             _timeout = fabs(getFloatUserInput());
         }
         
+        else if (user_input == 'C' or user_input == 'c') {
+                
+            pc().printf("\r\n\nCURRENT STATUS AND PARAMETERS:\r\n");
+            
+            pc().printf("raw BCE pos: %d \r\n",adc().readCh0());
+            pc().printf("raw BMM pos: %d \r\n",adc().readCh1());
+            pc().printf("raw BCE current sense: %d \r\n",adc().readCh2());
+            pc().printf("raw BMM current sense: %d \r\n",adc().readCh3());
+            pc().printf("raw depth pressure: %d \r\n",adc().readCh4());
+            pc().printf("raw vessel pressure %d (internal psi: %0.1f)\r\n", adc().readCh5(),sensors().getInternalPressurePSI());
+            //pc().printf("raw vessel pressure: %d \r\n",adc().readCh5());
+            pc().printf("raw board voltage: %d (%0.1f volts)\r\n",adc().readCh6(),sensors().getVoltageInput());
+            pc().printf("raw board current: %d (%0.3f amps)\r\n",adc().readCh7(), sensors().getCurrentInput());
+            pc().printf("raw BCE limit switch: %d \r\n",bce().getSwitch());
+            pc().printf("raw BMM limit switch: %d \r\n",batt().getSwitch());
+            pc().printf("calc vessel pressure: %f (counts: %d) \r\n",sensors().getInternalPressurePSI(),adc().readCh5());
+            // End of ADC Test
+            
+            pc().printf("depth: %3.1f ft\r\n",depthLoop().getPosition());
+            pc().printf("pitch: %3.1f deg\r\n",imu().getPitch());
+            pc().printf("bce().getPosition_mm(): %3.1f\r\n",bce().getPosition_mm());
+            pc().printf("bce().getSetPosition_mm(): %3.1f\r\n",bce().getSetPosition_mm());
+            pc().printf("batt().getPosition_mm(): %3.1f\r\n",batt().getPosition_mm());
+            pc().printf("batt().getSetPosition_mm(): %3.1f\r\n",batt().getSetPosition_mm());
+            pc().printf("depthLoop().getCommand(): %3.1f\r\n",depthLoop().getCommand());
+            pc().printf("pitchLoop().getCommand(): %3.1f\r\n",pitchLoop().getCommand());
+            
+            pc().printf("\r\nNeutral Buoyancy Positions: bce: %0.1f, batt: %0.1f\r\n",_neutral_bce_pos_mm,_neutral_batt_pos_mm);
+            pc().printf("depthLoop().getOutputOffset(): %0.1f\r\n",depthLoop().getOutputOffset());
+            pc().printf("pitchLoop().getOutputOffset(): %0.1f\r\n",pitchLoop().getOutputOffset());
+            pc().printf("Max recorded depth: neutral: %0.1f, dive: %0.1f, auto_neutral_depth: %0.1f\r\n\n",_max_recorded_depth_neutral, _max_recorded_depth_dive, _max_recorded_auto_neutral_depth);
+            
+            pc().printf("\r\n");
+            pc().printf("bce    P:%6.2f, I:%6.2f, D:%6.2f,   zero offset: %3i, limit %6.1f mm, slope %0.5f  \r\n", bce().getControllerP(), bce().getControllerI(), bce().getControllerD(), bce().getZeroCounts(), bce().getTravelLimit(), bce().getPotSlope());
+            pc().printf("batt   P:%6.2f, I:%6.2f, D:%6.2f,   zero offset: %3i, limit %6.1f mm, slope %0.5f  \r\n", batt().getControllerP(), batt().getControllerI(), batt().getControllerD(), batt().getZeroCounts(), batt().getTravelLimit(), batt().getPotSlope());
+            pc().printf("depth  P:%6.2f, I:%6.2f, D:%6.2f, output offset: %6.1f mm \r\n", depthLoop().getControllerP(), depthLoop().getControllerI(), depthLoop().getControllerD(), depthLoop().getOutputOffset());
+            pc().printf("pitch  P:%6.2f, I:%6.2f, D:%6.2f, output offset: %6.1f mm \r\n", pitchLoop().getControllerP(), pitchLoop().getControllerI(), pitchLoop().getControllerD(), pitchLoop().getOutputOffset());
+        }
+        
     /***************************** COMMON COMMANDS *****************************/
         
 /***************************** DEBUG MENU *****************************/             
@@ -1151,10 +1177,6 @@
             else if (user_input == 'X') {
                 mbedLogger().printMbedDirectory();        //print all log files to the screen
             }
-            else if (user_input == 'G') {
-                wait(1);
-                _keyboard_state = TX_MBED_LOG;
-            }
             else if (user_input == 'I') {
                 mbedLogger().receiveMissionDataWithTicker();    //receive sequence.txt files
             }
@@ -1215,7 +1237,7 @@
                 pitchLoop().setOutputOffset(_neutral_batt_pos_mm); // decrease the batt neutral setpoint
                 pc().printf("Adjusting batt neutral position. new offset: %0.1f\r\n",pitchLoop().getOutputOffset());
                 // save neutral pitch value to config file
-                configFileIO().savePitchData(_pitch_KP, _pitch_KI, _pitch_KD, _neutral_batt_pos_mm);
+                configFileIO().savePitchData(_pitch_KP, _pitch_KI, _pitch_KD, _neutral_batt_pos_mm, _pitch_filter_freq, _pitch_deadband); //P,I,D,batt zeroOffset
             }
             
             //BCE/DEPTH
@@ -1225,17 +1247,17 @@
                 depthLoop().setOutputOffset(_neutral_bce_pos_mm); // decrease the bce neutral setpoint
                 pc().printf("Adjusting bce neutral position. new offset: %0.1f\r\n",depthLoop().getOutputOffset());
                 // save neutral depth value to config file
-                configFileIO().saveDepthData(_depth_KP, _depth_KI, _depth_KD, _neutral_bce_pos_mm);
+                configFileIO().saveDepthData(_depth_KP, _depth_KI, _depth_KD, _neutral_bce_pos_mm, _depth_filter_freq, _depth_deadband);
             }
      
     // change settings
             //heading is in the common controls        
             else if (user_input == 'Q') {
-                pc().printf(">> Please enter the desired depth (ft).\r\n");
+                pc().printf(">> Please enter the desired PITCH (deg).\r\n");
                 _pitch_command = getFloatUserInput();
             }
             else if (user_input == 'A') {
-                pc().printf(">> Please enter the desired pitch (deg).\r\n");
+                pc().printf(">> Please enter the desired DEPTH (ft).\r\n");
                 _depth_command = getFloatUserInput();
             }
             
@@ -1252,9 +1274,9 @@
                 keyboard_menu_MANUAL_TUNING();
             }
             
-            else if (user_input == 'U') {
-                keyboard_menu_POSITION_READINGS();
-            }
+//            else if (user_input == 'U') {
+//                keyboard_menu_POSITION_READINGS();
+//            }
             
             // go to sub-menus for the PID gains (this is blocking)
             else if (user_input == '1') {
@@ -1269,49 +1291,7 @@
             else if (user_input == '4') {
                 keyboard_menu_PITCH_PID_settings();
             }
-            
-            else if (user_input == 'C' or user_input == 'c') {
-                
-                pc().printf("\r\n\nCURRENT STATUS AND PARAMETERS:\r\n");
-                
-                // Testing out ADC
-                float vref = 5.6;
-                float vmeasured = 0;
-                unsigned int raw = adc().readCh5();
-                vmeasured = ((float)raw)/4095.0*vref;
-                pc().printf("raw BCE pos: %d \r\n",adc().readCh0());
-                pc().printf("raw BMM pos: %d \r\n",adc().readCh1());
-                pc().printf("raw BCE current sense: %d \r\n",adc().readCh2());
-                pc().printf("raw BMM current sense: %d \r\n",adc().readCh3());
-                pc().printf("raw depth pressure: %d \r\n",adc().readCh4());
-                pc().printf("raw vessel pressure: %d \r\n",adc().readCh5());
-                pc().printf("raw battery voltage: %d \r\n",adc().readCh6());
-                pc().printf("raw board current: %d \r\n",adc().readCh7());
-                pc().printf("raw BCE limit switch: %d \r\n",bce().getSwitch());
-                pc().printf("raw BMM limit switch: %d \r\n",batt().getSwitch());
-                pc().printf("raw vessel pressure: %f %d \r\n",vmeasured,raw);
-                // End of ADC Test
-                
-                pc().printf("depth: %3.1f ft\r\n",depthLoop().getPosition());
-                pc().printf("pitch: %3.1f deg\r\n",imu().getPitch());
-                pc().printf("bce().getPosition_mm(): %3.1f\r\n",bce().getPosition_mm());
-                pc().printf("bce().getSetPosition_mm(): %3.1f\r\n",bce().getSetPosition_mm());
-                pc().printf("batt().getPosition_mm(): %3.1f\r\n",batt().getPosition_mm());
-                pc().printf("batt().getSetPosition_mm(): %3.1f\r\n",batt().getSetPosition_mm());
-                pc().printf("depthLoop().getCommand(): %3.1f\r\n",depthLoop().getCommand());
-                pc().printf("pitchLoop().getCommand(): %3.1f\r\n",pitchLoop().getCommand());
-                
-                pc().printf("\r\nNeutral Buoyancy Positions: bce: %0.1f, batt: %0.1f\r\n",_neutral_bce_pos_mm,_neutral_batt_pos_mm);
-                pc().printf("depthLoop().getOutputOffset(): %0.1f\r\n",depthLoop().getOutputOffset());
-                pc().printf("pitchLoop().getOutputOffset(): %0.1f\r\n",pitchLoop().getOutputOffset());
-                pc().printf("Max recorded depth: neutral: %0.1f, dive: %0.1f, auto_neutral_depth: %0.1f\r\n\n",_max_recorded_depth_neutral, _max_recorded_depth_dive, _max_recorded_auto_neutral_depth);
-                
-                pc().printf("\r\n");
-                pc().printf("bce    P:%6.2f, I:%6.2f, D:%6.2f, zero %3i, limit %6.1f mm, slope %0.5f  \r\n", bce().getControllerP(), bce().getControllerI(), bce().getControllerD(), bce().getZeroCounts(), bce().getTravelLimit(), bce().getPotSlope());
-                pc().printf("batt   P:%6.2f, I:%6.2f, D:%6.2f, zero %3i, limit %6.1f mm, slope %0.5f  \r\n", batt().getControllerP(), batt().getControllerI(), batt().getControllerD(), batt().getZeroCounts(), batt().getTravelLimit(), batt().getPotSlope());
-                pc().printf("depth  P:%6.2f, I:%6.2f, D:%6.2f, offset:%6.1f mm \r\n", depthLoop().getControllerP(), depthLoop().getControllerI(), depthLoop().getControllerD(), depthLoop().getOutputOffset());
-                pc().printf("pitch  P:%6.2f, I:%6.2f, D:%6.2f, offset:%6.1f mm \r\n", pitchLoop().getControllerP(), pitchLoop().getControllerI(), pitchLoop().getControllerD(), pitchLoop().getOutputOffset());
-            }            
+                     
             else if (user_input == '*') {
                 pc().printf("SWITCHING TO SIMPLE MENU!\r\n"); 
                 wait(2);
@@ -1344,65 +1324,11 @@
                 //printCurrentSdLog();
                 mbedLogger().printCurrentLogFile();        //print the current log file to the screen
             }
-            else if (user_input == 'G') {
-                wait(1);
-                _keyboard_state = TX_MBED_LOG;
-            }
             else if (user_input == '~') {
                 pc().printf("ERASING MBED LOG FILE\r\n"); 
                 mbedLogger().eraseFile();
             }
             
-            else if (user_input == 'C' or user_input == 'c') {
-                
-                pc().printf("\r\n\nCURRENT STATUS AND PARAMETERS:\r\n");
-                
-                // Testing out ADC
-                float vref = 5.6;
-                float vmeasured = 0;
-                unsigned int raw = adc().readCh5();
-                vmeasured = ((float)raw)/4095.0*vref;
-                
-                //same equations in mbed logger
-                float press_xducer_PSI = (22.029*(5.0*adc().readCh5()/4095.0) + 10.884) * 0.145038; // Press_Xducer (on-board)
-                float voltage_input = (adc().readCh6()/4095.0) * 5.0 * 7.8;   //tnh
-                float current_input = adc().readCh7()/4095.0;
-                
-                pc().printf("raw BCE pos: %d \r\n",adc().readCh0());
-                pc().printf("raw BMM pos: %d \r\n",adc().readCh1());
-                pc().printf("raw BCE current sense: %d \r\n",adc().readCh2());
-                pc().printf("raw BMM current sense: %d \r\n",adc().readCh3());
-                pc().printf("raw depth pressure: %d \r\n",adc().readCh4());
-                pc().printf("raw vessel pressure %d (internal psi: %0.1f)\r\n", adc().readCh5(),press_xducer_PSI);
-                //pc().printf("raw vessel pressure: %d \r\n",adc().readCh5());
-                pc().printf("raw board voltage: %d (%0.1f volts)\r\n",adc().readCh6(),voltage_input);
-                pc().printf("raw board current: %d (%0.3f amps)\r\n",adc().readCh7(), current_input);
-                pc().printf("raw BCE limit switch: %d \r\n",bce().getSwitch());
-                pc().printf("raw BMM limit switch: %d \r\n",batt().getSwitch());
-                pc().printf("raw vessel pressure: %f %d \r\n",vmeasured,raw);
-                // End of ADC Test
-                
-                pc().printf("depth: %3.1f ft\r\n",depthLoop().getPosition());
-                pc().printf("pitch: %3.1f deg\r\n",imu().getPitch());
-                pc().printf("bce().getPosition_mm(): %3.1f\r\n",bce().getPosition_mm());
-                pc().printf("bce().getSetPosition_mm(): %3.1f\r\n",bce().getSetPosition_mm());
-                pc().printf("batt().getPosition_mm(): %3.1f\r\n",batt().getPosition_mm());
-                pc().printf("batt().getSetPosition_mm(): %3.1f\r\n",batt().getSetPosition_mm());
-                pc().printf("depthLoop().getCommand(): %3.1f\r\n",depthLoop().getCommand());
-                pc().printf("pitchLoop().getCommand(): %3.1f\r\n",pitchLoop().getCommand());
-                
-                pc().printf("\r\nNeutral Buoyancy Positions: bce: %0.1f, batt: %0.1f\r\n",_neutral_bce_pos_mm,_neutral_batt_pos_mm);
-                pc().printf("depthLoop().getOutputOffset(): %0.1f\r\n",depthLoop().getOutputOffset());
-                pc().printf("pitchLoop().getOutputOffset(): %0.1f\r\n",pitchLoop().getOutputOffset());
-                pc().printf("Max recorded depth: neutral: %0.1f, dive: %0.1f, auto_neutral_depth: %0.1f\r\n\n",_max_recorded_depth_neutral, _max_recorded_depth_dive, _max_recorded_auto_neutral_depth);
-                
-                pc().printf("\r\n");
-                pc().printf("bce    P:%6.2f, I:%6.2f, D:%6.2f, zero %3i, limit %6.1f mm, slope %0.5f  \r\n", bce().getControllerP(), bce().getControllerI(), bce().getControllerD(), bce().getZeroCounts(), bce().getTravelLimit(), bce().getPotSlope());
-                pc().printf("batt   P:%6.2f, I:%6.2f, D:%6.2f, zero %3i, limit %6.1f mm, slope %0.5f  \r\n", batt().getControllerP(), batt().getControllerI(), batt().getControllerD(), batt().getZeroCounts(), batt().getTravelLimit(), batt().getPotSlope());
-                pc().printf("depth  P:%6.2f, I:%6.2f, D:%6.2f, offset:%6.1f mm \r\n", depthLoop().getControllerP(), depthLoop().getControllerI(), depthLoop().getControllerD(), depthLoop().getOutputOffset());
-                pc().printf("pitch  P:%6.2f, I:%6.2f, D:%6.2f, offset:%6.1f mm \r\n", pitchLoop().getControllerP(), pitchLoop().getControllerI(), pitchLoop().getControllerD(), pitchLoop().getOutputOffset());
-            }
-            
 //POSITION DIVE COMMANDS
             else if (user_input == 'Q') {
                 pc().printf(">> Please enter the desired BMM offset (mm).\r\n");
@@ -1412,6 +1338,11 @@
                 pc().printf(">> Please enter the desired BCE offset (mm).\r\n");
                 _BCE_dive_offset = getFloatUserInput();
             }
+            
+            else if (user_input == 'S') {
+                pc().printf(">> Please enter the desired DEPTH (ft).\r\n");
+                _depth_command = getFloatUserInput();
+            }
 //POSITION DIVE COMMANDS
             
             else if (user_input == '*') {
@@ -1444,29 +1375,8 @@
             wait(1);         
             
             
-            pc().printf("BCE POS (CMD): %0.1f (%0.1f) BATT POS: %0.1f (%0.1f) PRESS_psi: %0.2f [depth_ft: %0.2f], PITCH: %0.2f, HEADING: %0.2f, rudder_servo_pwm: %0.1f [0(%d),1(%d),2(%d),6(%d),4(%d),5(%d),6(%d),7(%d)] Switch: BCE(%d) BMM(%d)\r",bce().getPosition_mm(), bce().getSetPosition_mm(),batt().getPosition_mm(), batt().getSetPosition_mm(),depth().getPsi(),depthLoop().getPosition(),imu().getPitch(),imu().getHeading(),rudder().getPosition_pwm(),adc().readCh0(),adc().readCh1(),adc().readCh2(),adc().readCh3(),adc().readCh4(),adc().readCh5(),adc().readCh6(),adc().readCh7(), bce().getHardwareSwitchStatus(),batt().getHardwareSwitchStatus());
-            //pc().printf("BCE POS (CMD): %0.1f (%0.1f) BATT POS: %0.1f (%0.1f) PRESS_psi: %0.2f (unfiltered: %0.2f) [depth_ft: %0.2f], PITCH: %0.2f, HEADING: %0.2f, rudder_servo_pwm: %0.1f\r",bce().getPosition_mm(), bce().getSetPosition_mm(),batt().getPosition_mm(), batt().getSetPosition_mm(),depth().getPsi(),depth().getRawPSI(),depthLoop().getPosition(),imu().getPitch(),imu().getHeading(),rudder().getPosition_pwm());
-            //pc().printf("\n0(%d),1(%d),2(%d),6(%d),4(%d),5(%d),6(%d),7(%d)\r\n",adc().readCh0(),adc().readCh1(),adc().readCh2(),adc().readCh3(),adc().readCh4(),adc().readCh5(),adc().readCh6(),adc().readCh7()); 
-            
-            
-            //pc().printf("(set) BCE POS: %0.1f (%0.1f) BATT POS: %0.1f (%0.1f) PRESS: %0.2f )(channel reading: %d) (volt: %0.2f) << %0.2f >> (Pressure: %0.2f (raw: %0.2f) PITCH: %0.2f HEADING: %0.2f)\r\n",bce().getPosition_mm(), bce().getSetPosition_mm(),batt().getPosition_mm(), batt().getSetPosition_mm(), depthLoop().getPosition(),depth().readADCCounts(),depth().readVoltage(),depth().getPsi(),depth().getRawPSI(),depth().getRawPSI(),imu().getPitch(),imu().getHeading());
-            
-            //pc().printf("Neutral Buoyancy Positions: bce: %0.1f, batt: %0.1f\r\n",_neutral_bce_pos_mm,_neutral_batt_pos_mm);
-//            pc().printf("depth: %3.1f ft\r\n",depthLoop().getPosition());
-//            pc().printf("pitch: %3.1f deg\r\n",imu().getPitch());
-//            pc().printf("heading (rudder): %3.1f deg\r\n",rudderLoop().getPosition());                   //for heading
-            
-//            pc().printf("bce().getPosition_mm(): %3.1f\r\n",bce().getPosition_mm());
-//            pc().printf("bce().getSetPosition_mm(): %3.1f\r\n",bce().getSetPosition_mm());
-//            
-//            pc().printf("batt().getPosition_mm(): %3.1f\r\n",batt().getPosition_mm());
-//            pc().printf("batt().getSetPosition_mm(): %3.1f\r\n",batt().getSetPosition_mm());
-            
-//            pc().printf("depthLoop().getCommand(): %3.1f\r\n",depthLoop().getCommand());
-//            pc().printf("depthLoop().getOutputOffset(): %0.1f\r\n",depthLoop().getOutputOffset());
-//            
-//            pc().printf("pitchLoop().getCommand(): %3.1f\r\n",pitchLoop().getCommand());
-//            pc().printf("pitchLoop().getOutputOffset(): %0.1f\r\n",pitchLoop().getOutputOffset());   
+//            pc().printf("BCE POS (CMD): %0.1f (%0.1f) BATT POS: %0.1f (%0.1f) PRESS_psi: %0.2f [depth_ft: %0.2f], PITCH: %0.2f, HEADING: %0.2f, rudder_servo_pwm: %0.1f \n[FILT/RAW 0(%d,%d),1(%d),2(%d),6(%d),4(%d),5(%d),6(%d),7(%d)] Switch: BCE(%d) BMM(%d)\r",bce().getPosition_mm(), bce().getSetPosition_mm(),batt().getPosition_mm(), batt().getSetPosition_mm(),depth().getPsi(),depthLoop().getPosition(),imu().getPitch(),imu().getHeading(),rudder().getPosition_pwm(),adc().readCh0(),adc().readCh1(),adc().readCh2(),adc().readCh3(),adc().readCh4(),adc().readCh5(),adc().readCh6(),adc().readCh7(), bce().getHardwareSwitchStatus(),batt().getHardwareSwitchStatus()); 
+            pc().printf("BCE POS: %0.1f (cmd %0.1f) BATT POS: %0.1f (cmd %0.1f) PRESS_psi: %0.2f [depth_ft: %0.2f], PITCH: %0.2f, HEADING: %0.2f, rdr_pwm: %0.1f [FILT/RAW 0(%d,%d),1(%d,%d),2(%d,%d),3(%d,%d),4(%d,%d),5(%d,%d),6(%d,%d),7(%d,%d)] Switch: BCE(%d) BMM(%d)\r",bce().getPosition_mm(), bce().getSetPosition_mm(),batt().getPosition_mm(), batt().getSetPosition_mm(),depth().getPsi(),depthLoop().getPosition(),imu().getPitch(),imu().getHeading(),rudder().getPosition_pwm(),adc().readCh0(),adc().readRawCh0(),adc().readCh1(),adc().readRawCh1(),adc().readCh2(),adc().readRawCh2(),adc().readCh3(),adc().readRawCh3(),adc().readCh4(),adc().readRawCh4(),adc().readCh5(),adc().readRawCh5(),adc().readCh6(),adc().readRawCh6(),adc().readCh7(),adc().readRawCh7(),bce().getHardwareSwitchStatus(),batt().getHardwareSwitchStatus()); 
             
             continue; // didn't get a user input, so keep waiting for it
         }
@@ -1560,68 +1470,8 @@
     }
 }
 
-void StateMachine::keyboard_menu_HEADING_PID_settings() {    
-    char HEADING_PID_key;
-    
-    float heading_KP = headingLoop().getControllerP();
-    float heading_KI = headingLoop().getControllerI();
-    float heading_KD = headingLoop().getControllerD();    
-    float heading_offset_deg = headingLoop().getOutputOffset();
- 
-    // print the menu
-    pc().printf("\n\rHEADING (rudder outer loop) PID gain settings (MENU)");
-    pc().printf("\n\r   Adjust PID settings with the following keys: P and I and D");
-    pc().printf("\n\r   Adjust zero offset with O (oh)");
-    pc().printf("\n\r(Hit shift + X to exit w/o saving.  Hit shift + S to save.\n\r");
-    pc().printf("HEADING P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm \r\n", headingLoop().getControllerP(), headingLoop().getControllerI(), headingLoop().getControllerD(), headingLoop().getOutputOffset());
- 
-    // handle the key presses
-    while(1) {
-        // get the user's keystroke from either of the two inputs
-        if (pc().readable()) {
-            HEADING_PID_key = pc().getc();
-        }
-        else {
-            continue; // didn't get a user input, so keep waiting for it
-        }
- 
-        // handle the user's key input     
-        if (HEADING_PID_key == 'S') { // user wants to save the modified values
-            // set global values
-            headingLoop().setControllerP(heading_KP);
-            headingLoop().setControllerI(heading_KI);
-            headingLoop().setControllerD(heading_KD);
-            headingLoop().setOutputOffset(heading_offset_deg);
-            
-            // save pitch PID values for outer loop (must save neutral position also)
-            configFileIO().saveHeadingData(heading_KP, heading_KI, heading_KD, heading_offset_deg);    //_neutral_heading_pos_deg);
-            pc().printf("HEADING P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm \r\n", headingLoop().getControllerP(), headingLoop().getControllerI(), headingLoop().getControllerD(), headingLoop().getOutputOffset());
-        }
-        else if (HEADING_PID_key == 'X') {    
-            break;  //exit the while loop
-        }
-        
-        else if (HEADING_PID_key == 'P') {
-            heading_KP = getFloatUserInput();;
-        }
-        else if (HEADING_PID_key == 'I') {
-            heading_KI = getFloatUserInput();
-        }
-        else if (HEADING_PID_key == 'D') {
-            heading_KD = getFloatUserInput();
-        }
-        else if (HEADING_PID_key == 'O') {
-            heading_offset_deg = getFloatUserInput();
-        }
-        
-        else {
-            pc().printf("HEADING SETUP: [%c] This key does nothing here.                           \r", HEADING_PID_key);
-        }
-    }
-}
-
 void StateMachine::keyboard_menu_COUNTS_STATUS() {
-    
+    // DELETE REMOVE  
 }
 
 void StateMachine::keyboard_menu_MANUAL_TUNING() {
@@ -1757,60 +1607,43 @@
     }
 }
 
-void StateMachine::keyboard_menu_POSITION_READINGS() {
-    char TUNING_key;
-        
-    // show the menu
-    pc().printf("\r\n9: BCE and BMM POSITION READINGS (EXIT WITH 'X' !)");
-    
-    while (1) {
-        if (pc().readable()) {
-            TUNING_key = pc().getc();   //get each keystroke
-        }
-        
-                // process the keys            
-        if (TUNING_key == 'X') {    
-            // STOP THE MOTORS BEFORE LEAVING! (Just in case.)
-            bce().pause();
-            batt().pause();
-            
-            break;  //exit the while loop
-        }
-        
-        else {
-            // Testing out ADC
-            wait(0.5);
-            float vref = 5.6;
-            float vmeasured = 0;
-            unsigned int raw = adc().readCh5();
-            vmeasured = ((float)raw)/4095.0*vref;
-            
-                    
-            //pc().printf("BCE POS(%d),BMM POS(%d), BCE CUR(%d), BMM CUR(%d), Depth Pressure (%d) \r\n",adc().readCh0(),adc().readCh1(),adc().readCh2(),adc().readCh3(),adc().readCh4());
-            
-            pc().printf("BCE POS(%d), BMM POS(%d), BCE CUR(%d), BMM CUR(%d), Depth Pressure (%d)  << POS: BCE %0.2f, BATT %0.2f >>\r\n",adc().readCh0(),adc().readCh1(),adc().readCh2(),adc().readCh3(),adc().readCh4(),bce().getPosition_mm(),batt().getPosition_mm());
-            
-            //pc().printf("vessel pressure(%d) batt voltage(%d) board current(%d) LIMIT: BCE(%d) BMM(%d) (HW reading limit: BCE(%d) BMM (%d) \r\n",adc().readCh5(),adc().readCh6(),adc().readCh7(),bce().getSwitch(), batt().getSwitch(),bce().getSwitchState(),batt().getSwitchState());
-            //pc().printf("LIMIT: BCE(%d) BMM(%d) << HW reading limit: BCE(%d) BMM (%d) >> \r\n",bce().getSwitch(), batt().getSwitch(),bce().getHWSwitchReading(),batt().getHWSwitchReading());
-            //pc().printf("raw vessel pressure: %f %d \r\n",vmeasured,raw);
-            // End of ADC Test
-            
-//            pc().printf("raw BCE pos: %d \r\n",adc().readCh0());
-//            pc().printf("raw BMM pos: %d \r\n",adc().readCh1());
-//            pc().printf("raw BCE current sense: %d \r\n",adc().readCh2());
-//            pc().printf("raw BMM current sense: %d \r\n",adc().readCh3());
-//            pc().printf("raw depth pressure: %d \r\n",adc().readCh4());
-//            pc().printf("raw vessel pressure: %d \r\n",adc().readCh5());
-//            pc().printf("raw battery voltage: %d \r\n",adc().readCh6());
-//            pc().printf("raw board current: %d \r\n",adc().readCh7());
-            
-            continue; // didn't get a user input, so keep waiting for it
-        }            
-    }
-}
+//void StateMachine::keyboard_menu_POSITION_READINGS() {
+//    char TUNING_key;
+//        
+//    // show the menu
+//    pc().printf("\r\n9: BCE and BMM POSITION READINGS (EXIT WITH 'X' !)");
+//    
+//    while (1) {
+//        if (pc().readable()) {
+//            TUNING_key = pc().getc();   //get each keystroke
+//        }
+//        
+//                // process the keys            
+//        if (TUNING_key == 'X') {    
+//            // STOP THE MOTORS BEFORE LEAVING! (Just in case.)
+//            bce().pause();
+//            batt().pause();
+//            
+//            break;  //exit the while loop
+//        }
+//        
+//        else {
+//            // Testing out ADC
+//            wait(0.5);
+//            float vref = 5.6;
+//            float vmeasured = 0;
+//            unsigned int raw = adc().readCh5();
+//            vmeasured = ((float)raw)/4095.0*vref;
+//            
+//            pc().printf("BCE POS(%d), BMM POS(%d), BCE CUR(%d), BMM CUR(%d), Depth Pressure (%d)  << POS: BCE %0.2f, BATT %0.2f >>\r\n",adc().readCh0(),adc().readCh1(),adc().readCh2(),adc().readCh3(),adc().readCh4(),bce().getPosition_mm(),batt().getPosition_mm());
+//   
+//            continue; // didn't get a user input, so keep waiting for it
+//        }            
+//    }
+//}
  
 void StateMachine::keyboard_menu_BCE_PID_settings() {    
-    char PID_key;
+    char BCE_PID_key;
     
     float bce_KP = bce().getControllerP();  // load current value
     float bce_KI = bce().getControllerI();  // load current global value
@@ -1818,54 +1651,64 @@
  
     // show the menu
     pc().printf("\n\rBuoyancy Engine PID gain settings (MENU)");
-    pc().printf("\n\r(Adjust PID settings with the following keys: P and I and D");
+    pc().printf("\n\rAdjust PID settings with the following keys: P I D. Filter = F, deadband = B.\n\r");
     pc().printf("\n\r(Hit shift + X to exit w/o saving.  Hit shift + S to save.)\n\n\n\r");
-    pc().printf("bce    P: %3.3f, I: %3.3f, D %3.3f, zero %d, limit %3.0f mm, slope %3.3f  \r\n", bce().getControllerP(), bce().getControllerI(), bce().getControllerD(), bce().getZeroCounts(), bce().getTravelLimit(), bce().getPotSlope());
+    pc().printf("bce    P: %3.3f, I: %3.3f, D %3.3f, zeroOffset %d, limit %3.0f mm, slope %3.3f  \r\n", bce().getControllerP(), bce().getControllerI(), bce().getControllerD(), bce().getZeroCounts(), bce().getTravelLimit(), bce().getPotSlope());
     
     // handle the key presses
     while(1) {
         // get the user's keystroke from either of the two inputs
         if (pc().readable()) {
-            PID_key = pc().getc();
+            BCE_PID_key = pc().getc();
         }
         else {
             continue; // didn't get a user input, so keep waiting for it
         }
     
         // handle the user's key input
-        if (PID_key == 'S') { // user wants to save these modified values
+        if (BCE_PID_key == 'S') { // user wants to save these modified values
             // set values
             bce().setControllerP(bce_KP);
             bce().setControllerI(bce_KI);
             bce().setControllerD(bce_KD);  
  
-            // save to "BATT.TXT" file
-            configFileIO().saveBCEData(bce_KP, bce_KI, bce_KD);
+            // save to "BCE.TXT" file
+            configFileIO().saveBCEData(bce_KP, bce_KI, bce_KD, 100, 6.0, 0.5);
             pc().printf("bce    P: %3.3f, I: %3.3f, D %3.3f, zero %d, limit %3.0f mm, slope %3.3f  \r\n", bce().getControllerP(), bce().getControllerI(), bce().getControllerD(), bce().getZeroCounts(), bce().getTravelLimit(), bce().getPotSlope());
         }
-        else if (PID_key == 'X') {    
+        else if (BCE_PID_key == 'X') {    
             break;  //exit the while loop
         }
-        else if (PID_key == 'P') {
+        else if (BCE_PID_key == 'P') {
             pc().printf(">> Type in proportional gain with keyboard.\n\r");
             bce_KP = getFloatUserInput();
         }
-        else if (PID_key == 'I') {
+        else if (BCE_PID_key == 'I') {
             pc().printf(">> Type in integral gain with keyboard.\n\r");
             bce_KI = getFloatUserInput();
         }
-        else if (PID_key == 'D') {
+        else if (BCE_PID_key == 'D') {
             pc().printf(">> Type in derivative gain with keyboard.\n\r");
             bce_KD = getFloatUserInput();
         }
+        else if (BCE_PID_key == 'F') {
+            pc().printf(">> Type in FILTER FREQUENCY with keyboard.\n\r");
+            float bce_freq = getFloatUserInput();
+            bce().setFilterFrequency(bce_freq);
+        }
+        else if (BCE_PID_key == 'B') {
+            pc().printf(">> Type in DEADBAND with keyboard.\n\r");
+            float bce_deadband = getFloatUserInput();
+            bce().setDeadband(bce_deadband);
+        }
         else {
-            pc().printf("\n\rBCE: [%c] This key does nothing here.                                  \r", PID_key);
+            pc().printf("\n\rBCE: [%c] This key does nothing here.                                  \r", BCE_PID_key);
         }
     }
 }
 
 void StateMachine::keyboard_menu_BATT_PID_settings() {    
-    char PID_key;
+    char BMM_PID_key;
     
     float batt_KP = batt().getControllerP(); // load current global value
     float batt_KI = batt().getControllerI(); // load current global value
@@ -1873,7 +1716,7 @@
  
     // print the menu
     pc().printf("\n\rBattery Motor PID gain settings (MENU)");
-    pc().printf("\n\r(Adjust PID settings with the following keys: P and I and D");
+    pc().printf("\n\rAdjust PID settings with the following keys: P I D. Filter = F, deadband = B.\n\r");
     pc().printf("\n\r(Hit shift + X to exit w/o saving.  Hit shift + S to save.)\n\n\n\r");
     pc().printf("batt    P: %3.3f, I: %3.3f, D %3.3f, zero %d, limit %3.0f mm, slope %3.3f  \r\n", batt().getControllerP(), batt().getControllerI(), batt().getControllerD(), batt().getZeroCounts(), batt().getTravelLimit(), batt().getPotSlope());
     
@@ -1881,159 +1724,279 @@
     while(1) {
         // get the user's keystroke from either of the two inputs
         if (pc().readable()) {
-            PID_key = pc().getc();
+            BMM_PID_key = pc().getc();
         }
         else {
             continue; // didn't get a user input, so keep waiting for it
         }
     
         // handle the user's key input
-        if (PID_key == 'S') { // user wants to save these modified values
+        if (BMM_PID_key == 'S') { // user wants to save these modified values
             // set values
             batt().setControllerP(batt_KP);
             batt().setControllerI(batt_KI);
             batt().setControllerD(batt_KD);  
  
             // save to "BATT.TXT" file
-            configFileIO().saveBattData(batt_KP, batt_KI, batt_KD);
+            configFileIO().saveBattData(batt_KP, batt_KI, batt_KD, 100, 6.0, 0.5);
             pc().printf("batt    P: %3.3f, I: %3.3f, D %3.3f, zero %d, limit %3.0f mm, slope %3.3f  \r\n", batt().getControllerP(), batt().getControllerI(), batt().getControllerD(), batt().getZeroCounts(), batt().getTravelLimit(), batt().getPotSlope());
         }
-        else if (PID_key == 'X') {    
+        else if (BMM_PID_key == 'X') {    
             break;  //exit the while loop
         }
-        else if (PID_key == 'P') {
+        else if (BMM_PID_key == 'P') {
             pc().printf(">> Type in proportional gain with keyboard.\n\r");
             batt_KP = getFloatUserInput();
         }
-        else if (PID_key == 'I') {
+        else if (BMM_PID_key == 'I') {
             pc().printf(">> Type in integral gain with keyboard.\n\r");
             batt_KI = getFloatUserInput();
         }
-        else if (PID_key == 'D') {
+        else if (BMM_PID_key == 'D') {
             pc().printf(">> Type in derivative gain with keyboard.\n\r");
             batt_KD = getFloatUserInput();
         }
+        else if (BMM_PID_key == 'F') {
+            pc().printf(">> Type in FILTER FREQUENCY with keyboard.\n\r");
+            float batt_freq = getFloatUserInput();
+            batt().setFilterFrequency(batt_freq);
+        }
+        else if (BMM_PID_key == 'B') {
+            pc().printf(">> Type in DEADBAND with keyboard.\n\r");
+            float batt_deadband = getFloatUserInput();
+            batt().setDeadband(batt_deadband);
+        }
         else {
-            pc().printf("\n\rBATT: [%c] This key does nothing here.                                  \r", PID_key);
+            pc().printf("\n\rBATT: [%c] This key does nothing here.                                  \r", BMM_PID_key);
         }
     }
 }
  
 void StateMachine::keyboard_menu_DEPTH_PID_settings() {    
-    char PID_key;
+    char DEPTH_PID_key;
     
     float depth_KP = depthLoop().getControllerP();       // load current depth value
     float depth_KI = depthLoop().getControllerI();       // load current depth value
     float depth_KD = depthLoop().getControllerD();       // load current depth value
+    float depth_freq = depthLoop().getFilterFrequency();
+    float depth_deadband = depthLoop().getDeadband();
  
     // print the menu
     pc().printf("\n\rDEPTH (Buoyancy Engine O.L.) PID gain settings (MENU)");
-    pc().printf("\n\r(Adjust PID settings with the following keys: P and I and D");
+    pc().printf("\n\rAdjust PID settings with the following keys: P I D. Filter = F, deadband = B.\n\r");
     pc().printf("\n\r(Hit shift + X to exit w/o saving.  Hit shift + S to save.)\n\n\n\r");
-    pc().printf("DEPTH P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm \r\n", depthLoop().getControllerP(), depthLoop().getControllerI(), depthLoop().getControllerD(), depthLoop().getOutputOffset());
+    pc().printf("DEPTH P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm (filter: %0.2f, deadband: %0.2f)\r\n", depthLoop().getControllerP(), depthLoop().getControllerI(), depthLoop().getControllerD(),depthLoop().getOutputOffset(),depthLoop().getFilterFrequency(),depthLoop().getDeadband());
     
     // handle the key presses
     while(1) {
         // get the user's keystroke from either of the two inputs
         if (pc().readable()) {
-            PID_key = pc().getc();
+            DEPTH_PID_key = pc().getc();
         }
         else {
             continue; // didn't get a user input, so keep waiting for it
         }
     
         // handle the user's key input
-        if (PID_key == 'S') { // user wants to save these modified values
+        if (DEPTH_PID_key == 'S') { // user wants to save these modified values
             // set values
             depthLoop().setControllerP(depth_KP);
             depthLoop().setControllerI(depth_KI);
-            depthLoop().setControllerD(depth_KD);  
+            depthLoop().setControllerD(depth_KD);
+            depthLoop().setFilterFrequency(depth_freq);
+            depthLoop().setDeadband(depth_deadband);
  
             // save to "DEPTH.TXT" file
-            configFileIO().saveDepthData(depth_KP, depth_KI, depth_KD, _neutral_bce_pos_mm);
-            pc().printf("DEPTH P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm \r\n", depthLoop().getControllerP(), depthLoop().getControllerI(), depthLoop().getControllerD(), depthLoop().getOutputOffset());
+            configFileIO().saveDepthData(depth_KP, depth_KI, depth_KD, _neutral_bce_pos_mm, depth_freq, depth_deadband); //P,I,D, bce zeroOffset
+            
+            pc().printf("DEPTH P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm (filter: %0.2f, deadband: %0.2f)\r\n", depthLoop().getControllerP(), depthLoop().getControllerI(), depthLoop().getControllerD(),depthLoop().getOutputOffset(),depthLoop().getFilterFrequency(),depthLoop().getDeadband());
             
             //set class variables that will be used in find neutral sequence
             _depth_KP = depthLoop().getControllerP();       // load current depth value
             _depth_KI = depthLoop().getControllerI();       // load current depth value
             _depth_KD = depthLoop().getControllerD();       // load current depth value
         }
-        else if (PID_key == 'X') {    
+        else if (DEPTH_PID_key == 'X') {    
             break;  //exit the while loop
         }
-        else if (PID_key == 'P') {
+        else if (DEPTH_PID_key == 'P') {
             pc().printf(">> Type in proportional gain with keyboard.\n\r");
             depth_KP = getFloatUserInput();
         }
-        else if (PID_key == 'I') {
+        else if (DEPTH_PID_key == 'I') {
             pc().printf(">> Type in integral gain with keyboard.\n\r");
             depth_KI = getFloatUserInput();
         }
-        else if (PID_key == 'D') {
+        else if (DEPTH_PID_key == 'D') {
             pc().printf(">> Type in derivative gain with keyboard.\n\r");
             depth_KD = getFloatUserInput();
         }
+        else if (DEPTH_PID_key == 'F') {
+            pc().printf(">> Type in FILTER FREQUENCY with keyboard.\n\r");
+            depth_freq = getFloatUserInput();
+        }
+        else if (DEPTH_PID_key == 'B') {
+            pc().printf(">> Type in DEADBAND with keyboard.\n\r");
+            depth_deadband = getFloatUserInput();
+        }
         else {
-            pc().printf("\n\rDEPTH: [%c] This key does nothing here.                                  \r", PID_key);
+            pc().printf("\n\rDEPTH: [%c] This key does nothing here.                                  \r", DEPTH_PID_key);
         }
     }
 }
  
 void StateMachine::keyboard_menu_PITCH_PID_settings() {    
-    char PID_key;
+    char PITCH_PID_key;
     
     float pitch_KP = pitchLoop().getControllerP();       // load current pitch value
     float pitch_KI = pitchLoop().getControllerI();       // load current pitch value
     float pitch_KD = pitchLoop().getControllerD();       // load current pitch value
+    float pitch_freq = pitchLoop().getFilterFrequency();
+    float pitch_deadband = pitchLoop().getDeadband();
  
     // print the menu
     pc().printf("\n\rPITCH (Battery Motor O.L.) PID gain settings (MENU)");
-    pc().printf("\n\r(Adjust PID settings with the following keys: P and I and D");
+    pc().printf("\n\rAdjust PID settings with the following keys: P I D. Filter = F, deadband = B.\n\r");
     pc().printf("\n\r(Hit shift + X to exit w/o saving.  Hit shift + S to save.)\n\n\n\r");
-    pc().printf("PITCH P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm \r\n", pitchLoop().getControllerP(), pitchLoop().getControllerI(), pitchLoop().getControllerD(), pitchLoop().getOutputOffset());
+    pc().printf("PITCH P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm (filter: %0.2f, deadband: %0.2f)\r\n", pitchLoop().getControllerP(), pitchLoop().getControllerI(), pitchLoop().getControllerD(), pitchLoop().getOutputOffset(),pitchLoop().getFilterFrequency(),pitchLoop().getDeadband());
     
     // handle the key presses
     while(1) {
         // get the user's keystroke from either of the two inputs
         if (pc().readable()) {
-            PID_key = pc().getc();
+            PITCH_PID_key = pc().getc();
         }
         else {
             continue; // didn't get a user input, so keep waiting for it
         }
     
         // handle the user's key input
-        if (PID_key == 'S') { // user wants to save these modified values
+        if (PITCH_PID_key == 'S') { // user wants to save these modified values
             // set values
             pitchLoop().setControllerP(pitch_KP);
             pitchLoop().setControllerI(pitch_KI);
-            pitchLoop().setControllerD(pitch_KD);  
+            pitchLoop().setControllerD(pitch_KD);
+            pitchLoop().setFilterFrequency(pitch_freq);
+            pitchLoop().setDeadband(pitch_deadband);
  
-            // save to "PITCH.TXT" file
-            configFileIO().savePitchData(pitch_KP, pitch_KI, pitch_KD, _neutral_batt_pos_mm);
-            pc().printf("PITCH P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm \r\n", pitchLoop().getControllerP(), pitchLoop().getControllerI(), pitchLoop().getControllerD(), pitchLoop().getOutputOffset());
-                
+            // save to "PITCH.TXT" file (doesn't modify neutral position)
+            configFileIO().savePitchData(pitch_KP, pitch_KI, pitch_KD, _neutral_batt_pos_mm, pitch_freq, pitch_deadband);
+            
+            pc().printf("PITCH P: %3.3f, I: %3.3f, D %3.3f, zeroOffset: %3.1f mm (filter: %0.2f, deadband: %0.2f)\r\n", pitchLoop().getControllerP(), pitchLoop().getControllerI(), pitchLoop().getControllerD(), pitchLoop().getOutputOffset(),pitchLoop().getFilterFrequency(),pitchLoop().getDeadband());
+
             _pitch_KP = pitchLoop().getControllerP();       // load current pitch value
             _pitch_KI = pitchLoop().getControllerI();       // load current pitch value
             _pitch_KD = pitchLoop().getControllerD();       // load current pitch value
         }
-        else if (PID_key == 'X') {    
+        else if (PITCH_PID_key == 'X') {    
             break;  //exit the while loop
         }
-        else if (PID_key == 'P') {
+        else if (PITCH_PID_key == 'P') {
             pc().printf(">> Type in proportional gain with keyboard.\n\r");
             pitch_KP = getFloatUserInput();
         }
-        else if (PID_key == 'I') {
+        else if (PITCH_PID_key == 'I') {
             pc().printf(">> Type in integral gain with keyboard.\n\r");
             pitch_KI = getFloatUserInput();
         }
-        else if (PID_key == 'D') {
+        else if (PITCH_PID_key == 'D') {
             pc().printf(">> Type in derivative gain with keyboard.\n\r");
             pitch_KD = getFloatUserInput();
         }
+        else if (PITCH_PID_key == 'F') {
+            pc().printf(">> Type in FILTER FREQUENCY with keyboard.\n\r");
+            pitch_freq = getFloatUserInput();
+        }
+        else if (PITCH_PID_key == 'B') {
+            pc().printf(">> Type in DEADBAND with keyboard.\n\r");
+            pitch_deadband = getFloatUserInput();
+        }
         else {
-            pc().printf("\n\rPITCH: [%c] This key does nothing here.                                  \r", PID_key);
+            pc().printf("\n\rPITCH: [%c] This key does nothing here.                                  \r", PITCH_PID_key);
+        }
+    }
+}
+
+void StateMachine::keyboard_menu_HEADING_PID_settings() {    
+    char HEADING_PID_key;
+    
+    float heading_KP = headingLoop().getControllerP();
+    float heading_KI = headingLoop().getControllerI();
+    float heading_KD = headingLoop().getControllerD();    
+    float heading_offset_deg = headingLoop().getOutputOffset();
+    float heading_freq = headingLoop().getFilterFrequency();
+    float heading_deadband = headingLoop().getDeadband();
+ 
+    // print the menu
+    pc().printf("\n\rHEADING (rudder outer loop) PID gain settings (MENU)");
+    pc().printf("\n\rAdjust PID settings with the following keys: P I D. Filter = F, deadband = B.\n\r");
+    pc().printf("\n\r   Adjust zero offset with O (oh)");
+    pc().printf("\n\r(Hit shift + X to exit w/o saving.  Hit shift + S to save.\n\r");
+    pc().printf("HEADING P: %3.3f, I: %3.3f, D %3.3f, zeroOffset: %3.1f mm (filter: %0.2f, deadband: %0.2f)\r\n\r\n", headingLoop().getControllerP(),headingLoop().getControllerI(),headingLoop().getControllerD(),headingLoop().getOutputOffset(),pitchLoop().getFilterFrequency(),pitchLoop().getDeadband());
+ 
+    // handle the key presses
+    while(1) {
+        // get the user's keystroke from either of the two inputs
+        if (pc().readable()) {
+            HEADING_PID_key = pc().getc();
+        }
+        else {
+            continue; // didn't get a user input, so keep waiting for it
+        }
+ 
+        // handle the user's key input     
+        if (HEADING_PID_key == 'S') { // user wants to save the modified values
+            // set global values
+            headingLoop().setControllerP(heading_KP);
+            headingLoop().setControllerI(heading_KI);
+            headingLoop().setControllerD(heading_KD);
+            headingLoop().setOutputOffset(heading_offset_deg);
+            
+            // save pitch PID values for outer loop (must save neutral position also)
+            configFileIO().saveHeadingData(heading_KP, heading_KI, heading_KD, heading_offset_deg, 6.0, 0.5);    //_neutral_heading_pos_deg);
+            pc().printf("HEADING P: %3.3f, I: %3.3f, D %3.3f, offset: %3.1f mm \r\n", headingLoop().getControllerP(), headingLoop().getControllerI(), headingLoop().getControllerD(), headingLoop().getOutputOffset());
+        }
+        else if (HEADING_PID_key == 'X') {    
+            break;  //exit the while loop
+        }
+        
+        else if (HEADING_PID_key == 'P') {
+            heading_KP = getFloatUserInput();;
+        }
+        else if (HEADING_PID_key == 'I') {
+            heading_KI = getFloatUserInput();
+        }
+        else if (HEADING_PID_key == 'D') {
+            heading_KD = getFloatUserInput();
+        }
+        else if (HEADING_PID_key == 'F') {
+            pc().printf(">> Type in FILTER FREQUENCY with keyboard.\n\r");
+            heading_freq = getFloatUserInput();
+        }
+        else if (HEADING_PID_key == 'B') {
+            pc().printf(">> Type in DEADBAND with keyboard.\n\r");
+            heading_deadband = getFloatUserInput();
+        }
+        
+//heading offset
+        else if (HEADING_PID_key == 'O') {
+            heading_offset_deg = getFloatUserInput();
+        }
+//heading offset
+        
+        else if (HEADING_PID_key == 'F') {
+            pc().printf(">> Type in FILTER FREQUENCY with keyboard.\n\r");
+            float heading_freq = getFloatUserInput();
+            pitchLoop().setFilterFrequency(heading_freq);
+        } 
+        else if (HEADING_PID_key == 'B') {
+            pc().printf(">> Type in DEADBAND with keyboard.\n\r");
+            float heading_deadband = getFloatUserInput();
+            pitchLoop().setDeadband(heading_deadband);
+        }
+        
+        else {
+            pc().printf("HEADING SETUP: [%c] This key does nothing here.                           \r", HEADING_PID_key);
         }
     }
 }
@@ -2060,6 +2023,8 @@
 
 void StateMachine::setState(int input_state) {
     _state = input_state;
+    
+    _isTimeoutRunning = false;  //to start each state you have to reset this
 }
  
 int StateMachine::getState() {
@@ -2085,10 +2050,6 @@
     pc().printf("Neutral Buoyancy Positions: batt: %0.1f, bce: %0.1f\r\n",_neutral_batt_pos_mm,_neutral_bce_pos_mm);
 }
  
-int StateMachine::timeoutRunning() {
-    return _isTimeoutRunning;
-}
- 
 //process one state at a time
 void StateMachine::getDiveSequence() {
     //iterate through this sequence using the FSM
@@ -2105,15 +2066,6 @@
     //might be worth saving the last few logs to the MBED...
 }
 
-//check if the file is still opened
-void StateMachine::createNewFile() {
-    if (_file_closed) {
-        //mbedLogger().createFile();       //create a new MBED file
-        
-        _file_closed = false;   //file is still open until you get to SIT_IDLE
-    }
-}
-
 // 06/06/2018
 float StateMachine::getFloatUserInput() {
     float float_conversion = 0.0;
@@ -2164,4 +2116,8 @@
     if (bce().getPosition_mm() < 0 or  batt().getPosition_mm() < 0 ) {
         //_state = FLOAT_BROADCAST;        
     }
+}
+
+float StateMachine::getTimerValue() {
+    return _fsm_timer;    
 }
\ No newline at end of file