# Numerical explanation of the CM7 automatic backlight settings



## byrong (Oct 13, 2011)

Note: I first posted this on XDA on 3/22/2011. It is my original work.

_While the CM7 auto-backlight settings should function the same across supported devices, I do not know how the light sensor itself may differ. As such, some of what I write below *may *be specific to the Droid Incredible while the general concepts should be applicable to other devices._

_Thanks to userjf for helping me better understand the effect of kernel choice on light sensor readings. 
_

The CM7 automatic backlight settings can seem a bit intimidating at first: there are a lot of options for the user to tweak. Don't worry though: there is some very basic math being used and once you understand it, optimizing your settings becomes much easier.

The most important thing to realize right away is that the light sensor can only detect a fixed number of raw values. If you are using the stock kernel in nightly #26 (or later), then you should be able to read 10 values: 

```
10, 160, 225, 320, 640, 1280, 2600, 5800, 8000, 10240
```
If you are using an older nightly, or a custom kernel that does not yet incorporate these extra levels, you will only be able to read 7 values: 

```
160, 225, 320, 640, 1280, 2600, 10240
```
If you aren't sure what you have, go to the "edit other levels" portion of the CM7 backlight settings and then cover your light sensor. When the raw reading updates, you should see either 10 or 160, telling you which of the above two lists applies to you.

Since there are only 10 possible raw readings, setting up more than 10 custom levels is pointless, _unless you also enable *filtering*_. Filtering uses an average of raw readings to create new filtered readings, increasing the number of possible values.

The number of new values will be dependent on your window length and sample interval. If you select a window length of 30 seconds with a sample interval of 5 seconds, each filtered reading will now be based on the average of 6 raw readings (30/5). A quick example of this 30/5 filter involves walking from a room that has a raw reading of 640 to one that has a raw reading of 320:










Notice that the shift in filtered values is much more gradual than the shift in raw values. Given enough time, however, the filtered value will always return to a raw value.

*If the filtered value always anchors back to a raw value, why enable filtering?*

*There are two primary benefits offered by filtering:*
1. It can allow you to set up smoother brightness transitions (assuming you also increase the number of custom levels)
2. It can decrease the likelihood of screen flicker in mixed lighting

Point #1 should be relatively self-explanatory: since we now have interpolated light values, we can create intermediate screen brightness levels. Each of those values between 640 and 320 can trigger subtle changes in screen brightness, allowing for a smoother transition between them.

As for #2, you may find yourself in mixed lighting conditions that straddle two raw brightness levels. Without filtering, these raw levels may cause your screen to repeatedly shift back and forth between two brightness settings. I've found this can easily happen with artificial lighting as it is more directional than natural lighting. Sitting in your office, for example, you may find that simply shifting the angle at which you hold the phone changes the brightness reading.

With a filter in place, however, the effects of fluctuating raw values can be mitigated. This is true even if you don't create additional brightness levels. For example, using the stock values, let's look at what would happen if your sensor was getting raw readings back and forth between 640 and 320:










Notice that without filtering, the screen brightness jumps back and forth between 70 and 55, which can be very distracting. The filter, on the other hand, maintains a single value for the screen brightness, even under these fluctuating lighting conditions.

Of course, there may be times in which you want the screen to respond quickly to changes rather than slowly ramping. Moving from a dark building out in to broad daylight, for example, you don't want to watch your screen slowly brighten over the course of 30 seconds: those are 30 seconds in which your phone may be unreadable. This is where the *reset threshold* comes in handy. If a raw reading differs from your current average by this amount, the filtered value is immediately reset to the raw value. Finding the right value for your reset threshold allows you the best of both worlds: a screen that gradually changes based on subtle light changes, but responds rapidly to extreme changes.

"Allow light decrease" is a very simple option. If this is checked, your screen brightness will increase *and decrease* according to your custom levels. If it is unchecked, your screen will brighten as the light sensor reads higher values, but will never darken, even if the sensor detects that you have moved to a very dark area. I'm not quire sure why anyone would want to uncheck this, but maybe I'm missing something.

Finally, the hysteresis option is a bit of a mystery to me. That is, I understand the concept of hysteresis ("a retardation of the effect when the forces acting upon a body are changed"), but I don't see any difference in practice. In my testing, it doesn't matter whether I set hysteresis to 0% or 90% - my brightness values and resulting screen values behave exactly the same. If you are able to observe a quantifiable difference, please let me know your findings.

Putting this all together should hopefully give you a better idea of how to tweak your settings. If you want a screen that responds very rapidly to changes in ambient lighting, possibly at the risk of flickering, decrease your filter window (or disable the filter completely) and increase your sample interval. If you want a screen that never flickers, possibly at the risk of slow responsiveness, increase your window.

Note that any settings you choose can easily be modeled with some very basic math. Here are some example configurations and how they would play out:

Filter A: 10 second window, 2 second interval
Filter B: 20 second window, 2 second interval
Filter C: 30 second window, 2 second interval
Filter D: Same as Filter C, but includes a reset threshold of 2000

This is a pretty ugly graph, but hopefully it conveys the concept. Filter D is represented as a dotted line because it overlaps Filter C so much.










Note how the inclusion of a reset threshold on Filter D allows for immediate responsiveness under extreme light changes while still preserving the gradual shifts at smaller changes.

It's also worth noting a known issue at the time of this writing. That is, if you are using the screen on/off animations in CM7, any screen brightness changes will look more "jumpy." That is, if you change your screen from 100 to 150, either manually or automatically, the change will look like a switch was flipped. If you disable the animations, however, that same change from 100 to 150 will be smoother, with the system automatically scaling through the intermediate brightness levels. Even so, the change will be fairly quick, so it does not replace filtering: it's just a nice extra if you really prefer smooth brightness changes.


----------

