- day mode brightness
- night mode brightness
- level control to switch between day and night
It would be better if this could be done automatically. Maxim Integrated has an application note concerning display brightness adjustment according to ambient light levels. They make reference to a logarithmic conversion proposed by Microsoft Windows.
Brightness mapping ambient-light levels to optimal screen brightness. f(x) = Screen Brightness (%)
In the first implementation, the brightness adjustment involved three settings:
The APDS-9960 outputs integer light levels, which compare more or less to lux. The smallest non-dark light level that can be measured is 1 lux. As a result from the formula above, the minimum screen brightness (which corresponds to 1 lux) is 27%. All lower screen brightness levels would be unused because the APDS-9960 can measure light levels smaller than 1 lux.
The MAX7219 display panel only has 16 brightness levels. It would be a shame not to use them all. So a different brightness mapping will be used.
In the clock, the display brightness levels 0 to 15 are linearly mapped to brightness ratios of 27% to 100%. Then the inverse formula of the one above has been used.
g(x) = light level in lux, x=brightness level [0 15]
Another problem with this formula is that it uses a computationally intensive logarithmic function. Instead of calculating a brightness setting for a specific light level, a lookup table will be used defining what light level corresponds to a certain brightness setting. There are only 16 brightness levels, so the lookup table doesn't take up much memory space.
Ambient light sensor selection
The clock should monitor the intensity of the ambient light in order to adjust the intensity of the LED array. Especially in the dark it can be quite annoying when the LED array is too bright. Many choices for sensing the ambient light are available.
Important factors that determine the choice are cost and sensitivity in the human eye light spectrum (390 to 700nm).
IC sensor
- More expensive
- More features (proximity sensing)
- Parts
- TSL2591
- Adafruit TSL2591 High Dynamic Range Digital Light Sensor
- Works fine with the hardwired I²C of the STM32 Blue Pill
- Gain x25 with 600ms integration time matches our application (max. 1254lux) perfectly. When the light level is higher, -1 is returned as lux value.
- The Adafruit libraries are using a blocking read function, which means the read function hangs as long as the integration time (up to 600ms) is not finished.
VEML7700- Adafruit 4162
- Reads Lux directly, should provide more stable and more reproducible readings
- Adafruit VEML7700 library: sensor detected, but readout remains zero on the STM32. 25KB for the example application!
- Mikroelektronika Ambient 6 Click : libraries in custom mpkg-format, not usable for other platforms
- DFRobot Gravity: I2C VEML7700 Ambient Light Sensor (0~120Klx). 20KB for the sample application. Output is constantly 0.12lux using the STM32.
- The problem with the STM32 Arduino tool chain is that it doesn't send a repeated start. It sends a stop instead, followed by a start. This may be ok for most of the I²C devices, but the VEML7700 doesn't allow it.
- We might want to try a SoftWire I²C library on the STM32 as a workaround. I patched the SoftWire library to get the repeated start working. You can find the library here.
- Unfortunately, another problem arose : the SoftWire I²C library doesn't work simultaneously with the DCF-library. The DCF-library relies on the 1ms timer interrupt. The SoftWire library prevents it from working correctly in some way.
APDS-9960- RGB, ambient light, proximity & gesture
- Range of the gesture sensor is limited to about 10-20cm. In this application this is useless. When your hand is that close (in the dark), you might as well push any random button to stop an ongoing alarm.
- AliExpress : $1.51
- Breakout board at Sparkfun & Adafruit
- Arduino libraries:
- Sparkfun : gesture recognition didn't work at all
- Adafruit : gesture recognition can't be combined with ambient light sensing. If you try it anyway, after some time, no ambient light values will be returned any more. It's like the internal state machine of the sensor gets stuck somewhere. No effort has been put into debugging this. Eventually, the library still gets stuck as no luminance reading ever comes available inside the sensor.
APDS-9930- ambient light & proximity
- AliExpress : $0.90
MAX44009- ambient light (22bit dynamic range)
- AliExpress : $1.75
Dyna Image Corp AP3216- ambient light & proximity
- AliExpress : $0.95
- 5 to 15cm
- little info available
TI OPT3001- ambient light (23bit dynamic range)
- TSL2591
LDR
Contains the poisonous CdS. Not RoHS compliant.
Photo diode
- More expensive than photo transistor.
- Requires signal conditioning to make the sensor level readable to an MCU.
- Most diodes have the highest sensitivity outside of human eye spectrum.
Photo transistor
- Cheap
- Available in variants that have sensitivity matching the human eye
- Parts
- TEMT6000 : AliExpress module
- $0.86/pce with header & mounting hole
- overpriced compared to AP3216 modules which offer more functionality for about the same price
- TEPT4400
- T-1 through hole package (E: long pin, C: short pin)
- €0.59/pce Digikey
- small opening angle : could be pointed by bending the leads in desired direction of the light
- Spectral sensitivity resembles that of human eye
- Circuitry: Optimal series resistance value gives full scale voltage for 1254 lux: taking 8K2 works pretty well.
- Circuitry: photodarlington with "dark current sink" resistor.
- Problem: too much noise on the ADC-counts, up to 13 counts have been seen. This would result in a brightness setting of 0 or 7 (where 16 is maximum). A moving average filter can filter some garbage out, but this is clearly too much.
- TEMT6000 : AliExpress module
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.