-
Notifications
You must be signed in to change notification settings - Fork 174
/
gas.py
140 lines (104 loc) · 2.92 KB
/
gas.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"""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', 'adc'
def __init__(self, ox, red, nh3, adc=None):
self.oxidising = ox
self.reducing = red
self.nh3 = nh3
self.adc = adc
def __repr__(self):
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__
def setup():
global adc, _is_setup
if _is_setup:
return
_is_setup = True
adc = ads1015.ADS1015(i2c_addr=0x49)
adc.set_mode('single')
adc.set_programmable_gain(MICS6814_GAIN)
adc.set_sample_rate(1600)
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(MICS6814_HEATER_PIN, GPIO.OUT)
GPIO.output(MICS6814_HEATER_PIN, 1)
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)
def read_all():
"""Return gas resistence for oxidising, reducing and NH3"""
setup()
ox = adc.get_voltage('in0/gnd')
red = adc.get_voltage('in1/gnd')
nh3 = adc.get_voltage('in2/gnd')
try:
ox = (ox * 56000) / (3.3 - ox)
except ZeroDivisionError:
ox = 0
try:
red = (red * 56000) / (3.3 - red)
except ZeroDivisionError:
red = 0
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 oxidising gases.
Eg chlorine, nitrous oxide
"""
setup()
return read_all().oxidising
def read_reducing():
"""Return gas resistance for reducing gases.
Eg hydrogen, carbon monoxide
"""
setup()
return read_all().reducing
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