diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/README.md b/README.md index 910077c..4330f35 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,18 @@ + # python-veml6070 -A python library for accessing the VEML6070 digital UV light sensor from Vishay + +A Python library for accessing the [VEML6070 digital UV light sensor](http://www.vishay.com/docs/84277/veml6070.pdf) from Vishay via `python-smbus` using the I2C interface. + +Default settings are suitable for Raspberry Pi 2 and 3 and was successfully tested using a [breakout](https://github.com/watterott/VEML6070-Breakout). + +I created this Python library in style of e.g. [python-tsl2591](https://github.com/maxlklaxl/python-tsl2591) (of the TSL2591 light sensor) since I found either [python code](https://github.com/ControlEverythingCommunity/VEML6070) broken for my hardware or [code targeted at Arduino](https://github.com/kriswiner/VEML6070). + +## Usage + +Consult the data sheet and see [demo.py](demo.py) for clues how to use this library. + +Not all functions of the chip are supported, especially not the interrupt handling since I had no use for this. Please send pull requests for improvements and bug fixes! + +## License + +Python files in this repository are released under the [MIT license](LICENSE). diff --git a/demo.py b/demo.py new file mode 100644 index 0000000..3b82c49 --- /dev/null +++ b/demo.py @@ -0,0 +1,13 @@ + +import veml6070 + +if __name__ == '__main__': + veml = veml6070.Veml6070() + for i in [veml6070.INTEGRATIONTIME_1_2T, + veml6070.INTEGRATIONTIME_1T, + veml6070.INTEGRATIONTIME_2T, + veml6070.INTEGRATIONTIME_4T]: + veml.set_integration_time(i) + uv_raw = veml.get_uva_light_intensity_raw() + uv = veml.get_uva_light_intensity() + print "Integration Time setting %d: %f W/(m*m) from raw value %d" % (i, uv, uv_raw) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..ae35a21 --- /dev/null +++ b/setup.py @@ -0,0 +1,11 @@ +from setuptools import setup + +setup(name='veml6070', + version='1.0', + url='http://github.com/cmur2/python-veml6070', + author='Christian Nicolai', + description=' A python library for accessing the VEML6070 digital UV light sensor from Vishay.', + packages=['veml6070'], + long_description=open('README.md').read(), + requires=['python (>= 2.7)', 'smbus (>= 0.4.1)'], + install_requires=['smbus-cffi']) \ No newline at end of file diff --git a/veml6070/__init__.py b/veml6070/__init__.py new file mode 100644 index 0000000..a3be6f3 --- /dev/null +++ b/veml6070/__init__.py @@ -0,0 +1,3 @@ + +from veml6070 import Veml6070 +from veml6070 import INTEGRATIONTIME_1_2T, INTEGRATIONTIME_1T, INTEGRATIONTIME_2T, INTEGRATIONTIME_4T, RSET_240K, RSET_270K, RSET_300K, RSET_600K diff --git a/veml6070/veml6070.py b/veml6070/veml6070.py new file mode 100644 index 0000000..7e98a3a --- /dev/null +++ b/veml6070/veml6070.py @@ -0,0 +1,104 @@ + +import smbus +import time + +ADDR_L=0x38 # 7bit address of the VEML6070 (write, read) +ADDR_H=0x39 # 7bit address of the VEML6070 (read) + +RSET_240K=240000 +RSET_270K=270000 +RSET_300K=300000 +RSET_600K=600000 + +SHUTDOWN_DISABLE=0x00 +SHUTDOWN_ENABLE=0x01 + +INTEGRATIONTIME_1_2T=0x00 +INTEGRATIONTIME_1T=0x01 +INTEGRATIONTIME_2T=0x02 +INTEGRATIONTIME_4T=0x03 + +class Veml6070: + + def __init__(self, i2c_bus=1, sensor_address=ADDR_L, rset=RSET_270K, integration_time=INTEGRATIONTIME_1T): + self.bus = smbus.SMBus(i2c_bus) + self.sendor_address = sensor_address + self.rset = rset + self.shutdown = SHUTDOWN_DISABLE # before set_integration_time() + self.set_integration_time(integration_time) + self.disable() + + def set_integration_time(self, integration_time): + self.integration_time = integration_time + self.bus.write_byte(self.sendor_address, self.get_command_byte()) + # constant offset determined experimentally to allow sensor to readjust + time.sleep(0.2) + + def get_integration_time(self): + return self.integration_time + + def enable(self): + self.shutdown = SHUTDOWN_DISABLE + self.bus.write_byte(self.sendor_address, self.get_command_byte()) + + def disable(self): + self.shutdown = SHUTDOWN_ENABLE + self.bus.write_byte(self.sendor_address, self.get_command_byte()) + + def get_uva_light_intensity_raw(self): + self.enable() + # wait two times the refresh time to allow completion of a previous cycle with old settings (worst case) + time.sleep(self.get_refresh_time()*2) + msb = self.bus.read_byte(self.sendor_address+(ADDR_H-ADDR_L)) + lsb = self.bus.read_byte(self.sendor_address) + self.disable() + return (msb << 8) | lsb + + def get_uva_light_intensity(self): + uv = self.get_uva_light_intensity_raw() + return uv * self.get_uva_light_sensitivity() + + def get_command_byte(self): + """ + assembles the command byte for the current state + """ + cmd = (self.shutdown & 0x01) << 0 # SD + cmd = (self.integration_time & 0x03) << 2 # IT + cmd = ((cmd | 0x02) & 0x3F) # reserved bits + return cmd + + def get_refresh_time(self): + """ + returns time needed to perform a complete measurement using current settings (in s) + """ + case_refresh_rset = { + RSET_240K: 0.1, + RSET_270K: 0.1125, + RSET_300K: 0.125, + RSET_600K: 0.25 + } + case_refresh_it = { + INTEGRATIONTIME_1_2T: 0.5, + INTEGRATIONTIME_1T: 1, + INTEGRATIONTIME_2T: 2, + INTEGRATIONTIME_4T: 4 + } + return case_refresh_rset[self.rset] * case_refresh_it[self.integration_time] + + def get_uva_light_sensitivity(self): + """ + returns UVA light sensitivity in W/(m*m)/step + """ + case_sens_rset = { + RSET_240K: 0.05, + RSET_270K: 0.05625, + RSET_300K: 0.0625, + RSET_600K: 0.125 + } + case_sens_it = { + INTEGRATIONTIME_1_2T: 0.5, + INTEGRATIONTIME_1T: 1, + INTEGRATIONTIME_2T: 2, + INTEGRATIONTIME_4T: 4 + } + return case_sens_rset[self.rset] / case_sens_it[self.integration_time]