My first Bluetooth project for the Arduino Nano 33 Sense involved taking temperature, humidity and barometric pressure readings from the Nano 33 BLE Sense and making that data available to Bluetooth Low Energy clients. Bluetooth and all the sensors are built in, so it was really just an exercise in writing software.
In the process, I learned quite a bit about Bluetooth Low Energy (BLE) and the Generic Attribute (GATT) characteristics that are an integral part of it. The next logical step for me was to explore the Nano's APDS-9960 gesture sensor that also reads colors and ambient light.
Watts and Meters and Counts, Oh My!The real trick in this sketch is getting the ambient light readings into the proper units for BLE GATT characteristics. GATT is very rigid in the units used. You must give it the value it expects or the readings will be meaningless. The GATT characteristic for irradiance is Watts per square meter.
This project focuses on finding out how to read ambient light as a value suitable for the BLE irradiance characteristic. For a more in depth introduction to BLE, GATT, and terms like characteristic, see my Bluetooth Weather project.
Knowing the GATT characteristic needs units of W/m^2 is the first piece of the puzzle. The next is figuring out what the Nano's sensor reads. For this I had to find the data sheet for the APDS-9960 sensor.
On page four of the PDF, there's a line that reads: Clear channel irradiance responsivity, with minimum, typical, and maximum values of 18.88; 23.60; and 28.32, respectively. The units are expressed in counts/(μW/cm^2).
In other words, if the ambient light value read from the APDS-9960 is 23.60, that would be 1μW/cm^2. Of course, the reading is an integer, so it can't be 23.60. Another way to think of it is that every time the APDS-9960 counts to 236, that's 10μW/cm^2 of ambient light.
The first step, then, is to take the value reported by the APDS-9960 and divide it by 23.60 to get μW/cm^2.
APDS.readColor(red, green, blue, ambient);
irradiance = (float) ambient / 23.60;
But Bluetooth GATT characteristics are expressed in W/m^2 and the APDS-9960 data sheet says the units are in μW/cm^2. There's more conversion to be done.
There are 10, 000 square centimeters in one square meter, so multiplying by 10, 000 will give μW/m^2.
There are 1, 000, 000 μW in a Watt, so dividing by 1, 000, 000 will give W/m^2.
Multiplying by ten-thousand and then dividing by one-million is the same as dividing by 100.
Conversion of the APDS-9960 counter output to W/m^2 involves first dividing by 23.60 to get μW/cm^2 then dividing by 100 to get W/m^2. This can be simplified as dividing the count by 2360.
APDS.readColor(red, green, blue, ambient);
irradiance = (float) ambient / 2360;
It's important to use (float) in the equation, because ambient
and 2360
are both integers and the fractional part will be lost without casting to a float type.
Before the irradiance value can be communicated, Bluetooth needs to be set up. This starts with creating a service and advertising it. The code below is part of the setup() function in the sketch.
BLEService environmentalSensingService("181A");
BLEUnsignedIntCharacteristic irradianceCharacteristic("2A77", BLERead);
BLE.setLocalName("Nano33BLE");
BLE.setAdvertisedService(environmentalSensingService);
environmentalSensingService.addCharacteristic(irradianceCharacteristic);
BLE.addService(environmentalSensingService);
BLE.setConnectable(true);
See the complete code for comments that explain what each part does.
Once the setup is done, all that's left is to wait for a connection and update the irradiance characteristic with a new value from the APDS-9960. The code below is the core of the loop() part of the sketch.
if (APDS.colorAvailable()) {
int red, green, blue, ambient;
APDS.readColor(red, green, blue, ambient);
irradiance = (float) ambient / 2360;
irradianceCharacteristic.writeValue((uint16_t) round(irradiance * 10));
}
There are a few more details that make the sketch complete. Be sure to look at the full code.
TestingAfter loading the sketch on the Nano, I tried a few scenarios. In a room lit with a single 60-Watt equivalent compact florescent bulb, the ambient light reading barely registered. Shining a white light LED flashlight a few inches above the sensor gave a much better reading. Unfortunately, the weather here has been cloudy, so it may be some time before I can test in full sun.
What's It Good For?Ultimately, I plan to combine this with my Bluetooth Weather sketch as one more characteristic alongside temperature, humidity, and barometric pressure. Measuring ambient outdoor light could be used to determine the amount of cloud cover.
If nothing else, it was a good introduction to Bluetooth communication and what it takes to make senor values accessible as GATT characteristics.
Comments
Please log in or sign up to comment.