Scanning Modes

Scanning modes allow for an easy way to configure different states for the application where different sensors can be scanned in each state. For example, you could have a 'sleep' mode scanning a single proximity sensor and an 'active' mode that scans all sensors. You could then alternate between the states based on recent user activity to reduce power consumption.

When switching modes, the first scan result is ignored to allow the filters to properly reset themselves. The mTouch_state.skippedDecode bit will be set if this occured with the most recent decode and should be used to limit when mode changes can occur. An example is provided below.

How It Works

All mTouch sensors, regardless of which mode they are in, are first defined as a normal mTouch sensor in the mTouch_config.h file. The MTOUCH_SENSORx index value for the sensor will be used to configure the modes.

The MTOUCH_SENSORx index value will be referred to as the "sensor index".

You can define up to 10 different modes. Each mode must have at least one sensor being scanned. (If you wish to simply disable scanning, use the mTouch_DisableScanning() macro.) The framework will start in Mode0. All decisions on when to change modes and why are left to the application. To change a mode, use the mTouch_ChangeMode(i) call, where i is the mode number.

The framework will only scan and decode the sensors that are enabled for the currently-active mode.

Scanning Mode Configuration

  1. Configure all sensors for the system in mTouch_config.h as normal.
  2. Open mTouch_config_modes.h and set the value of MTOUCH_NUM_MODES to a value larger than 1.
    • (MTOUCH_NUM_MODES == 1) or (MTOUCH_NUM_MODES == 0) means 'modes' will not be implemented.
     #define MTOUCH_NUM_MODES                    2   // Two modes: Mode0 and Mode1
    
  3. For each mode:
    • Set MTOUCH_MODEx_NUM_SENSORS to the number of sensors that will be scanned in that mode.
       #define MTOUCH_MODE0_NUM_SENSORS      3   // Three sensors scanned in Mode0.
      
    • For each sensor in each mode:
      • Set MTOUCH_MODEx_SENSORx to the sensor index to be scanned.
         #define MTOUCH_MODE0_SENSOR0    4   // Sensor0 of Mode0 is MTOUCH_SENSOR4
        

Scanning Mode Configuration Example

 //
 // mTouch_config.h        ::
 //
 #define MTOUCH_NUMBER_SENSORS         4   // Total of four mTouch sensors

 #define MTOUCH_SENSOR0              AN4        
 #define MTOUCH_SENSOR1              AN2            
 #define MTOUCH_SENSOR2              AN7    
 #define MTOUCH_SENSOR3              AN8  

 //
 // mTouch_config_modes.h  ::
 //
 #define MTOUCH_NUM_MODES              3   // Three modes: Mode0, Mode1, Mode2

 #define MTOUCH_MODE0_NUM_SENSORS      3   // Mode0 has 3 sensors
 #define MTOUCH_MODE0_SENSOR0          0   // Sensor0 of Mode0 is MTOUCH_SENSOR0
 #define MTOUCH_MODE0_SENSOR1          1   // Sensor1 of Mode0 is MTOUCH_SENSOR1
 #define MTOUCH_MODE0_SENSOR2          2   // Sensor2 of Mode0 is MTOUCH_SENSOR2

 #define MTOUCH_MODE1_NUM_SENSORS      1   // Mode1 has 1 sensor
 #define MTOUCH_MODE1_SENSOR0          0   // Sensor0 of Mode1 is MTOUCH_SENSOR0

 #define MTOUCH_MODE2_NUM_SENSORS      2   // Mode2 has 2 sensors
 #define MTOUCH_MODE2_SENSOR0          2   // Sensor0 of Mode2 is MTOUCH_SENSOR2
 #define MTOUCH_MODE2_SENSOR1          3   // Sensor1 of Mode2 is MTOUCH_SENSOR3

Scanning Mode API

To change the current mode, use the mTouch_ChangeMode(i) macro.

To read the current mode, use mTouch_modeIndex. Do NOT change mTouch_modeIndex directly. Use the mTouch_ChangeMode macro!

When switching modes, the first scan result is ignored to allow the filters to properly reset themselves. The mTouch_state.skippedDecode bit will be set if this occured with the most recent decode and should be used to limit when mode changes can occur. An example is provided below.

An example usage of the API to switch between modes based on the state of different sensors:

 mTouch_DisableScanning();   // Temporarily disable scanning while this logic completes
 
 // Are all of the current sensors initialized? If not, stay in the current mode and keep scanning until 
 // they are. mTouch_state.areInitialized is a single-bit reserved for making temporary, local checks 
 // such as this.
 mTouch_state.areInitialized = 1;
 
 // Assuming four enabled sensors...
 if (mTouch_GetButtonState(0) == MTOUCH_INITIALIZING) {   mTouch_state.areInitialized = 0;    }
 if (mTouch_GetButtonState(1) == MTOUCH_INITIALIZING) {   mTouch_state.areInitialized = 0;    }
 if (mTouch_GetButtonState(2) == MTOUCH_INITIALIZING) {   mTouch_state.areInitialized = 0;    }
 if (mTouch_GetButtonState(3) == MTOUCH_INITIALIZING) {   mTouch_state.areInitialized = 0;    }
 // NOTE: You'll want additional checks here for all sensors being currently scanned.

 if (mTouch_state.areInitialized && !mTouch_state.skippedDecode)   // If we're not still initializing,
 {                                                                 // and we didn't skip the decode
                                                                   // due to just changing modes...
     if (mTouch_modeIndex == 0)                            // Application Specific: When in Mode0, let's
     {                                                     //    change to Mode1 based on MTOUCH_SENSOR1.
         if (mTouch_GetButtonState(1) == MTOUCH_PRESSED)
         {
             mTouch_ChangeMode(1); 
         }
     }
     else if (mTouch_modeIndex == 1)                       // Application Specific: When in Mode1, let's
     {                                                     //    sleep in-between decodes and change to
                                                           //    Mode0 based on MTOUCH_SENSOR0.

         #if defined(MCOMM_ENABLED) && defined(MCOMM_UART_HARDWARE_USED) 
                                           // If we are outputting data using a hardware UART...
             while(MCOMM_UART_TXIF == 0);  // Finish all communications before entering sleep
         #endif
         
         PIC_SWDTEN_ON();                  // If using a software-enabled WDT, enable it now.
         SLEEP();                          // Sleep, if you want to.
         NOP();                            // One more instruction is executed before sleeping.
         
         if (mTouch_GetButtonState(0) == MTOUCH_PRESSED)   // (Application Specific mode change logic)
         {
             mTouch_ChangeMode(0);
         }
         
         PIC_SWDTEN_OFF();                 // Sleep is over --> let's turn off the WDT.
     }
 }
 mTouch_EnableScanning();    // Re-enable scanning now that mode-changing logic is complete.