Device-os: Proposed: Wi-Fi Eco mode on Photon/P1

Created on 24 Mar 2016  路  2Comments  路  Source: particle-iot/device-os

The following was taken from a private repo where initial development on Photon took place


Doing some testing with the WICED SDK examples, I measured the current consumption in an example that uses the WICED powersave feature. We will be calling this mode Wi-Fi Eco mode in the Particle API.

Here's an app note on WICED's powersave feature.

It pings a server every second for 30 seconds in Eco mode. The current was roughly 18mA between TX/RX bursts, which is much better than constantly being 80-100mA (depending on input voltage). You can enable it with and without throughput (i.e. a delay in 10's of milliseconds that puts the Wi-Fi module back in Eco mode after the TX/RX of a packet.). If throughput is enabled, the RX latency is low. If not enabled, it can be <100ms to 400ms, on avg about 225ms. The throughput sleep delay must be set in increments of 10 milliseconds and not equal to zero. Perhaps rounding up to the nearest 10ms would be appropriate.

I've found that wiced_network_suspend(); and wiced_network_resume(); need not be called between pings to keep the resting current at 18mA.

The WICED example is "ping_powersave" and the meat of it is:

/* Enable Wi-Fi powersave */
#ifdef USE_POWERSAVE_POLL
    //wiced_wifi_enable_powersave();
#else
    const uint8_t return_to_sleep_delay = 10;
    wiced_wifi_enable_powersave_with_throughput( return_to_sleep_delay );
#endif

    while (1)
    {
        /* Send an ICMP ping to the gateway */
        send_ping( );

        /* Suspend network timers */
        wiced_network_suspend();

        /* Sleep for a while */
        wiced_rtos_delay_milliseconds( WIFI_SLEEP_TIME );

        /* Resume network timers */
        wiced_network_resume();
    }

and the WICED API is:

/** Enables powersave mode without regard for throughput reduction
 *
 *  This function enables (legacy) 802.11 PS-Poll mode and should be used
 *  to achieve the lowest power consumption possible when the Wi-Fi device
 *  is primarily passively listening to the network
 *
 * @return @ref wwd_result_t
 */
extern wwd_result_t wwd_wifi_enable_powersave( void );

/* Enables powersave mode while attempting to maximize throughput
 *
 * Network traffic is typically bursty. Reception of a packet often means that another
 * packet will be received shortly afterwards (and vice versa for transmit).
 *
 * In high throughput powersave mode, rather then entering powersave mode immediately
 * after receiving or sending a packet, the WLAN chip waits for a timeout period before
 * returning to sleep.
 *
 * @return  WWD_SUCCESS : if power save mode was successfully enabled
 *          Error code   : if power save mode was not successfully enabled
 *
 * @param[in] return_to_sleep_delay : The variable to set return to sleep delay.*
 *
 * return to sleep delay must be set to a multiple of 10 and not equal to zero.
 */
extern wwd_result_t wwd_wifi_enable_powersave_with_throughput( uint16_t return_to_sleep_delay );


/** Disables 802.11 power save mode
 *
 * @return  WWD_SUCCESS : if power save mode was successfully disabled
 *          Error code   : if power save mode was not successfully disabled
 */
extern wwd_result_t wwd_wifi_disable_powersave( void );

Proposed API:

See issue https://github.com/spark/firmware/issues/1150 for the API.

Some conversation


  • what would be the criteria for the user in deciding whether or not to enable WiFi Eco? Performance/power tradeoff?
  • do we need the WICED Poll (legacy) powersave, or only the powersave with throughput?
  • if latency is high on the first packet received, will this make polling the cloud connection slower? Just mentioning since this might have implications for the user loop throughput. (user loop and system are on separate threads)

  • the criteria would be, save power for a latency tradeoff. If you need high throughput like loading some JSON data you might not want to have Eco mode on, but you could certainly turn it on after you are done grabbing all of that data :) And if you are just Particle.publish()'ing every second, you should probably have Eco mode on. If you are doing some realtime UDP app, you should probably have Eco mode off.
  • All of the API calls have the option of returning error codes as well, in case the WICED SDK fails to set/get various calls.
  • I would say we should implement both Eco mode features, legacy and with throughput. Legacy has a lower power consumption profile. With a minimum of 10ms of throughput does not. AFAIK with throughput leaves the WiFi in high power consumption mode for a minimum of 10ms (or whatever you've set the delay to). This is basically on users to characterize their traffic and set the Eco mode appropriately.
  • yes a higher latency will affect how responsive certain aspects of the Particle Cloud are. Particle.variable()/function() would probably feel slower. I think this would barely affect the Particle.publish() though, maybe more so with Particle.subscribe(). A user that's very energy conscious may want to run in SYSTEM_MODE(MANUAL) anyway, and control the Cloud connection to minimize power consumed between Publishing events though. So I believe there are some really good ways we can recommend using all of these features to maximize the energy consumed.

feature confirmed

Most helpful comment

Double bump this!

I currently lower the CPU speed to 30MHz which saves ~19mA using the following:

    // Run processor at 30MHz (saves ~19mA)
    RCC_PCLK1Config(RCC_HCLK_Div1);
    RCC_PCLK2Config(RCC_HCLK_Div1);
    RCC_HCLKConfig(RCC_SYSCLK_Div4);
    SystemCoreClockUpdate();
    SysTick_Configuration();
    FLASH->ACR &= ~FLASH_ACR_PRFTEN;

Turn off the breathing RGB LED with the following to save another ~2mA:

    // Control RGB LED and turn it off (saves ~2mA)
    RGB.control(true);
    RGB.color(0, 0, 0);

And when possible I do the following instead of a 1 second delay in loop(), saving yet another ~10mA:

    // Put microcontroller to sleep for a second (WiFi stays active, saves ~10mA)
    pinMode(A6, INPUT_PULLDOWN);
    System.sleep(A6, RISING, 1, SLEEP_NETWORK_STANDBY); 

These save about 30mA in total (down to about 50mA) while still having full functionality including cloud API functions, flashing, webhooks, etc. The last one will add some lag at times, but it's far better than using System.sleep() where the WiFi shuts down (and takes way too long to reconnect at times). I typically need about a second response time for my projects. The WiFi most of the time takes 5-10 seconds to connect, and other times doesn't connect at all, neither of these are acceptable in my case.

Adding a WiFi eco mode in combination with the savings shown above could result in a fully functional yet very low powered project. The current System.sleep() with wake-up triggers simply doesn't work well (like only one pin trigger). Also, how long the Photon can take to connect to WiFi from sleep and how it can also just hang and never connect makes shutting off the WiFi module unacceptable (at least for me). WiFi eco mode is exactly what I need!

All 2 comments

I'd love to bump attention on this suggested interface. I tested some of these powersave functions, and saw an improvement on power consumption to 19mA from ~80mA (a 400% improvement?!). I would absolutely love to start using all of these functions on all of my projects, and it'd be awesome to be able to recommend these behaviors to customers as well.

Woo!

Double bump this!

I currently lower the CPU speed to 30MHz which saves ~19mA using the following:

    // Run processor at 30MHz (saves ~19mA)
    RCC_PCLK1Config(RCC_HCLK_Div1);
    RCC_PCLK2Config(RCC_HCLK_Div1);
    RCC_HCLKConfig(RCC_SYSCLK_Div4);
    SystemCoreClockUpdate();
    SysTick_Configuration();
    FLASH->ACR &= ~FLASH_ACR_PRFTEN;

Turn off the breathing RGB LED with the following to save another ~2mA:

    // Control RGB LED and turn it off (saves ~2mA)
    RGB.control(true);
    RGB.color(0, 0, 0);

And when possible I do the following instead of a 1 second delay in loop(), saving yet another ~10mA:

    // Put microcontroller to sleep for a second (WiFi stays active, saves ~10mA)
    pinMode(A6, INPUT_PULLDOWN);
    System.sleep(A6, RISING, 1, SLEEP_NETWORK_STANDBY); 

These save about 30mA in total (down to about 50mA) while still having full functionality including cloud API functions, flashing, webhooks, etc. The last one will add some lag at times, but it's far better than using System.sleep() where the WiFi shuts down (and takes way too long to reconnect at times). I typically need about a second response time for my projects. The WiFi most of the time takes 5-10 seconds to connect, and other times doesn't connect at all, neither of these are acceptable in my case.

Adding a WiFi eco mode in combination with the savings shown above could result in a fully functional yet very low powered project. The current System.sleep() with wake-up triggers simply doesn't work well (like only one pin trigger). Also, how long the Photon can take to connect to WiFi from sleep and how it can also just hang and never connect makes shutting off the WiFi module unacceptable (at least for me). WiFi eco mode is exactly what I need!

Was this page helpful?
0 / 5 - 0 ratings