Archive for February, 2016

Using Motion Detection To Wake Up Embedded System – A Practical Example

February 2, 2016

Put the embedded system into sleep while not in use is a must have for any battery powered applications.The tricky part is how to wake up the system if it has no peripherals, such as switch, to interact with. Using motion detection to wake up the system is a natural choice.
The example demonstrated here uses a digital accelerometer via I2C interface for motion detection. The accelerometer is configured to generate interrupts after motion is detected. The motion interrupt then wakes up the system from the deep sleep mode.
The following hardware, software and system configurations are used in the project. The custom KL03Z board is designed by Embedded Masters, other parts not used in the demo are not mentioned here. EFM32 Giant Gecko board and Simplicity Studio is optional and only used for Power/Energy Profiler.

Hardware Description
Freescale Kinetis Custom Board KL03Z MCU (Cortex-M0+ 48MHz, 32KB flash, 2 KB SRAM)
MMA8652 3-Axis 12-bit Digital Accelerometer
RGB LEDs
Silicon Labs EFM32 Giant Gecko (STK3700) Run Power/Energy Profiler
Segger JLink Debugger Program and/or Debug Kinetics MCU based hardware
Software Description
Freescale KDS 3.0 Freescale Kinetis MCU Eclipse IDE
Freescale KSDK 1.3 Kinetis SDK
Silicon Labs Simplicity Studio v3 Run Power/Energy Profiler
System Configuration Description
LPO Internal low power oscillator(1000Hz) works in very low power/leakage modes
LPTMR Low power timer with prescaler 3 to accommodate timer period up to 17.6 minutes
Clocking by LPO
I2C Baud rate 100Hz
MMA8652 Configured in Free-fall/Motion detection mode
Enable motion detection interrupt 2
Route motion detection interrupt 2 pin to PTB0 per KL03Z datasheet
PMC (Power Management Controller) VLPR (Very Low Power Run) mode while the system is up
VLPS (Very Low Power Stop) mode while in deep sleep
LLWU (Low Leakage Wakeup Unit) Route LLWU wake-up source pin P4 to MMA interrupt 2 pin
RGB LEDs Active-low

The key is to configure MMA8652 motion detection interrupt 2 and LLWU P4 to share the same pin such that the motion detection becomes the wake-up source. The following picture shows the KL03Z data sheet about how pins are assigned.

Pin Assignment

This is the application code blinks red and green LEDs 5 times before entering the sleep mode, and blinks blue LED once after waking up. Wakeup source is a 5 second timer and/or motion detection.

Application Code
/*!
 *  @brief Enter deep sleep mode, and use timer/motion detection to wakeup
 */
void enter_sleep()
{
    /*  Step 0 - Init MMA */
    mma8652_init( &i2c_devices, 0 );
    /* Step 1 - enable LPO timer to make it another wake up source (5s) */
    timer_set_period( 5*1000, true );

    /* Step 2 - Enable motion detection interrupt */
    enable_motion_interrupt( true );

    /* Step 3 - Switch to deep sleep mode VLPS */
    /* Using motion detection/timer as the wakeup sources */
    pmc_sleep( true, true );

    /* Step 4 - Exiting sleep mode */
    /* timer is reenabled by pmc_sleep call */
    /* disable motion detection interrupt */
    enable_motion_interrupt( false );
}

/*!
* @brief Main routine
*/
void main (void)
{
    hardware_init();
    /* initialize peripherals */
    peripheral_init();

    while(1)
    {
        for(int i=0; i<5; i++ )
        {
            LED1_ON;
            LED2_ON;
            delay100ms(1);
            LED2_OFF;
            delay100ms(1);
            LED1_OFF;
            delay100ms(1);
        }

        enter_sleep();
        LED3_ON;
        delay100ms(2);
        LED3_OFF;
        delay100ms(5);
    }
}

The following screenshot is taken from Simplicity Studio/Energy Profiler running session. It clearly indicates the system behavior and power consumption.
Power Profiler

This video clip shows the complete running, including power profiling process.

After much efforts, include working with Freescale FAE and applying some tricks listed in chip’s errata, the system consumes about 10uA while in sleep in VLPS mode.