adafruit / Adafruit-Raspberry-Pi-Python-Code

Adafruit library code for Raspberry Pi
1.43k stars 686 forks source link

Module for TSL2561 Light Sensor #137

Closed asciipip closed 4 years ago

asciipip commented 8 years ago

This includes a module for interacting with the TSL2561 light sensor. I hope that the main class's documentation is sufficient for use. If you have any questions or problems, please let me know.

csatt commented 8 years ago

Hi Phil,

As you may know, another pull request for a Adafruit_TSL2561 module was submitted by Iain Colledge a couple days after you submitted this one. He announced it on this thread on the Adafruit forum:

https://forums.adafruit.com/viewtopic.php?f=8&t=34922&p=430913#p430913

His is a very direct port of the Adafruit Arduino code which uses the integer math from the data sheet. I was looking for just such a thing, so I downloaded his module and tested it. After fixing a couple bugs, it works well. He mentioned your pull request, so I decided to download it and give it a try as well.

I found (and debugged) two bugs that need to be fixed in your code:

Bug #1: Bytes are swapped in 16-bit data from CHAN0 and CHAN1

    In the _getData method, the I2C reverseByteOrder method is
    called on the values read with readU16. I've seen this in other
    versions of this code, but in my testing it clearly appears to
    be wrong. I slowly moved my light source closer and closer to
    the sensor. Without the byte swap the values smoothly increase
    in the lower byte first, and then the upper byte starts
    increasing.

Bug #2: The gain is applied incorrectly in the scaling for the lux calculation

    The following line is wrong:

    chscale = self._integrationTime.scale * self.gain

    When the gain is set to 1, the value must be multiplied by
    16. And when the gain is set to 16, the value is used
    as-is. This sounds backwards, but it is correct. The line above
    should be changed to something like:

    if self.gain == 1:
        chscale = self._integrationTime.scale * 16
    else:
        chscale = self._integrationTime.scale

    Near the top of p. 26 in the data sheet there is the following
    code:

    // scale if gain is NOT 16X
    if (!iGain) chScale = chScale << 4; // scale 1X to 16X

There is also a problem (possibly in my set up? python version?) that causes the following error when the sensor saturation exception is raised:

    line 22, in __init__
        self.msg('Channel {0} is saturated.'.format(channel))
    AttributeError: 'SensorSaturatedException' object has no attribute 'msg'

Thanks!

asciipip commented 8 years ago

What's extra coincidental about the timing is that I wrote this module a couple of years ago and just recently decided that I ought to polish up the documentation and send a pull request.

I think I've fixed up all of the problems you pointed out. (In particular, I got the channel scaling pretty much completely backwards, which explains why 16x mode always looked weird to me. It should be right now; I get consistent results when switching between modes, at least. I don't have any other light sensors to compare my readings to, though.)

Also in here are some improvements to the use of the contents of the ID register. My original code was copied from the Arduino code (which looks a little off now; instead of if (x & 0x0A ), I think it probably at least ought to be if (x & 0x0F == 0x0A)); the new stuff is an improvement, I think.

ladyada commented 4 years ago

Thank you for the Pull Request This library has been deprecated in favor of our python3 Blinka library. We have replaced all of the libraries that use this repo with CircuitPython libraries that are Python3 compatible, and support a wide variety of single board/linux computers!

Visit https://circuitpython.org/blinka for more information

CircuitPython has support for almost 200 different drivers, and a as well as FT232H support for Mac/Win/Linux!