Skip to content

Commit

Permalink
bh1750: more decimals for mode2
Browse files Browse the repository at this point in the history
return half of raw value in both modes involving it
resolve #2550 (just for the sensor, no global setting yet)
  • Loading branch information
mcspr committed Dec 4, 2022
1 parent bea8508 commit b8921b9
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions code/espurna/sensors/BH1750Sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
#define BH1750_ONE_TIME_LOW_RES_MODE 0x23 // Start measurement at 1lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.

class BH1750Sensor : public I2CSensor<> {
static constexpr bool bh1750_is_mode2(unsigned char mode) {
return (mode == BH1750_CONTINUOUS_HIGH_RES_MODE_2) || (mode == BH1750_ONE_TIME_HIGH_RES_MODE_2);
}

class BH1750Sensor : public I2CSensor<> {
public:

void setMode(unsigned char mode) {
Expand Down Expand Up @@ -48,7 +51,9 @@ class BH1750Sensor : public I2CSensor<> {
// Initialization method, must be idempotent
void begin() override {

if (!_dirty) return;
if (!_dirty) {
return;
}

// I2C auto-discover
static constexpr uint8_t addresses[] {0x23, 0x5C};
Expand Down Expand Up @@ -90,10 +95,18 @@ class BH1750Sensor : public I2CSensor<> {
return 0;
}

// Number of decimals for a unit (or -1 for default)
signed char decimals(espurna::sensor::Unit unit) const {
if (bh1750_is_mode2(_mode)) {
return 2;
}

return 1;
}

protected:

double _read(uint8_t address) {

// For one-shot modes reconfigure sensor & wait for conversion
if (_run_configure) {

Expand All @@ -108,7 +121,7 @@ class BH1750Sensor : public I2CSensor<> {
espurna::duration::Milliseconds { (_mode & 0x02) ? 24 : 180 });

// Keep on running configure each time if one-shot mode
_run_configure = _mode & 0x20;
_run_configure = (_mode & 0x20) > 0;

}

Expand All @@ -119,12 +132,16 @@ class BH1750Sensor : public I2CSensor<> {
return 0;
}

return ((double) level) / 1.2;
// When using HIGH Mode2, value is halved
const auto multiplier = bh1750_is_mode2(_mode) ? 0.5 : 1.0;

// TODO also * MTreg?
return ((double)level / 1.2) * multiplier;
}

unsigned char _mode;
bool _run_configure = false;

double _lux = 0;

};
Expand Down

7 comments on commit b8921b9

@davebuk
Copy link
Contributor

@davebuk davebuk commented on b8921b9 Dec 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now have a decimal reading but presumed the output would either be #.0 or #.5 for any given light level.

With #define BH1750_MODE BH1750_CONTINUOUS_HIGH_RES_MODE_2 set at build, I'll get #.## readings, e.g 4.83 then 5.25 on the next 6 second read.

Without #define BH1750_MODE BH1750_CONTINUOUS_HIGH_RES_MODE_2 set at build, I'll get #.# readings, e.g 4.8 then 5.7 on the next 6 second read.

Are the #.## two decimal point values read form the sensor or just mathematically calculated values based on read time intervals?

@mcspr
Copy link
Collaborator Author

@mcspr mcspr commented on b8921b9 Dec 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only other value we could change is MTreg though? aka sensitivity

Sensor seems to already handle spans of time for raw value, we just need to take care of the config.
But, even with doubled MTreg, I think the raw value would be doubled and another multiplication by 69 / 138 aka 0.5 would yet again return something close to the originally read one?

edit: and meaning, we don't change the raw values too much but only the precision at which they are stored in the sensor reg

@mcspr
Copy link
Collaborator Author

@mcspr mcspr commented on b8921b9 Dec 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> 988a972
Slightly different, I'd suggest to use 1s reading interval instead of default 6s
Hopefully not broken :>

@davebuk
Copy link
Contributor

@davebuk davebuk commented on b8921b9 Dec 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All still working :-) even at 1 second reads.

The decimal values are still displaying e.g 7.38 or 7.75 or if built without #define BH1750_MODE BH1750_CONTINUOUS_HIGH_RES_MODE_2, 7.9 or 8.2 etc etc.

Its not an issue that the values are #.38 or #.75 etc I just presumed they would either be #.0 or #.5 for any decimal reading.

Again, its not an issue I just wondered if the values being displayed were correct?

@mcspr
Copy link
Collaborator Author

@mcspr mcspr commented on b8921b9 Dec 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried changing accuracy?

@mcspr
Copy link
Collaborator Author

@mcspr mcspr commented on b8921b9 Dec 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, its not an issue I just wondered if the values being displayed were correct?

Based on the datasheet, it seems it is 'precise up to' not how much the step is. We just grab the latest data directly from the devicce, only thing changing those is MTreg aka accuracy.

btw there is bh1750 driver for Linux, one could easily compare our results connecting to some sbc w/ i2c bus exposed (raspberry pi, etc.)
(ref. https://elixir.bootlin.com/linux/v6.1-rc8/source/drivers/iio/light/bh1750.c; it should be packaged by default, I see one in my /lib/modules/$kernel dir)

@davebuk
Copy link
Contributor

@davebuk davebuk commented on b8921b9 Dec 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried changing accuracy?

I have now. Setting #define BH1750_ACCURACY 1.44 will give values (at the current brightness) in the range of 8.86 and 9.21. I did have a value of 10.00 at one point but all other decimal values could be in the range of #.01 - #.99.

Building with accuracy at 1.2 and changing #define BH1750_SENSITIVITY to 1.0, 2.0, 3.0 or 3.68 doesn't affect the value either.

I'm happy with the output, it gives me the extra bit of range via the MQTT value every one minute to control the lights I want as per the original issue.

The sensor is built into a housing holding the ESP board so unfortunately I can't easily hook it upto a Linux device.

Please sign in to comment.