Source code for PyExpLabSys.drivers.analogdevices_ad5667
"""Driver for the Analog Devices AD5667 2 channel analog output DAC
Implemented from the manual located `here
<http://www.analog.com/media/en/technical-documentation/data-sheets/AD5627R_5647R_5667R_
5627_5667.pdf>`__ and the examples located `here
<https://github.com/ControlEverythingCommunity/AD5667>`__.
"""
import time
import smbus
from PyExpLabSys.common.supported_versions import python3_only
python3_only(__file__)
[docs]class AD5667:
"""Driver for the Analog Devices AD5667 2 channel analog output DAC"""
[docs] def __init__(self, address=0x0E):
"""Initialize object properties"""
# Get I2C bus
self.bus = smbus.SMBus(1)
self.address = address
self.dac_and_input_register = {
'both': 0x1F,
'A': 0x18,
'B': 0x19,
}
self.last_write = 0
self.waittime = 0.1
def reset_device(self):
data = [0x00, 0xFF]
command = 0b00101000
self.bus.write_i2c_block_data(0x0C, command, data)
return True
[docs] def enable_onbaord_reference(self):
"""Enable on-board reference voltage, if no voltage reference is externally
given, the onboard must be enabled.
"""
data = [0x00, 0xFF]
command = 0b00111000
self.bus.write_i2c_block_data(0x0C, command, data)
return True
def power_up_or_down(self):
# Notice, default state is up, if you run this, device will turn off.
data = [0x00, 0xFF]
command = 0b00100000
self.bus.write_i2c_block_data(0x0C, command, data)
return True
[docs] def write_to_and_update_dac(self, dac, value):
"""Set a voltage value on the DAC
Args:
dac (str): The name of the DAC to set. 'A', 'B' or 'both'
value (float): A float between 0.0 and 5.0
Raises:
ValueError: On bad DAC name or bad value
"""
to_wait = self.waittime - (time.time() - self.last_write)
if to_wait > 0:
time.sleep(to_wait)
try:
dac = self.dac_and_input_register[dac]
except KeyError:
message = 'Invalid dac setting \'{}\', must be on of: {}'.format(
dac,
list(self.dac_and_input_register.keys()),
)
raise ValueError(message)
if (not isinstance(value, float)) or value < 0.0 or value > 5.0:
message = 'Invalid value: {} Must be a float in range 0.0 -> 5.0'
raise ValueError(message.format(value))
# Scale by range and convert the value to 2 bytes
relative = int(round(value / 5.0 * 65535))
most_significant_byte = relative // 256
least_significant_byte = relative % 256
data = [most_significant_byte, least_significant_byte]
self.bus.write_i2c_block_data(self.address, dac, data)
self.last_write = time.time()
[docs] def set_channel_A(self, voltage): # pylint: disable=invalid-name
"""Set a voltage of channel A
Args:
value (float): A float between 0.0 and 5.0
See :meth:`.write_to_and_update_dac` for details on exceptions
"""
self.write_to_and_update_dac('A', voltage)
[docs] def set_channel_B(self, voltage): # pylint: disable=invalid-name
"""Set a voltage of channel B
Args:
value (float): A float between 0.0 and 5.0
See :meth:`.write_to_and_update_dac` for details
"""
self.write_to_and_update_dac('B', voltage)
[docs] def set_both(self, voltage):
"""Set a voltage of both channels
Args:
value (float): A float between 0.0 and 5.0
See :meth:`.write_to_and_update_dac` for details
"""
self.write_to_and_update_dac('both', voltage)
[docs]def module_test():
"""Simple module test"""
adc = AD5667(0x08)
for number in range(100):
adc.write_to_and_update_dac('A', number / 99.0 * 5.0)
if __name__ == '__main__':
# module_test()
adc = AD5667(0x0C)
adc.reset_device()
time.sleep(0.05)
adc.enable_onbaord_reference()
time.sleep(0.1)
adc.set_channel_A(0.0)
adc.set_channel_B(0.0)