jupyterpidaq.Boards.PiGPIO.ADS1115

  1# Utility sampling routines for using the ADS1115 ADC RPI HAT.
  2# J. Gutow <gutow@uwosh.edu> Nov. 12, 2018
  3# license GPL V3 or greater
  4import time
  5import numpy as np
  6
  7import logging
  8
  9import Adafruit_PureIO.smbus as smbus
 10import Adafruit_ADS1x15
 11
 12from jupyterpidaq.Boards import Board
 13
 14logger = logging.getLogger(__name__)
 15
 16# Optimized for Pi 3B+
 17RATE = 475  # 475 Hz with oversampling best S/N on Pi 3B+ per unit time interval.
 18# TODO: a more sophisticated initialization, which determines the loop time
 19#  and optimal value for RATE.
 20
 21# other rates 8, 16, 32, 64, 128, 250, 475, 860 in Hz.
 22
 23def find_boards():
 24    """
 25    A routine like this must be implemented by all board packages.
 26
 27    :return: list of ADS1115 board objects (maximum of 4 boards)
 28    """
 29    POSS_ADDR = (0x48, 0x49, 0x4A, 0x4B)
 30    boards = []
 31    tmpmod = None
 32    try:
 33        I2Cbus = smbus.SMBus(1)
 34    except OSError:
 35        # no bus so there cannot be any boards.
 36        return boards
 37    for addr in POSS_ADDR:
 38        try:
 39            I2Cbus.read_byte(addr)
 40        except OSError:
 41            continue
 42        try:
 43            tmpmod = Adafruit_ADS1x15.ADS1115(address=addr)            
 44        except RuntimeError as e:
 45            logger.debug(e)
 46            # print('No ADS1115 at: '+str(addr))
 47            tmpmod = None
 48        if tmpmod:
 49            boards.append(Board_ADS1115(tmpmod))
 50    return boards
 51
 52class Board_ADS1115(Board):
 53    """
 54    Class defining the properties of Adafruit compatible ADS1115
 55    analog-to-digital boards for Raspberry-Pi style GPIO. Key characteristics:
 56
 57    * 4 channels (0 - 3) with 16 bit resolution and a range of +/- 3.3 V
 58    * Programmable gain on each channel of 2/3, 1, 2, 4, 8, 16 making these
 59      good for small signals.
 60    * a differential mode is available but not implemented in this class.
 61    """
 62    def __init__(self,adc):
 63        super().__init__()
 64        self.name = 'ADS1115'
 65        self.vendor = '?' # Adafruit equivalent
 66        self.channels = (0, 1, 2, 3)
 67        self.gains = [2/3, 1, 2, 4, 8, 16]
 68        self.Vdd = 3.3
 69        self.adc = adc
 70
 71    def getsensors(self):
 72        """
 73        Return a list of valid sensor object names for this board.
 74        :return: list of classnames
 75        """
 76        sensorlist = ['RawAtoD', 'BuiltInThermistor', 'VernierSSTemp']
 77        # TODO: extend this list as appropriate. You can get a full list
 78        #  using the `Sensors.sensors.listSensors()` call.
 79        # The main program will use this list to access the actual sensor
 80        # objects when converting the raw board voltage and for producing
 81        # a menu of valid options for this particular board.
 82        return sensorlist
 83
 84    def V_oversampchan(self, chan, gain, avg_sec, data_rate=RATE):
 85        """
 86        This routine returns the average voltage for the channel
 87        averaged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec
 88        number of seconds. The 0.0012 is the required loop time
 89        on a RPI 3B+ in python.
 90
 91        Returns a tuple of the following 5 objects:
 92            V_avg -- float, the averaged voltage
 93
 94            V_min -- float, the minimum voltage read during
 95            the interval
 96
 97            V_max -- float, the maximum voltage read during the
 98            interval
 99
100            time_stamp -- float, the time at halfway through the averaging
101            interval in seconds since the beginning of the epoch (OS
102            dependent begin time)
103
104            self.Vdd -- float, the reference voltage.
105
106        :param int chan: the channel number (0, 1, 2, 3)
107
108        :param gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),
109         4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
110
111        :param int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,
112         128,250, 475 or 860 Hz). Set to 475 Hz by default.
113
114        :param float avg_sec: seconds to average for, actual
115         averaging interval will be as close as possible for an integer
116         number of samples
117
118        :returns: V_avg, V_min, V_max, time_stamp, self.Vdd
119        :return float V_avg: description
120        :return float V_min:
121        :return float V_max:
122        :return float time_stamp:
123        :return float self.Vdd:
124        """
125        n_samp = int(round(avg_sec / (0.0012 + 1 / data_rate)))
126        value = [0] * n_samp
127        avgmax = self.adc.read_adc(chan, gain=gain, data_rate=data_rate)
128        avgmin = avgmax
129        start = time.time()
130        # TODO: more error checking as in stats below
131        for k in range(n_samp):
132            value[k] = self.adc.read_adc(chan, gain=gain, data_rate=data_rate)
133        end = time.time()
134        time_stamp = (start + end) / 2
135        V_avg = sum(value) * 4.096 / n_samp / gain / 32767
136        V_min = min(value) * 4.096 / gain / 32767
137        V_max = max(value) * 4.096 / gain / 32767
138        return V_avg, V_min, V_max, time_stamp, self.Vdd
139
140
141    def V_oversampchan_stats(self, chan, gain, avg_sec, data_rate=RATE):
142        """
143        This routine returns the average voltage for the channel
144        averaged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec
145        number of seconds. The 0.0012 is the required loop time
146        on a RPI 3B+ in python3. The standard
147        deviation and the estimated deviation of the mean are also
148        returned.
149
150        Returns a tuple of the following 5 objects:
151            V_avg -- float, the averaged voltage
152
153            stdev -- float, the standard deviation of the measured values
154            during the averaging interval
155
156            stdev_avg -- float, the estimated standard deviation of the
157            returned average
158
159            time_stamp -- float, the time at halfway through the averaging
160            interval in seconds since the beginning of the epoch (OS
161            dependent begin time)
162
163            self.Vdd -- float, the reference voltage.
164
165        :param int chan: the channel number (0, 1, 2, 3)
166
167        :param gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),
168         4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
169
170        :param int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,
171         128,250, 475 or 860 Hz). Set to 475 Hz by default.
172
173        :param float avg_sec: seconds to average for, actual
174         averaging interval will be as close as possible for an integer
175         number of samples
176
177        :returns: VV_avg, stdev, stdev_avg, time_stamp, self.Vdd
178        :return float V_avg: description
179        :return float stdev:
180        :return float stdev_avg:
181        :return float time_stamp:
182        :return float self.Vdd:
183        """
184        n_samp = int(round(avg_sec / (0.0017 + 1 / data_rate)))
185        if (n_samp < 1):
186            n_samp = 1
187        value = []
188        start = 0
189        end = 0
190        while (len(
191                value) == 0):  # we will try until we get some values in case of bad reads
192            start = time.time()
193            for k in range(n_samp):
194                try:
195                    tempval = self.adc.read_adc(chan, gain=gain,
196                                            data_rate=data_rate)
197                except (ValueError, OverflowError):
198                    print('Bad adc read.')
199                    pass
200                else:
201                    if (tempval >= -32767) and (tempval <= 32767):
202                        value.append(tempval)
203                # time.sleep(0.0005)
204            end = time.time()
205        time_stamp = (start + end) / 2
206        V_avg = sum(value) * 4.096 / len(value) / gain / 32767
207        stdev = np.std(value, ddof=1, dtype=np.float64) * 4.096 / gain / 32767
208        stdev_avg = stdev / np.sqrt(float(len(value)))
209        return V_avg, stdev, stdev_avg, time_stamp, self.Vdd
210
211
212    def V_sampchan(self, chan, gain, data_rate=RATE):
213        """
214        This routine returns the voltage for the
215
216        Returns a tuple of the following 3 objects:
217            V -- float, the measured voltage
218
219            time_stamp -- float, the time at halfway through the averaging
220            interval in seconds since the beginning of the epoch (OS
221            dependent begin time)
222
223            self.Vdd -- float, the reference voltage.
224
225        :param int chan: the channel number (0, 1, 2, 3)
226
227        :param gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),
228         4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
229
230        :param int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,
231         128,250, 475 or 860 Hz). Set to 475 Hz by default.
232
233        :returns: V, time_stamp, self.Vdd
234        :return float V:
235        :return float time_stamp:
236        :return float self.Vdd:
237        """
238        start = time.time()
239        value = self.adc.read_adc(chan, gain=gain, data_rate=data_rate)
240        end = time.time()
241        time_stamp = (start + end) / 2
242        V = value * 4.096 / gain / 32767
243        return V, time_stamp, self.Vdd
def find_boards():
24def find_boards():
25    """
26    A routine like this must be implemented by all board packages.
27
28    :return: list of ADS1115 board objects (maximum of 4 boards)
29    """
30    POSS_ADDR = (0x48, 0x49, 0x4A, 0x4B)
31    boards = []
32    tmpmod = None
33    try:
34        I2Cbus = smbus.SMBus(1)
35    except OSError:
36        # no bus so there cannot be any boards.
37        return boards
38    for addr in POSS_ADDR:
39        try:
40            I2Cbus.read_byte(addr)
41        except OSError:
42            continue
43        try:
44            tmpmod = Adafruit_ADS1x15.ADS1115(address=addr)            
45        except RuntimeError as e:
46            logger.debug(e)
47            # print('No ADS1115 at: '+str(addr))
48            tmpmod = None
49        if tmpmod:
50            boards.append(Board_ADS1115(tmpmod))
51    return boards

A routine like this must be implemented by all board packages.

Returns

list of ADS1115 board objects (maximum of 4 boards)

class Board_ADS1115(jupyterpidaq.Boards.boards.Board):
 53class Board_ADS1115(Board):
 54    """
 55    Class defining the properties of Adafruit compatible ADS1115
 56    analog-to-digital boards for Raspberry-Pi style GPIO. Key characteristics:
 57
 58    * 4 channels (0 - 3) with 16 bit resolution and a range of +/- 3.3 V
 59    * Programmable gain on each channel of 2/3, 1, 2, 4, 8, 16 making these
 60      good for small signals.
 61    * a differential mode is available but not implemented in this class.
 62    """
 63    def __init__(self,adc):
 64        super().__init__()
 65        self.name = 'ADS1115'
 66        self.vendor = '?' # Adafruit equivalent
 67        self.channels = (0, 1, 2, 3)
 68        self.gains = [2/3, 1, 2, 4, 8, 16]
 69        self.Vdd = 3.3
 70        self.adc = adc
 71
 72    def getsensors(self):
 73        """
 74        Return a list of valid sensor object names for this board.
 75        :return: list of classnames
 76        """
 77        sensorlist = ['RawAtoD', 'BuiltInThermistor', 'VernierSSTemp']
 78        # TODO: extend this list as appropriate. You can get a full list
 79        #  using the `Sensors.sensors.listSensors()` call.
 80        # The main program will use this list to access the actual sensor
 81        # objects when converting the raw board voltage and for producing
 82        # a menu of valid options for this particular board.
 83        return sensorlist
 84
 85    def V_oversampchan(self, chan, gain, avg_sec, data_rate=RATE):
 86        """
 87        This routine returns the average voltage for the channel
 88        averaged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec
 89        number of seconds. The 0.0012 is the required loop time
 90        on a RPI 3B+ in python.
 91
 92        Returns a tuple of the following 5 objects:
 93            V_avg -- float, the averaged voltage
 94
 95            V_min -- float, the minimum voltage read during
 96            the interval
 97
 98            V_max -- float, the maximum voltage read during the
 99            interval
100
101            time_stamp -- float, the time at halfway through the averaging
102            interval in seconds since the beginning of the epoch (OS
103            dependent begin time)
104
105            self.Vdd -- float, the reference voltage.
106
107        :param int chan: the channel number (0, 1, 2, 3)
108
109        :param gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),
110         4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
111
112        :param int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,
113         128,250, 475 or 860 Hz). Set to 475 Hz by default.
114
115        :param float avg_sec: seconds to average for, actual
116         averaging interval will be as close as possible for an integer
117         number of samples
118
119        :returns: V_avg, V_min, V_max, time_stamp, self.Vdd
120        :return float V_avg: description
121        :return float V_min:
122        :return float V_max:
123        :return float time_stamp:
124        :return float self.Vdd:
125        """
126        n_samp = int(round(avg_sec / (0.0012 + 1 / data_rate)))
127        value = [0] * n_samp
128        avgmax = self.adc.read_adc(chan, gain=gain, data_rate=data_rate)
129        avgmin = avgmax
130        start = time.time()
131        # TODO: more error checking as in stats below
132        for k in range(n_samp):
133            value[k] = self.adc.read_adc(chan, gain=gain, data_rate=data_rate)
134        end = time.time()
135        time_stamp = (start + end) / 2
136        V_avg = sum(value) * 4.096 / n_samp / gain / 32767
137        V_min = min(value) * 4.096 / gain / 32767
138        V_max = max(value) * 4.096 / gain / 32767
139        return V_avg, V_min, V_max, time_stamp, self.Vdd
140
141
142    def V_oversampchan_stats(self, chan, gain, avg_sec, data_rate=RATE):
143        """
144        This routine returns the average voltage for the channel
145        averaged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec
146        number of seconds. The 0.0012 is the required loop time
147        on a RPI 3B+ in python3. The standard
148        deviation and the estimated deviation of the mean are also
149        returned.
150
151        Returns a tuple of the following 5 objects:
152            V_avg -- float, the averaged voltage
153
154            stdev -- float, the standard deviation of the measured values
155            during the averaging interval
156
157            stdev_avg -- float, the estimated standard deviation of the
158            returned average
159
160            time_stamp -- float, the time at halfway through the averaging
161            interval in seconds since the beginning of the epoch (OS
162            dependent begin time)
163
164            self.Vdd -- float, the reference voltage.
165
166        :param int chan: the channel number (0, 1, 2, 3)
167
168        :param gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),
169         4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
170
171        :param int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,
172         128,250, 475 or 860 Hz). Set to 475 Hz by default.
173
174        :param float avg_sec: seconds to average for, actual
175         averaging interval will be as close as possible for an integer
176         number of samples
177
178        :returns: VV_avg, stdev, stdev_avg, time_stamp, self.Vdd
179        :return float V_avg: description
180        :return float stdev:
181        :return float stdev_avg:
182        :return float time_stamp:
183        :return float self.Vdd:
184        """
185        n_samp = int(round(avg_sec / (0.0017 + 1 / data_rate)))
186        if (n_samp < 1):
187            n_samp = 1
188        value = []
189        start = 0
190        end = 0
191        while (len(
192                value) == 0):  # we will try until we get some values in case of bad reads
193            start = time.time()
194            for k in range(n_samp):
195                try:
196                    tempval = self.adc.read_adc(chan, gain=gain,
197                                            data_rate=data_rate)
198                except (ValueError, OverflowError):
199                    print('Bad adc read.')
200                    pass
201                else:
202                    if (tempval >= -32767) and (tempval <= 32767):
203                        value.append(tempval)
204                # time.sleep(0.0005)
205            end = time.time()
206        time_stamp = (start + end) / 2
207        V_avg = sum(value) * 4.096 / len(value) / gain / 32767
208        stdev = np.std(value, ddof=1, dtype=np.float64) * 4.096 / gain / 32767
209        stdev_avg = stdev / np.sqrt(float(len(value)))
210        return V_avg, stdev, stdev_avg, time_stamp, self.Vdd
211
212
213    def V_sampchan(self, chan, gain, data_rate=RATE):
214        """
215        This routine returns the voltage for the
216
217        Returns a tuple of the following 3 objects:
218            V -- float, the measured voltage
219
220            time_stamp -- float, the time at halfway through the averaging
221            interval in seconds since the beginning of the epoch (OS
222            dependent begin time)
223
224            self.Vdd -- float, the reference voltage.
225
226        :param int chan: the channel number (0, 1, 2, 3)
227
228        :param gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),
229         4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
230
231        :param int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,
232         128,250, 475 or 860 Hz). Set to 475 Hz by default.
233
234        :returns: V, time_stamp, self.Vdd
235        :return float V:
236        :return float time_stamp:
237        :return float self.Vdd:
238        """
239        start = time.time()
240        value = self.adc.read_adc(chan, gain=gain, data_rate=data_rate)
241        end = time.time()
242        time_stamp = (start + end) / 2
243        V = value * 4.096 / gain / 32767
244        return V, time_stamp, self.Vdd

Class defining the properties of Adafruit compatible ADS1115 analog-to-digital boards for Raspberry-Pi style GPIO. Key characteristics:

  • 4 channels (0 - 3) with 16 bit resolution and a range of +/- 3.3 V
  • Programmable gain on each channel of 2/3, 1, 2, 4, 8, 16 making these good for small signals.
  • a differential mode is available but not implemented in this class.
Board_ADS1115(adc)
63    def __init__(self,adc):
64        super().__init__()
65        self.name = 'ADS1115'
66        self.vendor = '?' # Adafruit equivalent
67        self.channels = (0, 1, 2, 3)
68        self.gains = [2/3, 1, 2, 4, 8, 16]
69        self.Vdd = 3.3
70        self.adc = adc

Should be overridden by each board and define at minimum: self.name = 'board name/adc name/type' Short an useful to end user self.vendor = 'Vendor/Manufacturer name` self.channels = tuple of available channel IDs self.gains = list of gains self.Vdd = voltage provided by board to sensors

def getsensors(self):
72    def getsensors(self):
73        """
74        Return a list of valid sensor object names for this board.
75        :return: list of classnames
76        """
77        sensorlist = ['RawAtoD', 'BuiltInThermistor', 'VernierSSTemp']
78        # TODO: extend this list as appropriate. You can get a full list
79        #  using the `Sensors.sensors.listSensors()` call.
80        # The main program will use this list to access the actual sensor
81        # objects when converting the raw board voltage and for producing
82        # a menu of valid options for this particular board.
83        return sensorlist

Return a list of valid sensor object names for this board.

Returns

list of classnames

def V_oversampchan(self, chan, gain, avg_sec, data_rate=475):
 85    def V_oversampchan(self, chan, gain, avg_sec, data_rate=RATE):
 86        """
 87        This routine returns the average voltage for the channel
 88        averaged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec
 89        number of seconds. The 0.0012 is the required loop time
 90        on a RPI 3B+ in python.
 91
 92        Returns a tuple of the following 5 objects:
 93            V_avg -- float, the averaged voltage
 94
 95            V_min -- float, the minimum voltage read during
 96            the interval
 97
 98            V_max -- float, the maximum voltage read during the
 99            interval
100
101            time_stamp -- float, the time at halfway through the averaging
102            interval in seconds since the beginning of the epoch (OS
103            dependent begin time)
104
105            self.Vdd -- float, the reference voltage.
106
107        :param int chan: the channel number (0, 1, 2, 3)
108
109        :param gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),
110         4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
111
112        :param int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,
113         128,250, 475 or 860 Hz). Set to 475 Hz by default.
114
115        :param float avg_sec: seconds to average for, actual
116         averaging interval will be as close as possible for an integer
117         number of samples
118
119        :returns: V_avg, V_min, V_max, time_stamp, self.Vdd
120        :return float V_avg: description
121        :return float V_min:
122        :return float V_max:
123        :return float time_stamp:
124        :return float self.Vdd:
125        """
126        n_samp = int(round(avg_sec / (0.0012 + 1 / data_rate)))
127        value = [0] * n_samp
128        avgmax = self.adc.read_adc(chan, gain=gain, data_rate=data_rate)
129        avgmin = avgmax
130        start = time.time()
131        # TODO: more error checking as in stats below
132        for k in range(n_samp):
133            value[k] = self.adc.read_adc(chan, gain=gain, data_rate=data_rate)
134        end = time.time()
135        time_stamp = (start + end) / 2
136        V_avg = sum(value) * 4.096 / n_samp / gain / 32767
137        V_min = min(value) * 4.096 / gain / 32767
138        V_max = max(value) * 4.096 / gain / 32767
139        return V_avg, V_min, V_max, time_stamp, self.Vdd

This routine returns the average voltage for the channel averaged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec number of seconds. The 0.0012 is the required loop time on a RPI 3B+ in python.

Returns a tuple of the following 5 objects: V_avg -- float, the averaged voltage

V_min -- float, the minimum voltage read during
the interval

V_max -- float, the maximum voltage read during the
interval

time_stamp -- float, the time at halfway through the averaging
interval in seconds since the beginning of the epoch (OS
dependent begin time)

self.Vdd -- float, the reference voltage.
Parameters
  • int chan: the channel number (0, 1, 2, 3)

  • gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))

  • int data_rate: the ADC sample rate in Hz (8, 16, 32, 64, 128,250, 475 or 860 Hz). Set to 475 Hz by default.

  • float avg_sec: seconds to average for, actual averaging interval will be as close as possible for an integer number of samples

:returns: V_avg, V_min, V_max, time_stamp, self.Vdd

Returns

description

Returns

Returns

Returns

Returns
def V_oversampchan_stats(self, chan, gain, avg_sec, data_rate=475):
142    def V_oversampchan_stats(self, chan, gain, avg_sec, data_rate=RATE):
143        """
144        This routine returns the average voltage for the channel
145        averaged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec
146        number of seconds. The 0.0012 is the required loop time
147        on a RPI 3B+ in python3. The standard
148        deviation and the estimated deviation of the mean are also
149        returned.
150
151        Returns a tuple of the following 5 objects:
152            V_avg -- float, the averaged voltage
153
154            stdev -- float, the standard deviation of the measured values
155            during the averaging interval
156
157            stdev_avg -- float, the estimated standard deviation of the
158            returned average
159
160            time_stamp -- float, the time at halfway through the averaging
161            interval in seconds since the beginning of the epoch (OS
162            dependent begin time)
163
164            self.Vdd -- float, the reference voltage.
165
166        :param int chan: the channel number (0, 1, 2, 3)
167
168        :param gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),
169         4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
170
171        :param int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,
172         128,250, 475 or 860 Hz). Set to 475 Hz by default.
173
174        :param float avg_sec: seconds to average for, actual
175         averaging interval will be as close as possible for an integer
176         number of samples
177
178        :returns: VV_avg, stdev, stdev_avg, time_stamp, self.Vdd
179        :return float V_avg: description
180        :return float stdev:
181        :return float stdev_avg:
182        :return float time_stamp:
183        :return float self.Vdd:
184        """
185        n_samp = int(round(avg_sec / (0.0017 + 1 / data_rate)))
186        if (n_samp < 1):
187            n_samp = 1
188        value = []
189        start = 0
190        end = 0
191        while (len(
192                value) == 0):  # we will try until we get some values in case of bad reads
193            start = time.time()
194            for k in range(n_samp):
195                try:
196                    tempval = self.adc.read_adc(chan, gain=gain,
197                                            data_rate=data_rate)
198                except (ValueError, OverflowError):
199                    print('Bad adc read.')
200                    pass
201                else:
202                    if (tempval >= -32767) and (tempval <= 32767):
203                        value.append(tempval)
204                # time.sleep(0.0005)
205            end = time.time()
206        time_stamp = (start + end) / 2
207        V_avg = sum(value) * 4.096 / len(value) / gain / 32767
208        stdev = np.std(value, ddof=1, dtype=np.float64) * 4.096 / gain / 32767
209        stdev_avg = stdev / np.sqrt(float(len(value)))
210        return V_avg, stdev, stdev_avg, time_stamp, self.Vdd

This routine returns the average voltage for the channel averaged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec number of seconds. The 0.0012 is the required loop time on a RPI 3B+ in python3. The standard deviation and the estimated deviation of the mean are also returned.

Returns a tuple of the following 5 objects: V_avg -- float, the averaged voltage

stdev -- float, the standard deviation of the measured values
during the averaging interval

stdev_avg -- float, the estimated standard deviation of the
returned average

time_stamp -- float, the time at halfway through the averaging
interval in seconds since the beginning of the epoch (OS
dependent begin time)

self.Vdd -- float, the reference voltage.
Parameters
  • int chan: the channel number (0, 1, 2, 3)

  • gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))

  • int data_rate: the ADC sample rate in Hz (8, 16, 32, 64, 128,250, 475 or 860 Hz). Set to 475 Hz by default.

  • float avg_sec: seconds to average for, actual averaging interval will be as close as possible for an integer number of samples

:returns: VV_avg, stdev, stdev_avg, time_stamp, self.Vdd

Returns

description

Returns

Returns

Returns

Returns
def V_sampchan(self, chan, gain, data_rate=475):
213    def V_sampchan(self, chan, gain, data_rate=RATE):
214        """
215        This routine returns the voltage for the
216
217        Returns a tuple of the following 3 objects:
218            V -- float, the measured voltage
219
220            time_stamp -- float, the time at halfway through the averaging
221            interval in seconds since the beginning of the epoch (OS
222            dependent begin time)
223
224            self.Vdd -- float, the reference voltage.
225
226        :param int chan: the channel number (0, 1, 2, 3)
227
228        :param gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),
229         4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
230
231        :param int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,
232         128,250, 475 or 860 Hz). Set to 475 Hz by default.
233
234        :returns: V, time_stamp, self.Vdd
235        :return float V:
236        :return float time_stamp:
237        :return float self.Vdd:
238        """
239        start = time.time()
240        value = self.adc.read_adc(chan, gain=gain, data_rate=data_rate)
241        end = time.time()
242        time_stamp = (start + end) / 2
243        V = value * 4.096 / gain / 32767
244        return V, time_stamp, self.Vdd

This routine returns the voltage for the

Returns a tuple of the following 3 objects: V -- float, the measured voltage

time_stamp -- float, the time at halfway through the averaging
interval in seconds since the beginning of the epoch (OS
dependent begin time)

self.Vdd -- float, the reference voltage.
Parameters
  • int chan: the channel number (0, 1, 2, 3)

  • gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))

  • int data_rate: the ADC sample rate in Hz (8, 16, 32, 64, 128,250, 475 or 860 Hz). Set to 475 Hz by default.

:returns: V, time_stamp, self.Vdd

Returns

Returns

Returns