How to use Ambient Light Sensors in your Linux projects

Modern ambient light sensors are categorised as IIO (Industrial Input Output) devices in Linux along with several other sensors and actuators. This article is targeted towards application developers and does not dwell too much into hardware. Below are few links on IIO subsystem:

APDS9306 Ambient Light Sensor

Datasheet can be found here.

Driver for this light sensor is present in Linux kernel version 6.10 onward and a backport of the driver for older kernels can be found here.

Schematic and PCB design can be found here.

Assuming your Linux board is set up with this device, you should see the following sysfs entries:

Verify your device by checking the name:

root@stm32mp1:~# cat /sys/bus/iio/devices/iio:device*/name
apds9306
48003000.adc:adc@0
48003000.adc:adc@100

root@stm32mp1:~# cat /sys/bus/iio/devices/iio:device0/name
apds9306

We found our device, now we list all the important files:

root@stm32mp1:/sys/bus/iio/devices/iio:device0# tree -L 1
.
|-- events                         #(interrupt related)
|-- in_illuminance_raw             #(raw sensor value)
|-- in_illuminance_scale           #(current scale)
|-- in_illuminance_scale_available #(all available scales)
|-- in_intensity_clear_raw         #(unfiltered raw value)
|-- integration_time               #(intg time per sample)
|-- integration_time_available     #(available intg time)
|-- name                           #(driver name)
|-- sampling_frequency             #(in case of continuous reads, or interrupt driven implementation, after how much time, sensor should generate outputs)
|-- sampling_frequency_available   #(available sampling freq)

We can obtain the values in Lux using this formula:

Lux = (raw_value + offset) * scale

offset is a fixed value which can be derived after manual testing such as if your sensor is under a darkened glass, etc. In our case, we will use zero.

root@stm32mp1:/sys/bus/iio/devices/iio:device0# scale=`cat in_illuminance_scale`

root@stm32mp1:/sys/bus/iio/devices/iio:device0# val=`cat in_illuminance_raw`

root@stm32mp1:/sys/bus/iio/devices/iio:device0# awk "BEGIN{printf (\"%f\n\", ($val + 0) * $scale)}"

388.039835

How to use Ambient Light Sensor interrupts:

A blog on how to configure and use APDS9306 IIO event interface (interrupts) can be found here.

Leave a Reply

Your email address will not be published. Required fields are marked *

9 + 1 =