Skip to content

Commit a73ee78

Browse files
authored
Merge pull request #12 from pimoroni/patch-adc
Add support for breakout ADC channel
2 parents c44453f + 8c9d061 commit a73ee78

File tree

3 files changed

+129
-12
lines changed

3 files changed

+129
-12
lines changed

examples/adc.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env python
2+
3+
import time
4+
from enviroplus import gas
5+
6+
print("""adc.py - Print readings from the MICS6814 Gas sensor.
7+
8+
Press Ctrl+C to exit!
9+
10+
""")
11+
12+
gas.enable_adc()
13+
gas.set_adc_gain(4.096)
14+
15+
try:
16+
while True:
17+
readings = gas.read_all()
18+
print(readings)
19+
time.sleep(1.0)
20+
except KeyboardInterrupt:
21+
pass

library/enviroplus/gas.py

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
11
"""Read the MICS6814 via an ads1015 ADC"""
22

3+
import time
34
import atexit
45
import ads1015
56
import RPi.GPIO as GPIO
67

78
MICS6814_HEATER_PIN = 24
8-
9+
MICS6814_GAIN = 6.144
910

1011
ads1015.I2C_ADDRESS_DEFAULT = ads1015.I2C_ADDRESS_ALTERNATE
1112
_is_setup = False
13+
_adc_enabled = False
14+
_adc_gain = 6.148
1215

1316

1417
class Mics6814Reading(object):
15-
__slots__ = 'oxidising', 'reducing', 'nh3'
18+
__slots__ = 'oxidising', 'reducing', 'nh3', 'adc'
1619

17-
def __init__(self, ox, red, nh3):
20+
def __init__(self, ox, red, nh3, adc=None):
1821
self.oxidising = ox
1922
self.reducing = red
2023
self.nh3 = nh3
24+
self.adc = adc
2125

2226
def __repr__(self):
23-
return """Oxidising: {:05.02f} Ohms
24-
Reducing: {:05.02f} Ohms
25-
NH3: {:05.02f} Ohms
26-
""".format(self.oxidising, self.reducing, self.nh3)
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)
2739

2840
__str__ = __repr__
2941

@@ -36,7 +48,7 @@ def setup():
3648

3749
adc = ads1015.ADS1015(i2c_addr=0x49)
3850
adc.set_mode('single')
39-
adc.set_programmable_gain(6.148)
51+
adc.set_programmable_gain(MICS6814_GAIN)
4052
adc.set_sample_rate(1600)
4153

4254
GPIO.setwarnings(False)
@@ -46,6 +58,18 @@ def setup():
4658
atexit.register(cleanup)
4759

4860

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+
4973
def cleanup():
5074
GPIO.output(MICS6814_HEATER_PIN, 0)
5175

@@ -57,11 +81,33 @@ def read_all():
5781
red = adc.get_voltage('in1/gnd')
5882
nh3 = adc.get_voltage('in2/gnd')
5983

60-
ox = (ox * 56000) / (3.3 - ox)
61-
red = (red * 56000) / (3.3 - red)
62-
nh3 = (nh3 * 56000) / (3.3 - nh3)
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
6393

64-
return Mics6814Reading(ox, red, nh3)
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)
65111

66112

67113
def read_oxidising():
@@ -86,3 +132,9 @@ def read_nh3():
86132
"""Return gas resistance for nh3/ammonia"""
87133
setup()
88134
return read_all().nh3
135+
136+
137+
def read_adc():
138+
"""Return spare ADC channel value"""
139+
setup()
140+
return read_all().adc

library/tests/test_setup.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ def test_gas_setup():
1616
smbus.SMBus = SMBusFakeDevice
1717
sys.modules['smbus'] = smbus
1818
from enviroplus import gas
19+
gas._is_setup = False
1920
gas.setup()
2021
gas.setup()
2122

@@ -27,6 +28,7 @@ def test_gas_read_all():
2728
smbus.SMBus = SMBusFakeDevice
2829
sys.modules['smbus'] = smbus
2930
from enviroplus import gas
31+
gas._is_setup = False
3032
result = gas.read_all()
3133

3234
assert type(result.oxidising) == float
@@ -48,7 +50,49 @@ def test_gas_read_each():
4850
smbus.SMBus = SMBusFakeDevice
4951
sys.modules['smbus'] = smbus
5052
from enviroplus import gas
53+
gas._is_setup = False
5154

5255
assert int(gas.read_oxidising()) == 16641
5356
assert int(gas.read_reducing()) == 16727
5457
assert int(gas.read_nh3()) == 16813
58+
59+
60+
def test_gas_read_adc():
61+
sys.modules['RPi'] = mock.Mock()
62+
sys.modules['RPi.GPIO'] = mock.Mock()
63+
smbus = mock.Mock()
64+
smbus.SMBus = SMBusFakeDevice
65+
sys.modules['smbus'] = smbus
66+
from enviroplus import gas
67+
gas._is_setup = False
68+
69+
gas.enable_adc(True)
70+
gas.set_adc_gain(2.048)
71+
assert gas.read_adc() == 0.255
72+
73+
74+
def test_gas_read_adc_default_gain():
75+
sys.modules['RPi'] = mock.Mock()
76+
sys.modules['RPi.GPIO'] = mock.Mock()
77+
smbus = mock.Mock()
78+
smbus.SMBus = SMBusFakeDevice
79+
sys.modules['smbus'] = smbus
80+
from enviroplus import gas
81+
gas._is_setup = False
82+
83+
gas.enable_adc(True)
84+
assert gas.read_adc() == 0.255
85+
86+
87+
def test_gas_read_adc_str():
88+
sys.modules['RPi'] = mock.Mock()
89+
sys.modules['RPi.GPIO'] = mock.Mock()
90+
smbus = mock.Mock()
91+
smbus.SMBus = SMBusFakeDevice
92+
sys.modules['smbus'] = smbus
93+
from enviroplus import gas
94+
gas._is_setup = False
95+
96+
gas.enable_adc(True)
97+
gas.set_adc_gain(2.048)
98+
assert 'ADC' in str(gas.read_all())

0 commit comments

Comments
 (0)