From 6b2e7f3129e915ae5c1549064f810456cf6d3e8b Mon Sep 17 00:00:00 2001 From: d3m1g0d Date: Sun, 3 Mar 2019 20:21:08 +0100 Subject: [PATCH] Added UV sensor code. Calculations may be inaccurate. --- backend/sensors.py | 83 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/backend/sensors.py b/backend/sensors.py index d77b0d0..c6f6263 100644 --- a/backend/sensors.py +++ b/backend/sensors.py @@ -133,14 +133,14 @@ class LxMeter: temp = self.bus.read_byte_data(self.addr, 0xa1) self.bus.write_byte_data(self.addr, 0xa1, (temp & 0xfc) | time) except: - raise Exception('An error occured setting lux integration time') + raise Exception('An exception occured setting lux integration time') def getIntTime(self): '''Get the lux sensor integration time.''' try: return self.bus.read_byte_data(self.addr, 0xa1) & 0x03 except: - raise Exception('An error occured getting lux integration time') + raise Exception('An exception occured getting lux integration time') def getData(self): '''return the calculated lux value''' @@ -148,16 +148,85 @@ class LxMeter: chA = self.bus.read_word_data(self.addr, 0xac) chB = self.bus.read_word_data(self.addr, 0xae) except: - raise Exception('An error occured fetching lux channels') + raise Exception('An exception occured fetching lux channels') + # scary computations ahead! refer to the apds-9301 datasheet! if chB/chA <= 0.5 and chB/chA > 0: - lux = (0.0304*chA) - (0.062*chA*((chB/chA)**1.4)) + lux = 0.0304*chA - 0.062*chA*(chB/chA)**1.4 elif chB/chA <= 0.61 and chB/chA > 0.5: - lux = (0.0224*chA) - (0.031*chB) + lux = 0.0224*chA - 0.031*chB elif chB/chA <=0.8 and chB/chA > 0.61: - lux = (0.0128*chA) - (0.0153*chB) + lux = 0.0128*chA - 0.0153*chB elif chB/chA <=1.3 and chB/chA >0.8: - lux = (0.00146*chA) - (0.00112*chB) + lux = 0.00146*chA - 0.00112*chB else: lux = 0 return lux + +class UVSensor: + def __init__(self, bus=1, addr=0x10): + try: + self.bus = smbus2.SMBus(bus) + except: + raise Exception('An exception occured opening SMBus {}'.format(bus)) + + try: + # enable the sensor and set the integration time + self.bus.write_byte_data(addr, 0x00, 0b00010000) + except: + raise Exception('An exception occured when initalizing the UV Sensor') + + def getABI(self): + '''Calculates the UVA and UVB irradiances, + along with UV index. Returns [a,b,i]''' + + try: + # read the raw UVA, UVB and compensation values from the sensor + aRaw = self.bus.read_word_data(addr, 0x07) + bRaw = self.bus.read_word_data(addr, 0x09) + c1 = self.bus.read_word_data(addr, 0x0a) + c2 = self.bus.read_word_data(addr, 0x0b) + except: + raise Exception('An exception occured when fetching raw UV data') + # scary computations ahead! refer to Vishay app note 84339 and Sparkfun + # VEML6075 documentation. + + # first, compensate for visible and IR noise + aCorr = aRaw - 2.22 * c1 - 1.33 * c2 + bCorr = bRaw - 2.95 * c1 - 1.74 * c2 + + # second, convert values into irradiances + a = aCorr * 0.00110 + b = bCorr * 0.00125 + + # last, calculate the UV index + i = (uva + uvb) / 2 + + return [a,b,i] + + def getA(self): + return self.getABI()[0] + + def getB(self): + return self.getABI()[1] + + def getI(self): + return self.getABI()[2] + + def on(self): + '''Turns the UV sensor on after shutdown.''' + try: + # write the default value for power on + # no configurable params = no bitmask + self.bus.write_byte_data(addr, 0x00, 0x10) + except: + raise Exception('An exception occured when turning the UV sensor on') + + def off(self): + '''Shuts the UV sensor down.''' + try: + # write the default value + the shutdown bit + # no configurable params = no bitmask + self.bus.write_byte_data(addr, 0x00, 0x11) + except: + raise Exception('An exception occured when shutting the UV sensor down')