0.3.2 BH1750FVI_RT

This commit is contained in:
Rob Tillaart 2024-07-24 11:05:52 +02:00
parent 710ef84c52
commit 3bc3891230
8 changed files with 155 additions and 82 deletions

View File

@ -1,7 +1,7 @@
// //
// FILE: BH1750FVI.cpp // FILE: BH1750FVI.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.3.1 // VERSION: 0.3.2
// PURPOSE: library for BH1750FVI lux sensor Arduino // PURPOSE: library for BH1750FVI lux sensor Arduino
// URL: https://github.com/RobTillaart/BH1750FVI_RT // URL: https://github.com/RobTillaart/BH1750FVI_RT
@ -84,8 +84,8 @@ float BH1750FVI::getLux(void)
{ {
lux *= _angleFactor; lux *= _angleFactor;
} }
// temperature compensation. // temperature compensation. 20 C is default.
if (_temp != 20) if (_temperature != 20)
{ {
lux *= _tempFactor; lux *= _tempFactor;
} }
@ -215,16 +215,16 @@ float BH1750FVI::getCorrectionFactor()
float BH1750FVI::setTemperature(int temp) float BH1750FVI::setTemperature(int temp)
{ {
_temp = temp; _temperature = temp;
// _tempFactor = 1.0f - (_temp - 20.0f) / 2000.0f; // _tempFactor = 1.0f - (_temperature - 20.0f) / 2000.0f;
_tempFactor = 1.0f - (_temp - 20.0f) * 0.0005f; _tempFactor = 1.0f - (_temperature - 20.0f) * 0.0005f;
return _tempFactor; return _tempFactor;
} }
float BH1750FVI::setAngle(int degrees) float BH1750FVI::setAngle(float degrees)
{ {
_angle = constrain(degrees, -89, 89); _angle = constrain(degrees, -89.9, 89.9);
// Lambert's Law. // Lambert's Law.
_angleFactor = 1.0f / cos(_angle * (PI / 180.0f)); _angleFactor = 1.0f / cos(_angle * (PI / 180.0f));
return _angleFactor; return _angleFactor;

View File

@ -2,7 +2,7 @@
// //
// FILE: BH1750FVI.h // FILE: BH1750FVI.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.3.1 // VERSION: 0.3.2
// PURPOSE: Arduino library for BH1750FVI (GY-30) lux sensor // PURPOSE: Arduino library for BH1750FVI (GY-30) lux sensor
// URL: https://github.com/RobTillaart/BH1750FVI_RT // URL: https://github.com/RobTillaart/BH1750FVI_RT
@ -27,7 +27,7 @@
#include "Arduino.h" #include "Arduino.h"
#define BH1750FVI_LIB_VERSION (F("0.3.1")) #define BH1750FVI_LIB_VERSION (F("0.3.2"))
#define BH1750FVI_DEFAULT_ADDRESS 0x23 #define BH1750FVI_DEFAULT_ADDRESS 0x23
@ -56,7 +56,7 @@ public:
float getRaw(); // no HIGH2 mode + no sensitivity factor. float getRaw(); // no HIGH2 mode + no sensitivity factor.
float getLux(); float getLux(); // corrected for mode, temp, angle and correctionFactor.
int getError(); int getError();
@ -98,8 +98,8 @@ public:
// read datasheet P3 and check figure 4 and 5. // read datasheet P3 and check figure 4 and 5.
// setAngle is constrained to -89..+89 // setAngle is constrained to -89..+89
// returns the angle correction factor // returns the angle correction factor
float setAngle(int degrees = 0); float setAngle(float degrees = 0);
int getAngle() { return _angle; }; float getAngle() { return _angle; };
// datasheet P3 figure 7 // datasheet P3 figure 7
@ -107,7 +107,7 @@ public:
// to be used if temp is really hot or cold. // to be used if temp is really hot or cold.
// returns the temperature correction factor // returns the temperature correction factor
float setTemperature(int temp = 20); float setTemperature(int temp = 20);
int getTemperature() { return _temp; }; int getTemperature() { return _temperature; };
// datasheet Page 3 figure 1 (experimental correction) // datasheet Page 3 figure 1 (experimental correction)
@ -131,9 +131,9 @@ private:
uint32_t _requestTime = 0; uint32_t _requestTime = 0;
float _angleFactor = 1; float _angleFactor = 1;
int _angle = 0; float _angle = 0;
float _tempFactor = 1; float _tempFactor = 1;
int _temp = 20; int _temperature = 20;
float _waveLengthFactor = 1; float _waveLengthFactor = 1;
int _waveLength = 580; int _waveLength = 580;

View File

@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
##[0.3.2] - 2024-07-23
- Fix #24, update readme.md
- setAngle() change parameter to float
- minor edits.
##[0.3.1] - 2024-04-09 ##[0.3.1] - 2024-04-09
- update GitHub actions - update GitHub actions
- update URL in examples - update URL in examples
@ -13,7 +18,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- fix CHANGELOG.md - fix CHANGELOG.md
- minor edits - minor edits
##[0.3.0] - 2023-10-18 ##[0.3.0] - 2023-10-18
- simplify constructor / begin() - simplify constructor / begin()
- update examples - update examples

View File

@ -17,7 +17,7 @@ Arduino library for BH1750FVI (GY-30) 16 bit I2C Lux sensor.
## Description ## Description
The BH1750FVI is a 16 bit lux sensor with an I2C interface. The BH1750FVI is a 16 bit lux sensor with an I2C interface.
It is possible to detect a wide range from 0.11 - 100000 lux. This sensor has a wide working range from 0.11 - 100000 lux.
To be able to support this wide range, the sensor can operate in three modi. To be able to support this wide range, the sensor can operate in three modi.
@ -34,11 +34,39 @@ It can be used to increase the working range like very bright or very low light
Another application is to correct the transparency of material, or the type of light used. Another application is to correct the transparency of material, or the type of light used.
Note that the typical integration time will differ if the correction factor is changed. Note that the typical integration time will differ if the correction factor is changed.
The **isReady()** an **getLux()** functions keep track of the adjustment needed. The **isReady()** and **getLux()** functions keep track of the adjustment needed.
#### Related ### 0.3.0 Breaking change
Version 0.3.0 introduced a breaking change.
You cannot set the I2C pins in the constructor any more.
This reduces the dependency of processor dependent Wire implementations.
The user has to call **Wire.begin()** and can optionally set the Wire pins
before calling **begin()**.
### Lux levels
The following table is an indication for Lux levels.
These might differ due to angle of incoming light or other causes.
Note that the table is not linear.
| LUX | Description |
|:--------:|:--------------------|
| 1 | Night |
| 10 | Twilight |
| 100 | Dark day |
| 1000 | Cloudy day |
| 10000 | Indirect sunlight |
| 100000 | Direct sunlight |
More elaborated table, e.g https://en.wikipedia.org/wiki/Lux
### Related
- https://en.wikipedia.org/wiki/Lux
- https://github.com/RobTillaart/BH1750FVI_RT - https://github.com/RobTillaart/BH1750FVI_RT
- https://github.com/RobTillaart/Max44007 - https://github.com/RobTillaart/Max44007
- https://github.com/RobTillaart/Max44009 - https://github.com/RobTillaart/Max44009
@ -52,7 +80,6 @@ IR sensor
- https://github.com/RobTillaart/TSL260R analog IR irradiance variant. - https://github.com/RobTillaart/TSL260R analog IR irradiance variant.
## Interface hardware ## Interface hardware
Library was tested with a breakout board. Library was tested with a breakout board.
@ -68,44 +95,77 @@ Library was tested with a breakout board.
// VCC |o | // VCC |o |
// +-----------------------+ // +-----------------------+
// //
// ADD = ADDRESS:
// 0 = 0x23
// 1 = 0x5C
//
``` ```
The sensor works on 2.4 - 3.6 volt so be careful not to connect directly to 5.0 volt. The sensor works on 2.4 - 3.6 volt so be careful not to connect directly to 5.0 volt.
Note: the breakout board was 5 volt tolerant. Note: the breakout board was 5 volt tolerant.
### I2C address
I2C address can be set with the ADDRESS pin.
| ADD PIN | address |
|:---------:|:---------:|
| LOW | 0x23 |
| HIGH | 0x5C |
Note these two addresses are inverted (7 bit).
### I2C multiplexing
Sometimes you need to control more devices than possible with the default
address range the device provides.
This is possible with an I2C multiplexer e.g. TCA9548 which creates up
to eight channels (think of it as I2C subnets) which can use the complete
address range of the device.
Drawback of using a multiplexer is that it takes more administration in
your code e.g. which device is on which channel.
This will slow down the access, which must be taken into account when
deciding which devices are on which channel.
Also note that switching between channels will slow down other devices
too if they are behind the multiplexer.
- https://github.com/RobTillaart/TCA9548
## Interface ## Interface
```cpp ```cpp
#include "BH1750FVI.h" #include "BH1750FVI.h"
``` ```
#### Constructor ### Constructor
- **BH1750FVI(uint8_t address, uint8_t dataPin, uint8_t clockPin)** ESP constructor with I2C parameters. - **BH1750FVI(uint8_t address, TwoWire \*wire = &Wire)** constructor.
- **BH1750FVI(uint8_t address, TwoWire \*wire = &Wire)** constructor for other platforms.
- **bool begin()** resets some internal variables to default. Use with care. - **bool begin()** resets some internal variables to default. Use with care.
- **bool isConnected()** returns true if address is on I2C bus. Returns true if address can be found on I2C bus.
- **bool isConnected()** returns true if address can be found on I2C bus.
#### Base ### Base
- **float getRaw()** reads the lux sensor. - **float getRaw()** reads the lux sensor.
- **float getLux()** reads the lux sensor and corrects for correctionFactor, mode, temperature and angle. - **float getLux()** reads the lux sensor and corrects for correctionFactor,
mode, temperature and angle.
#### Management ### Management
- **int getError()** get the latest error code, mainly for debugging. - **int getError()** get the latest error code, mainly for debugging.
- **void powerOn()** wakes up the sensor. - **void powerOn()** wakes up the sensor.
- **void powerOff()** set sensor to sleep. - **void powerOff()** set the sensor to sleep.
- **void reset()** resets the data register to 0, effectively removing last measurement. - **void reset()** resets the data register to 0, effectively removing last measurement.
#### Mode operators ### Mode operators
| ID | Mode | Integration time | Resolution | Notes |
|:----:|:-----:|:----------------:|:----------:|:--------------------------|
| 0 | LOW | 16 ms | 4.0 Lux | measure very bright light |
| 1 | HIGH | 120 ms | 1.0 lux | default |
| 2 | HIGH2 | 120 ms | 0.5 lux | measure very dim light |
- **uint8_t getMode()** gets the mode set by one of the set functions. - **uint8_t getMode()** gets the mode set by one of the set functions.
See table above. See table above.
@ -116,23 +176,26 @@ See table above.
- **void setOnceHigh2Res()** single shot mode in HIGH2 resolution. - **void setOnceHigh2Res()** single shot mode in HIGH2 resolution.
- **void setOnceLowRes()** single shot mode in LOW resolution. - **void setOnceLowRes()** single shot mode in LOW resolution.
- **bool isReady()** can be used to check if the sensor is ready.
This is based on a calculated time, the sensor does not have a means to indicate ready directly.
Needed only when one of the single shot modi is set.
The function **isReady()** takes the correction factor into account.
#### CorrectionFactor
### CorrectionFactor
Please read datasheet P11 about details of the correction factor. Please read datasheet P11 about details of the correction factor.
- **bool isReady()** can be used to check if the sensor is ready.
This is based on a calculated time, the sensor does not have a means to indicate ready directly.
Needed only for the single shot modi.
The function **isReady()** takes the correction factor into account.
- **void changeTiming(uint8_t time = BH1750FVI_REFERENCE_TIME)** 69 is default. - **void changeTiming(uint8_t time = BH1750FVI_REFERENCE_TIME)** 69 is default.
- **uint8_t setCorrectionFactor(float factor = 1)** preferred wrapper around changeTiming factor = 0.45 .. 3.68. - **uint8_t setCorrectionFactor(float factor = 1)** preferred wrapper around
changeTiming factor = 0.45 .. 3.68.
Returns changeTiming() parameter. Returns changeTiming() parameter.
- **float getCorrectionFactor()** returns the correction factor. - **float getCorrectionFactor()** returns the correction factor.
Note this can differ as it is stores as an integer internally. Note the returned value can differ slightly from the set value as the value is
stored as an integer internally.
#### Angle sensitivity ### Angle sensitivity
Note: experimental - use carefully Note: experimental - use carefully
@ -144,28 +207,32 @@ The angle adjustments is based upon the figure 4 and 5 (directional characterist
which describe **Lamberts Cosine Law**. (details see Wikipedia) which describe **Lamberts Cosine Law**. (details see Wikipedia)
So the correction factor is ```factor = 1.0 / cos(angle)```. So the correction factor is ```factor = 1.0 / cos(angle)```.
At 90 degrees it would fail (divide by zero) so the input is constrained At 90 degrees it would fail (divide by zero) so the input is constrained
to angles between -89 - +89 degrees. to angles between -89.9 - +89.9 degrees.
If the light is perpendicular on the sensor the angle to use is 0 degrees. If the light is perpendicular on the sensor the angle to use is 0 degrees.
Light coming from the side is 90 degrees. Light coming from the side is ±90 degrees.
- **float setAngle(int degrees = 0)** adjust the lux to incoming angle in degrees (-89..89). - **float setAngle(float degrees = 0)** adjust the lux to incoming angle in degrees (-89..89).
Returns the angle correction factor. Returns the angle correction factor.
- **int getAngle()** returns set angle in degrees, 0 by default is perpendicular. - **float getAngle()** returns set angle in degrees, 0 by default is perpendicular.
Note: it could be enough to be able to set the angle to 0..89.9 degrees as the
sign is not relevant.
#### Temperature Compensation ### Temperature Compensation
The reference temperature of the sensor = 20°C. The reference temperature of the sensor = 20°Celsius.
The effect of temperature is small, about 3% per 60°C ==> 1% per 20°C The effect of temperature is small, about 3% per 60°C ==> 1% per 20°C
so only on either a hot roof or on a icy cold day the effect is substantial. so only on either a hot roof or on a icy cold day the effect is substantial.
See datasheet P3 fig 7.
- **float setTemperature(int temp = 20)** see datasheet P3 fig 7. - **float setTemperature(int temp = 20)** set the temperature in Celsius to compensate for.
Returns the temperature correction factor. Returns the temperature correction factor.
- **int getTemperature()** returns temperature set, default = 20°C. - **int getTemperature()** returns temperature set, default = 20°C.
#### Spectral Compensation ! EXPERIMENTAL ! ### Spectral Compensation ! EXPERIMENTAL !
Spectral compensation is experimental and not tested. It is a compensation based upon the Spectral compensation is experimental and not tested. It is a compensation based upon the
graph figure 1, page 3 of the datasheet. If one has light of a known wavelength one can graph figure 1, page 3 of the datasheet. If one has light of a known wavelength one can
@ -173,7 +240,7 @@ compensate for it by setting the wavelength. It can also be used when using filt
As said it is not tested so use at your own risk, but I am interested in your experiences As said it is not tested so use at your own risk, but I am interested in your experiences
if you do real tests with it. if you do real tests with it.
- **float setWaveLength(int wavelength = 580)** set wavelength. - **float setWaveLength(int wavelength = 580)** set wavelength of the light.
Returns the wavelength correction factor. Returns the wavelength correction factor.
- **int getWaveLength()** returns set wavelength. - **int getWaveLength()** returns set wavelength.
@ -200,20 +267,21 @@ Default wavelength will be 580 as that gives 100%.
#### Must #### Must
#### Should #### Should
- test
#### Could #### Could
- **Intelligent isReady()** - **Intelligent isReady()**
After a **getLux()** call one can clean the data register explicitly with After a **getLux()** call one can clear the data register explicitly with
**reset()**. Then a call to **isReady()** fetches data and as long as **reset()**. Then a call to **isReady()** fetches data and as long as
data equals zero the sensor is not ready (or in pitch dark?) data equals zero the sensor is not ready (or sensor is in pitch dark?)
- **DVI interface** - **DVI interface**
To investigate, sort of external reset? To investigate, sort of external reset?
- move code to .cpp - move code to .cpp
#### Wont #### Wont
## Support ## Support

View File

@ -37,6 +37,7 @@ getAngle KEYWORD2
setTemperature KEYWORD2 setTemperature KEYWORD2
getTemperature KEYWORD2 getTemperature KEYWORD2
setWaveLength KEYWORD2 setWaveLength KEYWORD2
getWaveLength KEYWORD2 getWaveLength KEYWORD2

View File

@ -15,7 +15,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/BH1750FVI_RT.git" "url": "https://github.com/RobTillaart/BH1750FVI_RT.git"
}, },
"version": "0.3.1", "version": "0.3.2",
"license": "MIT", "license": "MIT",
"frameworks": "*", "frameworks": "*",
"platforms": "*", "platforms": "*",

View File

@ -1,9 +1,9 @@
name=BH1750FVI_RT name=BH1750FVI_RT
version=0.3.1 version=0.3.2
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for BH1750FVI (GY-30) lux sensor sentence=Arduino library for BH1750FVI (GY-30) lux sensor
paragraph=Includes compensation for angle, temperature and (experimental) wavelength. paragraph=Includes compensation for angle, temperature and (experimental) wavelength. GY30.
category=Sensors category=Sensors
url=https://github.com/RobTillaart/BH1750FVI_RT url=https://github.com/RobTillaart/BH1750FVI_RT
architectures=* architectures=*

View File

@ -152,17 +152,17 @@ unittest(test_angleFactor)
myLux.begin(); myLux.begin();
// -89 ..89 // -89 ..89
assertEqualFloat(57.2987, myLux.setAngle(-90), 0.0001); assertEqualFloat(572.967, myLux.setAngle(-90), 0.001);
assertEqualFloat(57.2987, myLux.setAngle(-89), 0.0001); assertEqualFloat( 57.2987, myLux.setAngle(-89), 0.0001);
assertEqualFloat(2.00000, myLux.setAngle(-60), 0.0001); assertEqualFloat( 2.00000, myLux.setAngle(-60), 0.0001);
assertEqualFloat(1.41421, myLux.setAngle(-45), 0.0001); assertEqualFloat( 1.41421, myLux.setAngle(-45), 0.0001);
assertEqualFloat(1.15470, myLux.setAngle(-30), 0.0001); assertEqualFloat( 1.15470, myLux.setAngle(-30), 0.0001);
assertEqualFloat(1.00000, myLux.setAngle( 0), 0.0001); assertEqualFloat( 1.00000, myLux.setAngle( 0), 0.0001);
assertEqualFloat(1.15470, myLux.setAngle( 30), 0.0001); assertEqualFloat( 1.15470, myLux.setAngle( 30), 0.0001);
assertEqualFloat(1.41421, myLux.setAngle( 45), 0.0001); assertEqualFloat( 1.41421, myLux.setAngle( 45), 0.0001);
assertEqualFloat(2.00000, myLux.setAngle( 60), 0.0001); assertEqualFloat( 2.00000, myLux.setAngle( 60), 0.0001);
assertEqualFloat(57.2987, myLux.setAngle( 89), 0.0001); assertEqualFloat( 57.2987, myLux.setAngle( 89), 0.0001);
assertEqualFloat(57.2987, myLux.setAngle( 90), 0.0001); assertEqualFloat( 572.967, myLux.setAngle( 90), 0.001);
} }