Catch #61 with tests and fix
[EVA-2020-02-2.git] / library / enviroplus / gas.py
CommitLineData
dd7489f8 1"""Read the MICS6814 via an ads1015 ADC"""
4f8716dc 2
4b18dd3a 3import time
82b86ca6 4import atexit
4f8716dc
PH
5import ads1015
6import RPi.GPIO as GPIO
7
dd7489f8 8MICS6814_HEATER_PIN = 24
8c9d0615 9MICS6814_GAIN = 6.144
4f8716dc
PH
10
11ads1015.I2C_ADDRESS_DEFAULT = ads1015.I2C_ADDRESS_ALTERNATE
12_is_setup = False
4b18dd3a
PH
13_adc_enabled = False
14_adc_gain = 6.148
4f8716dc
PH
15
16
dd7489f8 17class Mics6814Reading(object):
4b18dd3a 18 __slots__ = 'oxidising', 'reducing', 'nh3', 'adc'
4f8716dc 19
4b18dd3a 20 def __init__(self, ox, red, nh3, adc=None):
4f8716dc
PH
21 self.oxidising = ox
22 self.reducing = red
23 self.nh3 = nh3
4b18dd3a 24 self.adc = adc
4f8716dc
PH
25
26 def __repr__(self):
4b18dd3a
PH
27 fmt = """Oxidising: {ox:05.02f} Ohms
28Reducing: {red:05.02f} Ohms
29NH3: {nh3:05.02f} Ohms"""
30 if self.adc is not None:
31 fmt += """
32ADC: {adc:05.02f} Volts
33"""
34 return fmt.format(
35 ox=self.oxidising,
36 red=self.reducing,
37 nh3=self.nh3,
38 adc=self.adc)
4f8716dc
PH
39
40 __str__ = __repr__
41
42
43def setup():
44 global adc, _is_setup
45 if _is_setup:
46 return
47 _is_setup = True
48
49 adc = ads1015.ADS1015(i2c_addr=0x49)
50 adc.set_mode('single')
4b18dd3a 51 adc.set_programmable_gain(MICS6814_GAIN)
4f8716dc
PH
52 adc.set_sample_rate(1600)
53
54 GPIO.setwarnings(False)
55 GPIO.setmode(GPIO.BCM)
dd7489f8
SM
56 GPIO.setup(MICS6814_HEATER_PIN, GPIO.OUT)
57 GPIO.output(MICS6814_HEATER_PIN, 1)
82b86ca6
PH
58 atexit.register(cleanup)
59
60
4b18dd3a
PH
61def enable_adc(value=True):
62 """Enable reading from the additional ADC pin."""
63 global _adc_enabled
64 _adc_enabled = value
65
66
67def set_adc_gain(value):
68 """Set gain value for the additional ADC pin."""
69 global _adc_gain
70 _adc_gain = value
71
72
82b86ca6 73def cleanup():
dd7489f8 74 GPIO.output(MICS6814_HEATER_PIN, 0)
4f8716dc
PH
75
76
77def read_all():
82b86ca6
PH
78 """Return gas resistence for oxidising, reducing and NH3"""
79 setup()
4f8716dc
PH
80 ox = adc.get_voltage('in0/gnd')
81 red = adc.get_voltage('in1/gnd')
82 nh3 = adc.get_voltage('in2/gnd')
83
4b18dd3a
PH
84 try:
85 ox = (ox * 56000) / (3.3 - ox)
86 except ZeroDivisionError:
87 ox = 0
88
89 try:
90 red = (red * 56000) / (3.3 - red)
91 except ZeroDivisionError:
92 red = 0
93
94 try:
95 nh3 = (nh3 * 56000) / (3.3 - nh3)
96 except ZeroDivisionError:
97 nh3 = 0
98
99 analog = None
100
101 if _adc_enabled:
102 if _adc_gain == MICS6814_GAIN:
103 analog = adc.get_voltage('ref/gnd')
104 else:
105 adc.set_programmable_gain(_adc_gain)
106 time.sleep(0.05)
107 analog = adc.get_voltage('ref/gnd')
108 adc.set_programmable_gain(MICS6814_GAIN)
109
110 return Mics6814Reading(ox, red, nh3, analog)
4f8716dc
PH
111
112
113def read_oxidising():
114 """Return gas resistance for oxidising gases.
115
116 Eg chlorine, nitrous oxide
117 """
118 setup()
119 return read_all().oxidising
120
121
122def read_reducing():
123 """Return gas resistance for reducing gases.
124
125 Eg hydrogen, carbon monoxide
126 """
127 setup()
128 return read_all().reducing
129
130
131def read_nh3():
132 """Return gas resistance for nh3/ammonia"""
133 setup()
134 return read_all().nh3
8c9d0615
PH
135
136
137def read_adc():
138 """Return spare ADC channel value"""
139 setup()
140 return read_all().adc