-
Notifications
You must be signed in to change notification settings - Fork 58
Add wait for conversion #12
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
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,6 @@ | |
__version__ = "0.0.0-auto.0" | ||
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15.git" | ||
|
||
import time | ||
from micropython import const | ||
from adafruit_bus_device.i2c_device import I2CDevice | ||
|
||
|
@@ -131,6 +130,23 @@ def __init__(self, i2c, address=ADS1X15_DEFAULT_ADDRESS): | |
ADC_Channel(self, 2), | ||
ADC_Channel(self, 3)] | ||
|
||
def _write_register(self, reg, value): | ||
"""Write 16 bit value to register.""" | ||
self.buf[0] = reg | ||
self.buf[1] = (value >> 8) & 0xFF | ||
self.buf[2] = value & 0xFF | ||
with self.i2c_device as i2c: | ||
i2c.write(self.buf) | ||
|
||
def _read_register(self, reg): | ||
"""Return 16 bit register value as tuple of (LSB, MSB).""" | ||
self.buf[0] = reg | ||
with self.i2c_device as i2c: | ||
i2c.write(self.buf, end=1, stop=False) | ||
i2c.readinto(self.buf, start=1) | ||
# LSB MSB | ||
return self.buf[2], self.buf[1] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is only used in one place, does it really make sense to have it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yah, I was wondering about the tuple also. Basically it's just left over from first version of code. I was thinking of changing to just passing back an int. I'll take a look, I'm not sure why I can't just go ahead and do that. I think having the function makes sense for any future expansion of functionality - it'll be the generic register read for whatever. |
||
|
||
def _data_rate_default(self): | ||
"""Retrieve the default data rate for this ADC (in samples per second). | ||
Should be implemented by subclasses. | ||
|
@@ -164,6 +180,13 @@ def _read_channel_volts(self, channel): | |
""" | ||
raise NotImplementedError('Subclass must implement _read_channel_volts function!') | ||
|
||
def _conversion_complete(self): | ||
"""Return status of ADC conversion.""" | ||
# OS is bit 15 | ||
# OS = 0: Device is currently performing a conversion | ||
# OS = 1: Device is not currently performing a conversion | ||
return self._read_register(ADS1X15_POINTER_CONFIG)[1] & 0x80 | ||
|
||
def _read(self, mux, gain, data_rate, mode): | ||
"""Perform an ADC read with the provided mux, gain, data_rate, and mode | ||
values. Returns the signed integer result of the read. | ||
|
@@ -186,40 +209,24 @@ def _read(self, mux, gain, data_rate, mode): | |
config |= self._data_rate_config(data_rate) | ||
config |= ADS1X15_CONFIG_COMP_QUE_DISABLE # Disble comparator mode. | ||
# Send the config value to start the ADC conversion. | ||
# Explicitly break the 16-bit value down to a big endian pair of bytes. | ||
self.buf[0] = ADS1X15_POINTER_CONFIG | ||
self.buf[1] = (config >> 8) & 0xFF | ||
self.buf[2] = config & 0xFF | ||
with self.i2c_device as i2c: | ||
i2c.write(self.buf) | ||
# Wait for the ADC sample to finish based on the sample rate plus a | ||
# small offset to be sure (0.1 millisecond). | ||
time.sleep(1.0/data_rate+0.0001) | ||
# Retrieve the result. | ||
self.buf[0] = ADS1X15_POINTER_CONVERSION | ||
i2c.write(self.buf, end=1, stop=False) | ||
i2c.readinto(self.buf, start=1) | ||
return self._conversion_value(self.buf[2], self.buf[1]) | ||
self._write_register(ADS1X15_POINTER_CONFIG, config) | ||
# Wait for conversion to complete | ||
while not self._conversion_complete(): | ||
pass | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wouldn't be better to have time.sleep() instead of pass? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the reason? Easy enough to do, just curious what the trade off is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose it's a good practice from regular Python, where you want to give the control back to the operating system and other applications, instead of running it at 100%. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha. I figured time.sleep(0) |
||
# Return the result | ||
return self.get_last_result() | ||
|
||
def stop_adc(self): | ||
"""Stop all continuous ADC conversions (either normal or difference mode). | ||
""" | ||
# Set the config register to its default value of 0x8583 to stop | ||
# continuous conversions. | ||
self.buf[0] = ADS1X15_POINTER_CONFIG | ||
self.buf[1] = 0x85 | ||
self.buf[2] = 0x83 | ||
with self.i2c_device as i2c: | ||
i2c.write(self.buf) | ||
self._write_register(ADS1X15_POINTER_CONFIG, 0x8583) | ||
|
||
def get_last_result(self): | ||
"""Read the last conversion result when in continuous conversion mode. | ||
Will return a signed integer value. | ||
""" | ||
# Retrieve the conversion register value, convert to a signed int, and | ||
# return it. | ||
self.buf[0] = ADS1X15_POINTER_CONVERSION | ||
with self.i2c_device as i2c: | ||
i2c.write(self.buf, end=1, stop=False) | ||
i2c.readinto(self.buf, start=1) | ||
return self._conversion_value(self.buf[2], self.buf[1]) | ||
return self._conversion_value(*self._read_register(ADS1X15_POINTER_CONVERSION)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason for not using Adafruit_CircuitPython_Register?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just haven't used it yet. I'll take a look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deferring this to a future PR.