wollewald / AP3216_WE

Arduino library for the AP3216C module (CJMCU 3216)
https://wolles-elektronikkiste.de/en/ap3216-cjmcu-3216-ambient-light-and-proximity-sensor
MIT License
7 stars 0 forks source link

Lux values change when range is changed #1

Open moeburn opened 10 months ago

moeburn commented 10 months ago

If the calculated Lux values are assumed to be an absolute measurement of light, they shouldn't change when you change the range setting. But for example on a default range setting of 20661, the value returned by myAP3216.getAmbientLight(); is 62, After changing the range to 323, the value returned by myAP3216.getAmbientLight(); is 0.87. But the amount of ambient light didn't change, so if this is calculated lux it should also not change.

It is as though the lux calculations from the datasheet have already been applied to whatever value this library is retrieving from the sensor, and the library is then multiplying by the lux conversion factor again for a second time, when it shouldn't. Either that or the range setting isn't being properly applied in single shot mode, even though it is being used to calculate lux.

moeburn commented 10 months ago

Upon further testing it appears I need to apply the range value with SetLuxRange every time I set up the next single shot measurement with setMode(AP3216_ALS_PS_ONCE), not just in void setup, as the module is resetting to its default range but the library is unaware of this. For some reason the first measurement after bootup is still the double-multiplied garbage value.

wollewald commented 10 months ago

When you request an ambient light value the raw value of the latest conversion will be read from the ALS data register. According to the data sheet one conversion takes typically 100 milliseconds. So, if you change the range and immediately request a measured value, you will will read a measured value from the former range, but the factors for the new range will be applied. I guess that is what happened here.

In continuous mode, the worst case would be that a measurement has started right before you applied a new range. You would then have to wait 100 milliseconds for the measurement to be completed and another 100 milliseconds for the measurement in the new range. Since the data sheet has not shown to be very reliable in all aspects and since it says that 100 milliseconds is a typical value, I would recommend at least 250 milliseconds. Unfortunately, the AP3216 has no "data ready" or "conversion completed" bit, so you always have to assume the worst case. I will add a comment in the example sketches.

In single shot mode, the initiation of the measurement and and the request of the results are two steps. So yes, setMode(AP3216_ALS_PS_ONCE) will initiate the next measurement. This is explained in the example sketch and in my article about module and my library:

https://github.com/wollewald/AP3216_WE/blob/f2a1a148d3075d741f86d165ba18af65ec9a9603/examples/AP3216_Single/AP3216_Single.ino#L36

image

So, in single shot mode you can initiate the measurement immediately after you changed the range and then you'll need to wait 100 milliseconds (plus some safety time) before you request the result.

The alternative would be that I add the inititiation and delay to the getAmbientLight() function but that would be blocking. And in 100 milliseconds the microcontroller can do a lot of other things. My experience is that people raise issues if I apply blocking function. Maybe I add a "waitForCoversion()" conversion function which would be just a delay(150) to make it more obvious that you have to wait.