Skip to content

Wait for conversions in continuous example #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jan 5, 2021
14 changes: 12 additions & 2 deletions adafruit_ads1x15/ads1x15.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,16 @@ def _conversion_value(self, raw_adc):

def _read(self, pin):
"""Perform an ADC read. Returns the signed integer result of the read."""
# Immediately return conversion register result if in CONTINUOUS mode
# and pin has not changed
if self.mode == Mode.CONTINUOUS and self._last_pin_read == pin:
return self._conversion_value(self.get_last_result(True))

# Assign last pin read if in SINGLE mode or first sample in CONTINUOUS mode on this pin
self._last_pin_read = pin

# Configure ADC every time before a conversion in SINGLE mode
# or changing channels in CONTINUOUS mode
if self.mode == Mode.SINGLE:
config = _ADS1X15_CONFIG_OS_SINGLE
else:
Expand All @@ -171,12 +178,15 @@ def _read(self, pin):
config |= _ADS1X15_CONFIG_COMP_QUE_DISABLE
self._write_register(_ADS1X15_POINTER_CONFIG, config)

# Wait for conversion to complete
# ADS1x1x devices settle within a single conversion cycle
if self.mode == Mode.SINGLE:
# poll conversion complete status bit
# Continuously poll conversion complete status bit
while not self._conversion_complete():
pass
else:
# just sleep (can't poll in continuous)
# Can't poll registers in CONTINUOUS mode
# Wait expected time for two conversions to complete
time.sleep(2 / self.data_rate)

return self._conversion_value(self.get_last_result(False))
Expand Down
34 changes: 32 additions & 2 deletions examples/ads1x15_fast_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
SAMPLES = 1000

# Create the I2C bus with a fast frequency
# NOTE: Your device may not respect the frequency setting
# Raspberry Pis must change this in /boot/config.txt

i2c = busio.I2C(board.SCL, board.SDA, frequency=1000000)

# Create the ADC object using the I2C bus
Expand All @@ -22,16 +25,43 @@
ads.mode = Mode.CONTINUOUS
ads.data_rate = RATE

repeats = 0

data = [None] * SAMPLES

time_last_sample = time.monotonic()
start = time.monotonic()

# Read the same channel over and over
for i in range(SAMPLES):
# Wait for expected conversion finish time
while time.monotonic() < (time_last_sample + (1.0 / ads.data_rate)):
pass

# Read conversion value for ADC channel
time_last_sample = time.monotonic()
data[i] = chan0.value

# Detect repeated values due to over polling
if data[i] == data[i - 1]:
repeats += 1

end = time.monotonic()
total_time = end - start

print("Time of capture: {}s".format(total_time))
print("Sample rate requested={} actual={}".format(RATE, SAMPLES / total_time))
rate_reported = SAMPLES / total_time
rate_actual = (SAMPLES - repeats) / total_time
# NOTE: leave input floating to pickup some random noise
# This cannot estimate conversion rates higher than polling rate

print("Took {:5.3f} s to acquire {:d} samples.".format(total_time, SAMPLES))
print("")
print("Configured:")
print(" Requested = {:5d} sps".format(RATE))
print(" Reported = {:5d} sps".format(ads.data_rate))
print("")
print("Actual:")
print(" Polling Rate = {:8.2f} sps".format(rate_reported))
print(" {:9.2%}".format(rate_reported / RATE))
print(" Repeats = {:5d}".format(repeats))
print(" Conversion Rate = {:8.2f} sps (estimated)".format(rate_actual))