SetOption36 - RTurala/Sonoff-Tasmota GitHub Wiki

SetOption36 - CPU Main loop target / CPU Power Management

The term CPU is used loosely here for the sake of making it easier to understand - When the term CPU is used it is actually referring to the ESP8266 SoC Micro Controller.

With the introduction of many new drivers, sensors and other functions as part of the Sonoff-Tasmota firmware, it has become more important to pay specific attention to the amount of microcontroller clock cycles shared with the underlying SDK/Arduino ESP8266 Core.

The main application loop of the Sonoff-Tasmota firmware needs to visit each of the driver callbacks within the main loop to make sure all the required drivers and sensors receive the necessary processing time whilst ensuring that the main loop does not overwhelm the need for processing time by the SDK / Arduino ESP8266 core.

The highest priority drivers/sensors need to be called once per 50ms to operate as designed but most of the normal run of the mill drivers and sensors do not necessarily require this amount of intense polling. The 50-millisecond mark would normally be considered to be an absolute minimum duty cycle for the main processing loop on ESP8266 boards whilst most Sonoff device derivatives will function perfectly well way above this default setting.

To make this manageable from device to device a new setting has been introduced enabling the setting of the main loop target to a specific value in milliseconds.

For default operation, this will be set to 50 milliseconds as there are generally no drivers or sensors that need to be polled at a rate higher than this.

To allow for power usage flexibility this value may also be increased to a value of up to 255 milliseconds which is very useful to reduce power and processing demand on non-time critical devices such as switches (which is what most of Sonoff-Tasmota is used for.)

The purpose of this setting is to allow you as a user to set the speed at which driver and sensors will be serviced and as a result also the amount of time given to the SDK / Arduino ESP8266 core to handle its background tasks (which are not under direct control of the Sonoff-Tasmota firmware.)

Example Use Case

Let's assume the default value of 50 for SetOption36 and that a simple device such as a Sonoff Basic R1 or R2 is being used.

In this case, the main firmware loop will iterate through all the drivers and sensors once per 50 milliseconds.

Current tests suggest that a simple device such as a Sonoff Basic requires only about 9.5 milliseconds to complete one iteration of servicing all the drivers and sensors enabled in the standard sonoff.bin firmware.

The time management functionality offered by SetOption36 will compute this time requirement automatically and allow the SDK / Arduino ESP8266 Core to service background tasks such as maintaining WiFi connectivity for the remainder of the time not spent in the main firmware loop - i.e. in the case of SetOption36 50 this would mean 50 milliseconds - ~9.5 milliseconds = ~40.5 milliseconds spent outside of the main firmware loop servicing SDK / ESP8266 Core functions which automatically consume fewer clock cycles when there is nothing intense for the SDK / ESP8266 Core to maintain or perform.

Sleep was previously the only option for Tasmota powered devices wishing to take advantage of power saving but it does have the disadvantage that the sleep would be a constant setting insofar that the entire firmware codebase would run at a pre-determined speed causing some drivers to run slower than expected and decreasing the speed at which services such as the WebUI is rendered (This varies between the various underlying cores depending on which version is used.)

Using SetOption36 instead of sleep has the advantage that CPU time will be given to any particular driver or process (let's say the WebUI) on demand as and when needed whilst spending most of its time waiting for the next main loop iteration to occur.

During this time of waiting the ESP8266's power demand can go from 80mA all the way down to 20mA which yields great benefits for power saving vs. firmware responsiveness compared to the traditional sleep setting.

Monitoring Performance

Given all the above it is an obvious conclusion that in order to manage something you would need to be able to measure it. For this reason two new variables have been added to the telemetry data namely LoopSet and LoadAvg and are represented in the telemetry JSON as follows:

MQT: tele/sound1/STATE = {"Time":"2018-11-26T17:41:27","Uptime":"0T05:05:17","Vcc":3.504,"LoopSet":50,"LoadAvg":19,"POWER":"OFF","Wifi":{"AP":1,"SSId":"Wireless","BSSId":"DE:AD:00:00:BE:EF","Channel":3,"RSSI":100}}

The two values indicated for LoopSet and LoadAvg have the following relation:

Variable Value Description
LoopSet 50 Current value of SetOption36
LoadAvg 19 Reported % time of LoopSet spent doing Sonoff-Tasmota main loop processing

In this example, 19% of 50 milliseconds would be 9.5 milliseconds (19/100*50), so we can see that there is sufficient headroom for the SDK / ESP8266 Arduino Core to do its background work.

It is very important to remember that the sleep command will impact on this value negatively for all of the current Arduino Cores so in order not to distort the measurements, it is recommended to use a sleep value of 0 when SetOption36 is being used to perform CPU/Power Load Management.

On some devices which have many sensors connected you may observe the LoadAvg value exceeding 100 - This means that you have not set the value of SetOption36 high enough to accommodate all the sensors and drivers which need to be serviced.

In the latter case, you have two options - either increase the value of SetOption36 to a higher one to maintain a load average well below 100 or use multiple devices to spread the load across separate Sonoff-Tasmota powered devices/boards.

For the most part, all Sonoff based products should perform well balanced with the default setting of 50 for SetOption36.

How to use SetOption36

From serial console, or webui console enter command

SetOption36 xx

Where xx is the number of milliseconds you wish to target your main processing loop at ranging from 0 through to 255.

Should you set a SetOption36 value that is too low you will observe output on telemetry for the value of LoadAvg to be in excess of 100 - This is not ideal and should be avoided as it starves the Arduino Core / SDK of the needed processing time to take care of background tasks such as WiFi management.

For optimal operation of the Tasmota firmware, it is recommended to keep your device running at a LoadAvg value of 75 or lower. If your device does not have any time critical drivers/sensors connected you are encouraged to increase the SetOption36 value to a higher value to gain from the power saving benefits thereof.