Commit | Line | Data |
---|---|---|
dd7489f8 | 1 | """Read the MICS6814 via an ads1015 ADC""" |
4f8716dc | 2 | |
4b18dd3a | 3 | import time |
82b86ca6 | 4 | import atexit |
4f8716dc PH |
5 | import ads1015 |
6 | import RPi.GPIO as GPIO | |
7 | ||
dd7489f8 | 8 | MICS6814_HEATER_PIN = 24 |
4b18dd3a | 9 | MICS6814_GAIN = 6.148 |
4f8716dc PH |
10 | |
11 | ads1015.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 | 17 | class 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 |
28 | Reducing: {red:05.02f} Ohms | |
29 | NH3: {nh3:05.02f} Ohms""" | |
30 | if self.adc is not None: | |
31 | fmt += """ | |
32 | ADC: {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 | ||
43 | def 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 |
61 | def enable_adc(value=True): |
62 | """Enable reading from the additional ADC pin.""" | |
63 | global _adc_enabled | |
64 | _adc_enabled = value | |
65 | ||
66 | ||
67 | def set_adc_gain(value): | |
68 | """Set gain value for the additional ADC pin.""" | |
69 | global _adc_gain | |
70 | _adc_gain = value | |
71 | ||
72 | ||
82b86ca6 | 73 | def cleanup(): |
dd7489f8 | 74 | GPIO.output(MICS6814_HEATER_PIN, 0) |
4f8716dc PH |
75 | |
76 | ||
77 | def 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 | ||
113 | def 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 | ||
122 | def 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 | ||
131 | def read_nh3(): | |
132 | """Return gas resistance for nh3/ammonia""" | |
133 | setup() | |
134 | return read_all().nh3 |