Light and Proximity Sensing with the APDS-9930
Share
The APDS-9930 packs two separate sensing functions into one small I2C chip: a proximity detector built from an infrared LED paired with a photodiode that measures how much of its own emitted IR light bounces back off a nearby object, and an ambient light sensor built from two other photodiodes — one that responds to visible plus infrared light and one that responds mostly to infrared — whose difference is used to approximate how a human eye perceives brightness. One package, one I2C bus, two independent readings: how bright the room is, and whether something is close to the sensor.
What does the APDS-9930 actually measure?
The APDS-9930 reports two unrelated values from the same chip:
- Ambient light — a lux-scale brightness reading, calculated from two photodiodes with different spectral responses (one broadband, one infrared-heavy). Subtracting the infrared-only reading from the broadband reading cancels out most of the infrared component in ordinary light, which is what lets the chip approximate the way a human eye responds to brightness rather than just reporting raw photodiode current.
- Proximity — a unitless count that rises as a reflective object gets closer. The chip drives its own onboard infrared LED in short pulses, and a dedicated proximity photodiode measures how much of that pulsed IR light reflects back. There's no time-of-flight calculation and no distance-in-millimeters output — it's a relative "getting closer" signal, not a ranging sensor.
Both functions run independently and can be read from the same I2C address without conflict, which is why a single APDS-9930 replaces what would otherwise be two separate sensors — a light sensor and a proximity sensor — wired to two different sets of pins.
APDS-9930 vs a bare LDR: why use a dedicated light sensor?
A bare LDR (light-dependent resistor) is cheap, requires no library, and works with nothing more than a voltage divider and an analogRead() — but it comes with real limits that a chip like the APDS-9930 is built to remove. An LDR's resistance-to-light response is not linear and is not calibrated to anything; two LDRs from the same batch can report different raw values under identical light. It also has no data interface — it's a passive resistor, so a microcontroller only ever sees a divided voltage, not a lux number. And it has no proximity function at all; detecting a nearby object with an LDR setup requires an entirely separate sensor, typically an IR pair or an ultrasonic module.
The APDS-9930 addresses all three: it reports through I2C rather than an analog divider, it applies a two-photodiode subtraction specifically to approximate human-eye brightness response rather than raw photoconductivity, and it adds proximity sensing in the same package using hardware most projects would otherwise need a second module for. The tradeoff is that it's a more complex part to bring up in software — it needs a library and correct I2C wiring, where an LDR just needs a resistor.
How do you wire the APDS-9930 to an Arduino Uno?
APDS-9930 breakout boards typically expose four to five pins: VCC, GND, SDA, SCL, and sometimes an INT (interrupt) pin. The sensing chip itself runs on 3.3V logic, so check your specific breakout's datasheet or markings for 5V tolerance before wiring VCC directly to the Uno's 5V pin — many breakouts include an onboard regulator and level shifting that make this safe, but not all do.
| Arduino Uno pin | APDS-9930 pin | Signal |
|---|---|---|
| 5V (or 3.3V, check your breakout) | VCC | Power |
| GND | GND | Ground |
| A4 | SDA | I2C data |
| A5 | SCL | I2C clock |
| Not required for basic reads | INT | Optional interrupt on threshold crossing |
The Uno's I2C bus is fixed to A4 and A5, so no pin configuration is needed in code beyond initializing the library — only the physical wiring needs to be correct. The default I2C address for this sensor family is 0x39; if a scan doesn't find the chip there, that's the first thing to check.
What can you build with combined light and proximity sensing?
Having both signals from one chip is most useful in projects where "how bright is it" and "is something nearby" need to be evaluated together rather than as two separate subsystems: auto-dimming displays that lower backlight brightness in a dark room but also wake on approach, proximity-triggered lighting that only turns on if the room is already dim (so it doesn't fire uselessly in daylight), touchless switches that need to ignore ambient brightness changes so they don't false-trigger at dawn or dusk, and desk or enclosure lighting that reacts to both a hand coming near and the room's existing light level. Any project that would otherwise need to correlate readings from two separate sensors can instead read both from a single I2C address.
Watch it built live
We typed this into Compoden's storefront assistant, Soldr, phrased around the outcome rather than naming a specific part number:
"I want to build a project that senses both ambient light level and nearby object proximity using an Arduino Uno"
Full disclosure: Compoden does not currently stock the APDS-9930 itself. Rather than a single combined sensor, Soldr priced the build around two separate parts that each cover one of the two functions: a GY-30 BH1750FVI Light Intensity Sensor Module for ambient light and an HC-SR04 Ultrasonic Sensor for proximity, alongside the Arduino Uno, a power adapter, and breadboard wire. As Soldr explained it: "This build lets you measure how much light is in a room and also detect if an object is close by. The main board takes readings from two different sensors and can then use that information for other tasks you might want to add later." On the light sensor specifically: "The GY-30 BH1750FVI Light Intensity Sensor Module is designed to measure how bright the ambient light is around it... This sensor uses the I2C interface to talk to the Arduino board." On the proximity sensor: "The HC-SR04 Ultrasonic Sensor measures distance by sending out sound waves and listening for them to bounce back. This is how it detects if an object is nearby." Soldr also flagged a real wiring caution worth knowing regardless of which parts you use: the BH1750 module runs 3.3V logic while the HC-SR04 and the Arduino both run 5V logic, so the two sensors' voltage levels don't match by default and need to be handled correctly when wiring them together.
Watch the firmware get generated
We then took the same project — this time naming the sensor directly — to Compoden's VoltIQ/Soldr code assistant and asked it to write working firmware:
"I'm using an APDS-9930 ambient light and proximity sensor over I2C with an Arduino Uno. Write the full firmware to read both ambient light level and proximity, printing them to the serial monitor."
Here the code generator made a different substitution than the storefront did: rather than two separate sensors, it reached for the APDS9960 — a chip in the same Broadcom/Avago sensor family that Compoden does stock, sharing the APDS-9930's IR-LED-plus-photodiode proximity design and dual-photodiode ambient light sensing, with RGB color and gesture detection added on top. The generated sketch pulls in Wire.h and SparkFun_APDS9960.h, the standard library path for this chip family, and the instructions above the code panel read: "Upload this sketch to your Arduino Uno R3 using the Arduino IDE. Install via Library Manager: SparkFun APDS9960." The firmware's own comment block spells out both the I2C address and the wiring it assumed: // APDS-9930 I2C address is 0x39, followed by // APDS9960 VCC -> Arduino 5V, // APDS9960 GND -> Arduino GND, // APDS9960 SDA -> Arduino A4, and // APDS9960 SCL -> Arduino A5 — the same SDA/SCL pin assignment as the wiring table above, since both chips share the same I2C interface convention.
Get everything in this build
These are the exact parts Soldr selected for the live storefront build above, with real prices and direct add-to-cart links. This tray uses the BH1750 + HC-SR04 combination rather than an APDS-9930 module, since Compoden does not currently carry that exact part — see the disclosure above for the full explanation.
| Part | Price | Add to cart |
|---|---|---|
| Arduino Uno R3 CH340G ATmega328P Board | Rs.230 | Add to cart |
| GY-30 BH1750FVI Light Intensity Sensor Module | Rs.110 | Add to cart |
| HC-SR04 Ultrasonic Sensor | Rs.85 | Add to cart |
| USB-C 5V 3A Power Supply Adapter | Rs.180 | Add to cart |
| 23 AWG Multi-Strand Breadboard Wire | Rs.10 | Add to cart |
| Total | Rs.615 | Add all 5 to cart |
Jumper wires were flagged as needed for this build but were out of stock at the time of writing, so they aren't in the table above — add a jumper wire kit from Compoden's prototyping section before you start. If you'd rather use a single combined chip instead of two separate sensors, Compoden stocks the APDS9960 RGB and Gesture Sensor Module (Rs.270) — the same part VoltIQ's code assistant reached for when asked to generate firmware for this build — which covers ambient light and proximity from one I2C address, plus RGB and gesture on top.
Built and Backed by Compoden
Every part listed above ships from Compoden's own India stock, checked for compatibility before being carded together for a build like this one. Orders typically arrive in 3-7 days, with Cash on Delivery and UPI both supported at checkout, and Compoden's support team is available if you run into wiring or firmware questions while putting the project together.
Frequently asked questions
Does Compoden sell the APDS-9930 itself?
Not currently. When asked to build a combined ambient-light-and-proximity project, Compoden's storefront assistant substitutes two separate parts that together cover both functions — a BH1750 light sensor and an HC-SR04 proximity sensor — while its code assistant instead reaches for the APDS9960, a related single-chip sensor Compoden does stock.
What's the difference between the APDS-9930 and the APDS9960?
Both are from the same Broadcom/Avago sensor family and share the same core design: an infrared LED and photodiode for proximity, plus a second photodiode pair for ambient light. The APDS9960 adds RGB color sensing and gesture detection on top of those two functions, and uses the same I2C wiring convention, which is why it's a workable stand-in when only ambient light and proximity are needed.
Why not just use an LDR for ambient light instead of a dedicated sensor?
An LDR is cheaper and needs no library, but its resistance-to-light response isn't calibrated or linear, it has no digital interface, and it can't sense proximity at all. A dedicated sensor like the APDS-9930 reports through I2C, applies a two-photodiode calculation to approximate human-eye brightness response, and adds proximity sensing in the same package.
Can the APDS-9930 be used with boards other than an Arduino Uno?
Yes. It communicates over I2C, which is available on essentially every common microcontroller, including ESP32 and ESP8266 boards. Since the chip's sensing die runs 3.3V logic natively, boards that run 3.3V logic themselves avoid the logic-level question that comes up when wiring it to a 5V board like the Uno.