Let's take a look at a typical function for reading this sensor. This is from the Adafruit_VCNL4010 library and is for reading the proximity:
uint16_t Adafruit_VCNL4010::readProximity(void) {
uint8_t i = read8(VCNL4010_INTSTAT);
i &= ~0x80;
write8(VCNL4010_INTSTAT, i);
write8(VCNL4010_COMMAND, VCNL4010_MEASUREPROXIMITY);
while (1) {
//Serial.println(read8(VCNL4010_INTSTAT), HEX);
uint8_t result = read8(VCNL4010_COMMAND);
//Serial.print("Ready = 0x"); Serial.println(result, HEX);
if (result & VCNL4010_PROXIMITYREADY) {
return read16(VCNL4010_PROXIMITYDATA);
}
delay(1);
}
}
So let's tot up all the I2C transactions in that one function:
read8
write8
write8
{repeated
read8
[read16]
delay(1)
}
So in a best case scenario, assuming it's in a "ready" state, that's the minimum number of transactions, and the delay doesn't occur. So what is in each of those transactions?
Begin the transaction, write the address, end transaction, delay 170µs, begin request, read 1 byte, end transaction. Total 4 bytes plus 170µs
Begin transaction, write address, write data. Total 3 bytes.
Begin the transaction, write the address, end transaction, begin request, read 2 bytes, end transaction. Total 5 bytes (I notice this one has no delay...?)
So now we can see a best case scenario total of bytes transferred:
4 read8 *
3 write8
3 write8
{repeated
4 read8 *
5 [read16]
delay(1)
}
4+3+3+4+5 = 19 bytes, plus 2x170µs delay.
The default clock speed for I2C on the Arduino is 100kHz. We have 19 bytes, plus start/stop/ack bits. So 19 * 8 for the data bytes (152 bits) plus 19 ACK bits (171 bits) and 5 * start + 5 * stop. That's 181 bits in total.
181 bits, at 100kHz, takes 1.81ms to transfer. Add to that the 2*170µs delay, and we are up to a best case scenario of 2.15ms transfer.
Double that up for reading the ambient light as well, and we're up to 4.3ms transfer. That's a theoretical absolute maximum of about 230Hz readings.
Remember: that's a best case scenario. If the sensor isn't ready to return a reading at the time that there will immediately be a 1ms delay imposed and the number of transactions will increase.
So why would it not be ready to send a reading? The simplest explanation is that it's not set to a suitable sampling rate.
The library doesn't appear to change the sampling rate for the proximity from the default 1.95 samples per second, nor the ambient light sampling rate from the default of 2 samples per second - so unless you are using a different library, or manually changing these settings through your own Wire calls, even at a reduced triggering speed you'll not be getting anywhere near the kind of information you are after.
The fastest you can get for ambient light sampling is 10 samples per second. Proximity caps out at a more respectable 250 samples per second. But only if you tell it to...