"""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__
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)
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)
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():
"""Return gas resistance for nh3/ammonia"""
setup()
return read_all().nh3
+
+
+def read_adc():
+ """Return spare ADC channel value"""
+ setup()
+ return read_all().adc
smbus.SMBus = SMBusFakeDevice
sys.modules['smbus'] = smbus
from enviroplus import gas
+ gas._is_setup = False
gas.setup()
gas.setup()
smbus.SMBus = SMBusFakeDevice
sys.modules['smbus'] = smbus
from enviroplus import gas
+ gas._is_setup = False
result = gas.read_all()
assert type(result.oxidising) == float
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())