Enables or disables the imp WiFi sub-system’s power-save mode
Device
Name | Type | Description |
---|---|---|
state | Bool |
Whether to enable (true ) or disable (false ) power-save mode
|
Nothing
Power-save mode is disabled by default. This means the WiFi radio receiver is enabled constantly. This results in the lowest latency for data transfers, but a high power drain - the actual power used depends on the imp variant, but can vary from 40 to 80mA at 3.3V.
Enabling power-save mode drops this down to <5mA when the radio is idle (ie. between transactions with the server), by using the IEEE PS mode feature. The STA (WiFi device) tells the AP (access point) that is is going into power save mode, and the AP will queue downstream traffic for the STA. The STA then only wakes to listen to AP beacons, which include a TIM (traffic indication map) which indicate if the AP is holding traffic for the STA. At other times, the wireless circuitry is powered down, resulting in the large power savings.
If the TIM indicates traffic is queued for the STA, the STA will send a PS Poll message to the AP, which causes it to send the queued traffic to the STA. Note that upstream traffic — STA to AP — is not affected by this, and the STA will transmit upstream packets immediately, as the AP is always listening.
Latency is impacted by use of IEEE PS mode. Typically the highest latency seen is a little over the DTIM (beacon interval), or around 100ms, but on congested networks — or with some APs that de-prioritize queued traffic — this can be several hundred milliseconds in addition to any transit latency seen in non-powersave mode.
Power-save mode is disabled every time Squirrel restarts or reloads, such as across a deep sleep and subsequent warm start. For this reason, you may wish to ensure that your imp.setpowersave(true)
call appears as early as possible in your device code.
The imp.getpowersave() method can be used to determine whether power-save mode is currently in effect.
If you are using the imp004m, you should note that calling imp.setpowersave() has no effect on this module unless you have connected a 32KHz crystal to the imp and have notified impOS that the crystal is present. The OS is notified by applying a special setting in the NVRAM. For further details, please contact support.
The impC001 does not currently implement imp.setpowersave().
The following snippet enables power-save mode on the imp and logs the fact.
// Call this early in your code to ensure powersave mode | |
// is re-enabled as soon as possible after Squirrel restarts | |
imp.setpowersave(true); | |
// Check power save status | |
server.log("This imp " + (imp.getpowersave() ? "is set to" : "has disabled") + " powersave mode"); |
The following simple application measures the average duration of a unit of data sent from the device to the agent and then back again, first in full-power WiFi mode and then in power-save mode. Each measurement is an average over 100 runs, but should not be taken as a precise measure of transmission time because of the many other factors involved. But it does give an indication of how power save mode may broadly affect your application.
// Just respond to 'ping' messages by immmediately | |
// sending back a 'pong' message to the device | |
device.on("ping", function(dummy) { | |
device.send("pong", true); | |
}); |
// Set the number of messages from which the average rount-trip | |
// time will be taken at the end of every run (float for better | |
// accuracy when we come to calculate the average duration) | |
const TRIP_COUNT = 100.0; | |
local runCount = 0; | |
local total = 0; | |
local pingTime = 0; | |
// Send a 'ping' message to the server | |
function ping() { | |
// Record the time of the ping transmission | |
pingTime = hardware.millis(); | |
agent.send("ping", true); | |
} | |
// Handle the incoming 'pong' reply from the server | |
agent.on("pong", function(dummy) { | |
// How long did the message round trip take? | |
local roundTrip = hardware.millis() - pingTime; | |
// Add it to the total so we can average later | |
total = total + roundTrip; | |
runCount++; | |
if (runCount == TRIP_COUNT) { | |
// We've done the first batch of runs in Standard Mode | |
// Report the data and switch to power save | |
server.log(format("Standard WiFi Mode Avg. Round Trip Time: %.2fms", total / TRIP_COUNT)); | |
server.log("Starting Run #2 - Power-save WiFi Mode..."); | |
imp.setpowersave(true); | |
total = 0; | |
} else if (runCount >= TRIP_COUNT * 2) { | |
// End of final run, so report the power save time | |
server.log(format("Power-save WiFi Mode Avg. Round Trip Time: %.2fms", total / TRIP_COUNT)); | |
return; | |
} | |
// Send the next message | |
ping(); | |
}); | |
// Start of runtime | |
server.log("Starting Run #1 - Standard WiFi Mode..."); | |
ping(); |