From: Philip Howard Date: Wed, 17 Jul 2019 12:21:26 +0000 (+0100) Subject: Merge pull request #12 from pimoroni/patch-adc X-Git-Url: https://zdv2.bktei.com/gitweb/EVA-2020-02-2.git/commitdiff_plain/a73ee7811dc8302651b4a2eb324431ff5dd4ea1e?hp=c44453f6712b1dbdd47339d1b6a4f6d5f690c772 Merge pull request #12 from pimoroni/patch-adc Add support for breakout ADC channel --- diff --git a/examples/adc.py b/examples/adc.py new file mode 100755 index 0000000..c4cf45c --- /dev/null +++ b/examples/adc.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +import time +from enviroplus import gas + +print("""adc.py - Print readings from the MICS6814 Gas sensor. + +Press Ctrl+C to exit! + +""") + +gas.enable_adc() +gas.set_adc_gain(4.096) + +try: + while True: + readings = gas.read_all() + print(readings) + time.sleep(1.0) +except KeyboardInterrupt: + pass diff --git a/library/enviroplus/gas.py b/library/enviroplus/gas.py index ee1ad80..584317b 100644 --- a/library/enviroplus/gas.py +++ b/library/enviroplus/gas.py @@ -1,29 +1,41 @@ """Read the MICS6814 via an ads1015 ADC""" +import time import atexit import ads1015 import RPi.GPIO as GPIO MICS6814_HEATER_PIN = 24 - +MICS6814_GAIN = 6.144 ads1015.I2C_ADDRESS_DEFAULT = ads1015.I2C_ADDRESS_ALTERNATE _is_setup = False +_adc_enabled = False +_adc_gain = 6.148 class Mics6814Reading(object): - __slots__ = 'oxidising', 'reducing', 'nh3' + __slots__ = 'oxidising', 'reducing', 'nh3', 'adc' - def __init__(self, ox, red, nh3): + def __init__(self, ox, red, nh3, adc=None): self.oxidising = ox self.reducing = red self.nh3 = nh3 + self.adc = adc def __repr__(self): - return """Oxidising: {:05.02f} Ohms -Reducing: {:05.02f} Ohms -NH3: {:05.02f} Ohms -""".format(self.oxidising, self.reducing, self.nh3) + fmt = """Oxidising: {ox:05.02f} Ohms +Reducing: {red:05.02f} Ohms +NH3: {nh3:05.02f} Ohms""" + if self.adc is not None: + fmt += """ +ADC: {adc:05.02f} Volts +""" + return fmt.format( + ox=self.oxidising, + red=self.reducing, + nh3=self.nh3, + adc=self.adc) __str__ = __repr__ @@ -36,7 +48,7 @@ def setup(): adc = ads1015.ADS1015(i2c_addr=0x49) adc.set_mode('single') - adc.set_programmable_gain(6.148) + adc.set_programmable_gain(MICS6814_GAIN) adc.set_sample_rate(1600) GPIO.setwarnings(False) @@ -46,6 +58,18 @@ def setup(): atexit.register(cleanup) +def enable_adc(value=True): + """Enable reading from the additional ADC pin.""" + global _adc_enabled + _adc_enabled = value + + +def set_adc_gain(value): + """Set gain value for the additional ADC pin.""" + global _adc_gain + _adc_gain = value + + def cleanup(): GPIO.output(MICS6814_HEATER_PIN, 0) @@ -57,11 +81,33 @@ def read_all(): red = adc.get_voltage('in1/gnd') nh3 = adc.get_voltage('in2/gnd') - ox = (ox * 56000) / (3.3 - ox) - red = (red * 56000) / (3.3 - red) - nh3 = (nh3 * 56000) / (3.3 - nh3) + try: + ox = (ox * 56000) / (3.3 - ox) + except ZeroDivisionError: + ox = 0 + + try: + red = (red * 56000) / (3.3 - red) + except ZeroDivisionError: + red = 0 - return Mics6814Reading(ox, red, nh3) + try: + nh3 = (nh3 * 56000) / (3.3 - nh3) + except ZeroDivisionError: + nh3 = 0 + + analog = None + + if _adc_enabled: + if _adc_gain == MICS6814_GAIN: + analog = adc.get_voltage('ref/gnd') + else: + adc.set_programmable_gain(_adc_gain) + time.sleep(0.05) + analog = adc.get_voltage('ref/gnd') + adc.set_programmable_gain(MICS6814_GAIN) + + return Mics6814Reading(ox, red, nh3, analog) def read_oxidising(): @@ -86,3 +132,9 @@ def read_nh3(): """Return gas resistance for nh3/ammonia""" setup() return read_all().nh3 + + +def read_adc(): + """Return spare ADC channel value""" + setup() + return read_all().adc diff --git a/library/tests/test_setup.py b/library/tests/test_setup.py index b912a37..7c25d94 100644 --- a/library/tests/test_setup.py +++ b/library/tests/test_setup.py @@ -16,6 +16,7 @@ def test_gas_setup(): smbus.SMBus = SMBusFakeDevice sys.modules['smbus'] = smbus from enviroplus import gas + gas._is_setup = False gas.setup() gas.setup() @@ -27,6 +28,7 @@ def test_gas_read_all(): smbus.SMBus = SMBusFakeDevice sys.modules['smbus'] = smbus from enviroplus import gas + gas._is_setup = False result = gas.read_all() assert type(result.oxidising) == float @@ -48,7 +50,49 @@ def test_gas_read_each(): smbus.SMBus = SMBusFakeDevice sys.modules['smbus'] = smbus from enviroplus import gas + gas._is_setup = False assert int(gas.read_oxidising()) == 16641 assert int(gas.read_reducing()) == 16727 assert int(gas.read_nh3()) == 16813 + + +def test_gas_read_adc(): + sys.modules['RPi'] = mock.Mock() + sys.modules['RPi.GPIO'] = mock.Mock() + smbus = mock.Mock() + smbus.SMBus = SMBusFakeDevice + sys.modules['smbus'] = smbus + from enviroplus import gas + gas._is_setup = False + + gas.enable_adc(True) + gas.set_adc_gain(2.048) + assert gas.read_adc() == 0.255 + + +def test_gas_read_adc_default_gain(): + sys.modules['RPi'] = mock.Mock() + sys.modules['RPi.GPIO'] = mock.Mock() + smbus = mock.Mock() + smbus.SMBus = SMBusFakeDevice + sys.modules['smbus'] = smbus + from enviroplus import gas + gas._is_setup = False + + gas.enable_adc(True) + assert gas.read_adc() == 0.255 + + +def test_gas_read_adc_str(): + sys.modules['RPi'] = mock.Mock() + sys.modules['RPi.GPIO'] = mock.Mock() + smbus = mock.Mock() + smbus.SMBus = SMBusFakeDevice + sys.modules['smbus'] = smbus + from enviroplus import gas + gas._is_setup = False + + gas.enable_adc(True) + gas.set_adc_gain(2.048) + assert 'ADC' in str(gas.read_all())