Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

H res mode2 #46

Merged
merged 16 commits into from
Oct 3, 2018
Merged

H res mode2 #46

merged 16 commits into from
Oct 3, 2018

Conversation

coelner
Copy link
Contributor

@coelner coelner commented Mar 8, 2018

to sum it up:

  1. change return value to float Improve error handling #26 my own suggestion
  2. check return value from Wire.requestFrom Better error handling if not two bytes are available for read. #41
  3. use negative values as error message Improve error handling #26
  4. added info to readme Update README to capture change to undefined light level value of 65535 #45

@claws
Copy link
Owner

claws commented Sep 23, 2018

Hi, I've finally had some time to look into this project again. I have some questions about this merge request.

I began by installing the updated BH1750 library into my Arduino environment and then compiled and ran the simplest example, examples/BH1750test.ino. This seemed to work and I assumed was returning a int32_t even though the example creates a float lux to hold the returned value.

I then attempted to test the new float functionality by uncommented the pre-processor section at the top of the example script. This should remove the readLightLevel function that returns a int32_t and replace it with a readLightLevel function that returns a float. I observed compilation errors. It appears that the pre-processor flags are not quite working as expected.

Compiling /path/to/BH1750/examples/BH1750test/BH1750test.ino
/var/folders/_y/fb30sc1x5l54n3cymwws4rdc0000gn/T//ccIyCBjg.ltrans0.ltrans.o: In function `loop':
/path/to/BH1750/examples/BH1750test/BH1750test.ino:51: undefined reference to `BH1750::readLightLevel(bool)'
collect2: error: ld returned 1 exit status
exit status 1

With regard to the implementation proposed, I observe you have added the function to return a float and the needed internals to support that. In addition to that you have added another function which returns an integer value. The library now appears to return either an int32_t or a float. To switch between the alternative return types you have wrapped the function implementations with the pre-processor BH1750_FLOAT flag.

What is the reason for adding the integer functionality? Why not just the float function and remove all the complexity of the pre-processor code? Alternatively, if there is a real need for the integer function why not provide it as an explicit public function name and discard the pre-processor checks. Then leave it to a user to decide which functionality they want. Personally I think just having the float function is sufficient.

When I attempt to compile the new example script that demonstrates adjusting the measurement time I observe compile errors. I see the same when I use the simple compilation check script (build-examples.bash).

$ ARDUINO_IDE_PATH=/Applications/Arduino.app/Contents/Java ./build-examples.bash
Compiling /path/to/BH1750/examples/BH1750advanced/BH1750advanced.ino
Sketch uses 5844 bytes (18%) of program storage space. Maximum is 32256 bytes.
Global variables use 427 bytes (20%) of dynamic memory, leaving 1621 bytes for local variables. Maximum is 2048 bytes.
Compiling /path/to/BH1750/examples/BH1750onetime/BH1750onetime.ino
Sketch uses 5812 bytes (18%) of program storage space. Maximum is 32256 bytes.
Global variables use 427 bytes (20%) of dynamic memory, leaving 1621 bytes for local variables. Maximum is 2048 bytes.
Compiling /path/to/BH1750/examples/BH1750test/BH1750test.ino
Sketch uses 5810 bytes (18%) of program storage space. Maximum is 32256 bytes.
Global variables use 427 bytes (20%) of dynamic memory, leaving 1621 bytes for local variables. Maximum is 2048 bytes.
Compiling /path/to/BH1750/examples/BH1750autoadjust/BH1750autoadjust.ino
/path/to/BH1750/examples/BH1750autoadjust/BH1750autoadjust.ino: In function 'void setup()':
/path/to/BH1750/examples/BH1750autoadjust/BH1750autoadjust.ino:33:14: error: 'D2' was not declared in this scope
   Wire.begin(D2, D1);
              ^
/path/to/BH1750/examples/BH1750autoadjust/BH1750autoadjust.ino:33:18: error: 'D1' was not declared in this scope
   Wire.begin(D2, D1);
                  ^
exit status 1

I think you need to remove the references to the pins similar to the other examples.

It looks like this change would also close out #34 and #35 and #51. Is that correct?

@coelner
Copy link
Contributor Author

coelner commented Sep 25, 2018

Hi, I had some trouble with my local sync daemon and the git repo. Therefore I need time to get back into this merge request.

  1. Most of the microprocessors are bad at float calculations, but someone may find it useful to use them. I included them for testing purpose, but I did not complete this thought.
  2. I'm not sure, but the pre processor flags needs to be in *.h file
  3. Measurement Time Register function #34, Define conversion factor as a constant #35 and Better error handling #51 are closed
  4. I try to get this ready within a week

@@ -20,6 +20,11 @@

*/

/*
Copy link
Owner

Choose a reason for hiding this comment

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

This comment block should be removed as it only seems possible to modify the BH1750_FLOAT setting in the BH1750.h file not in user code.

@@ -10,6 +10,10 @@
preparation for the next measurement.

*/
/*
Copy link
Owner

Choose a reason for hiding this comment

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

This comment block should be removed as it only seems possible to modify the BH1750_FLOAT setting in the BH1750.h file not in user code.

@@ -23,7 +23,11 @@
#include <BH1750.h>

/*
Remove the following if you want to use float
Copy link
Owner

Choose a reason for hiding this comment

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

This comment block should be removed as it only seems possible to modify the BH1750_FLOAT setting in the BH1750.h file not in user code.

BH1750.cpp Outdated
#ifdef BH1750_FLOAT
/**
* Read light level from sensor
* @return Light level in lux (0.0 ~ 54612,5 [121556,85])
Copy link
Owner

Choose a reason for hiding this comment

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

Why are there two return value ranges specified in this comment? Does this comment need to be cleaned up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the value within the square brackets is the maximum value if you change the MTReg value. Otherwise you will get the value within the normal brackets.

@claws
Copy link
Owner

claws commented Sep 29, 2018

Thanks for your updates that add improved functionality and better refine the return values in error conditions.

I have some more review comments:

  1. There are a bunch of comments left in the example files that still refer to changing the BH1750_FLOAT define setting which need to be removed. The BH1750_FLOAT setting can only be modified in the `BH1750.h`` file. I'm unsure how a normal user would really modify it.
  2. The comment block above the float BH1750::readLightLevel(bool maxWait) in the BH1750.cpp indicates two separate ranges of return values. I suspect that this comment is no longer correct and should be fixed up.
  3. There is value in keeping this library simple so that it is easy to use and easy to test. The existing library returns a float value and I think we should stick with just that for now as no-one has been asking for int32_t based functionality and introducing it adds a significant amount of complexity to the code base. Can you pull out all code associated with the int32_t BH1750::readLightLevel(bool maxWait, bool hundredth) function? This would remove any need for having the BH1750_FLOAT setting. If you think the integer functionality is required feel then you could propose it in a separate merge request.

@coelner
Copy link
Contributor Author

coelner commented Sep 29, 2018

Thank you for the hints, unfortunately I haven't finished yet.

  1. I fixed that.
  2. that is related to the changable MTReg value. But I can add a note to that specific behaviour
  3. Of course. I don't know why I implemented that feature.

@coelner
Copy link
Contributor Author

coelner commented Oct 1, 2018

Should be completed

README.md Outdated

The sensor returns a 16 bit unsigned integer. Therefore the maximum value is limited in general.
The standard conversion between the so called 'counts' to lux is 1/1.2, that means you get a smaller value.
As we use signed integer or float, if an error occurs you will get a negative value.
Copy link
Owner

Choose a reason for hiding this comment

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

On this line the signed integer reference is no longer needed. In fact you could probably remove the first part and just say "If an error occurs...".


void loop() {
//we use here the maxWait option due fail save and we want reduced information loss due missing decimal part
float lux = lightMeter.readLightLevel(true, true)/100.0;
Copy link
Owner

Choose a reason for hiding this comment

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

The readLightLevel arguments here don't match the .h definition. There are two args when only one is expected.
Also, it s there a reason for dividing by 100? If so it would be useful for user to see a comment about why it is here.

//reduce time slot - needed in direct sun light
if(lightMeter.setMTreg(32)) {
Serial.println(F("[DEBUG]: MTReg low"));
lux = lightMeter.readLightLevel(true, true)/100.0;
Copy link
Owner

Choose a reason for hiding this comment

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

Same comment as above.

else {
if(lux > 10.0 && lightMeter.setMTreg(69)) {
Serial.println(F("[DEBUG]: MTReg default"));
lux = lightMeter.readLightLevel(true, true)/100.0;
Copy link
Owner

Choose a reason for hiding this comment

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

Same comment as above.

//very low light environment
if(lightMeter.setMTreg(254)) {
Serial.println(F("[DEBUG]: MTReg high"));
lux = lightMeter.readLightLevel(true, true)/100.0;
Copy link
Owner

Choose a reason for hiding this comment

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

Same comment as above.

@coelner
Copy link
Contributor Author

coelner commented Oct 2, 2018

sorry, I forget the example. The Readme should be clear now, the user should be aware that the sensor return only a unsigned 16 bit integer and therefore the user will get a smaller value. The datasheet announce a higher value which is only available after selecting MTreg.

@claws
Copy link
Owner

claws commented Oct 3, 2018

Some more review comments, hopefully these are the last ones. I think it is pretty close to being good to go.

These comments are all related to the BH1750autoadjust.ino example file.

  1. Could you set the baud rate the same as the other examples? I'm not too fussed about the actual value just so long as they are all consistent. It makes testing the examples easier as I don't have to remember to switch the baud rate for just one of the example files.
  2. There are multiple occurrences of lux = lux = readLightLevel(true);. I suspect that this is a left over from a refactor and the extra lux was missed from being removed.
  3. I am unable to thoroughly test the example as it is currently written. If I reduce the light level seen by the board the MTReg gets set to 254 and then the program just stops running or is locked up. I'm not exactly sure what is happening here. I lower the low light MTReg value from 254 down to 100 which worked. I then incrementally worked up to a value of 176. Anything higher and I see the same lock up problem. Do you encounter a similar issue? Perhaps consider lowering the value in the example so it will likely work for most people trying out the example. I suggest something between 100 and 176.
  4. If you do encounter a similar lock up issue when using large MTReg values (low light) could you add a comment in the example that large values have been observed to cause issues like locking up.
  5. I restructured the example loop function so it was a little easier for me to understand. I suspect that as it was written an error would fall into the <=10 block. There also didn't seem to be a need to read the light level within each if block after changing the MTReg value. I mainly added some error handling conditions. I also removed the DEBUG comment word as this is an example where it is fine to print this state information out. Please consider refactoring it along the same lines as shown below:
void loop() {
  //we use here the maxWait option due fail save
  float lux = lightMeter.readLightLevel(true);
  Serial.print(F("Light: "));
  Serial.print(lux);
  Serial.println(F(" lx"));
  
  if (lux < 0) {
    Serial.println(F("[DEBUG]: Error condition detected"));
  }
  else {
    if (lux > 40000.0) {
      // reduce measurement time - needed in direct sun light
      if (lightMeter.setMTreg(32)) {
        Serial.println(F("Setting MTReg to low value for high light environment"));
      }
      else {
        Serial.println(F("Error setting MTReg to default value for normal light environment"));
      }
    }
    else {
        if (lux > 10.0) {
          // typical light environment
          if (lightMeter.setMTreg(69)) { 
            Serial.println(F("Setting MTReg to default value for normal light environment"));
          }
          else {
            Serial.println(F("Error setting MTReg to default value for normal light environment"));
          }
        }
        else {
          if (lux <= 10.0) {
            //very low light environment
            if (lightMeter.setMTreg(176)) {
              Serial.println(F("Setting MTReg to high value for low light environment"));
            }
            else {
              Serial.println(F("Error setting MTReg to high value for low light environment"));
            }
          }
       }
    }

  }
  Serial.println(F("--------------------------------------")); 
  delay(5000);
}

@coelner
Copy link
Contributor Author

coelner commented Oct 3, 2018

  1. Done
  2. Yap, done.
  3. I run this sketch under esp8266 and it is working flawless. (I use the current esp8266 master branch, but I have big trouble for the last 6 month to get i2c working in a stable way. Do you use an arduino?
  4. I add this comment to remind the user to test their hardware
  5. I can't find any negative aspect of the refactoring. I enforced a new measurement after setting MTreg, but this is not needed if the user wait until loop() starts over. In my case I want to see the proper value immediately. In your sketch the light intensity should only change not faster than 11 seconds (Nyquist-theorem)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants