The mkII Astro Pi Flight Units carry a custom Sense HAT that includes a TCS34725 colour sensor, capable of measuring the amount of Red, Green and Blue (RGB) in the incident light, as well as providing a Clear light (brightness) reading.
To support interaction with this sensor, the Flight OS includes a custom-built sense_hat
Python library. The SenseHat
class provides a colour
(or color
) attribute which corresponds to a ColourSensor
object and provides access to the colour sensor.
The example below serves as an overview of how the colour sensor can be used, while the sections that follow provide additional details and explanations.
from sense_hat import SenseHat
from time import sleep
sense = SenseHat()
sense.color.gain = 4
sense.color.integration_cycles = 64
while True:
sleep(2 * sense.colour.integration_time)
red, green, blue, clear = sense.colour.colour # readings scaled to 0-256
print(f"R: {red}, G: {green}, B: {blue}, C: {clear}")
The colour
(or color
) property of the ColourSensor
object is a 4-tuple containing the measured values for Red, Green and Blue (RGB), along with a Clear light value, which is a measure of brightness. Individual colour and light readings can also be obtained through the red
, green
, blue
and clear
properties of the ColourSensor
object.
ColourSensor property |
Returned type | Explanation |
---|---|---|
red |
int | The amount of incident red light, scaled to 0-256 |
green |
int | The amount of incident green light, scaled to 0-256 |
blue |
int | The amount of incident blue light, scaled to 0-256 |
clear |
int | The amount of incident light (brightness), scaled to 0-256 |
colour |
tuple | A 4-tuple containing the RGBC (Red, Green, Blue and Clear) sensor readings, each scaled to 0-256 |
These are all read-only properties; they cannot be set.
Note that, in the current implementation, the four values accessed through the colour
property are retrieved through a single sensor reading. Obtaining these values through the red
, green
, blue
and clear
properties would require four separate readings.
In sensors, the term "gain" can be understood as being synonymous to sensitivity. A higher gain setting means the output values will be greater for the same input.
There are four possible gain values for the colour sensor: 1
, 4
, 16
and 60
, with the default value being 1
. You can get or set the sensor gain through the gain
property of the ColourSensor
object. An attempt to set the gain to a value that is not valid will result in a ValueError
exception being raised.
from sense_hat import SenseHAT
from time import sleep
sense = SenseHat()
sense.colour.gain = 1
sleep(1)
print(f"Gain: {sense.colour.gain}")
print(f"RGBC: {sense.colour.colour}")
sense.colour.gain = 16
sleep(1)
print(f"Gain: {sense.colour.gain}")
print(f"RGBC: {sense.colour.colour}")
Under the same lighting conditions, the RGBC values should be considerably higher when the gain setting is increased.
When there is very little ambient light and the RGBC values are low, it makes sense to use a higher gain setting. Conversely, when there is too much light and the RGBC values are maximal, the sensor is saturated and the gain should be set to lower values.
You can specify the number of integration cycles required to generate a new set of sensor readings. Each integration cycle is 2.4 milliseconds long, so the number of integration cycles determines the minimum amount of time required between consecutive readings.
You can set the number of integration cycles to any integer between 1
and 256
, through the integration_cycles
property of the ColourSensor
object. The default value is 1
. An attempt to set the number of integration cycles to a value that is not valid will result in a ValueError
or TypeError
exception being raised.
from sense_hat import SenseHAT
from time import sleep
sense = SenseHat()
sense.colour.integration_cycles = 100
print(f"Integration cycles: {sense.colour.integration_cycles}")
print(f"Minimum wait time between measurements: {sense.colour.integration_time} seconds")
The values of the colour
, red
, green
, blue
and clear
properties are integers between 0 and 256. However, these are not the actual raw values obtained from the sensor; they have been scaled down to this range for convenience.
The range of the raw values depends on the number of integration cycles:
integration_cycles |
maximum raw value (max_raw ) |
---|---|
1 - 64 | 1024 * integration_cycles |
> 64 | 65536 |
What this really means is that the accuracy of the sensor is affected by the number of integration cycles, i.e. the time required by the sensor to obtain a reading. A longer integration time will result in more reliable readings that fall into a wider range of values, being able to more accurately distinguish between similar lighting conditions.
The following properties of the ColourSensor
object provide direct access to the raw values measured by the sensor.
ColourSensor property |
Returned type | Explanation |
---|---|---|
red_raw |
int | The amount of incident red light, between 0 and max_raw |
green_raw |
int | The amount of incident green light, between 0 and max_raw |
blue_raw |
int | The amount of incident blue light, between 0 and max_raw |
clear_raw |
int | The amount of incident light (brightness), between 0 and max_raw |
colour_raw |
tuple | A 4-tuple containing the RGBC (Red, Green, Blue and Clear) raw sensor readings, each between 0 and max_raw |
Here is an example comparing raw values to the corresponding scaled ones, for a given number of integration cycles.
from sense_hat import SenseHAT
from time import sleep
sense = SenseHat()
sense.colour.integration_cycles = 64
print(f"Minimum time between readings: {sense.colour.integration_time} seconds")
print(f"Maximum raw sensor reading: {sense.colour.max_raw}")
sleep(sense.colour.integration_time + 0.1) # try omitting this
print(f"Current raw sensor readings: {sense.colour.colour_raw}")
print(f"Scaled values: {sense.colour.colour}")