Post Go back to editing

AD5667 on Pi - Analog Output checking

Hello,

I'm trying to generate a sinewave utilizing a I2CDAC >>> AD5667 that is caped on a Raspberry Pi. 

I'm struggling with checking whether or not the chip/device is being talked to from the Pi. 

I'm using this library to generate voltage: https://github.com/ControlEverythingCommunity/CE_PYTHON_LIB/blob/master/AD5667.py

I'm new to these devices and I've always struggling communicating with the chips; any help is appreciated!

  • Hi, 

    I'm assuming your slave address is correct and you get an ACK during your I2C transaction. I want to check your hardware setup:
    What is your VDD level? 
    What is the VOH coming from your Raspberry PI? It should be compliant to the VDD level as per Table 2 in the datasheet (Digital Input section)
    What are the /LDAC and /CLR levels?

    Let me clear up: are you using AD5667 (w/o internal reference) or AD5667R (w/ internal reference)? If using the *R version, you need to initialize the on-chip reference as it is off at power-up. If the refin/refout pin has a valid output then you can be sure that you are able to talk to the device.

    Best regards,

    Ian

  • Voh is about 5.03, last time I checked. According to Table 2, I think Vdd should be 5.5v? I could be wrong.

    I'm not sure how to measure LDAC or CLR

    I'm using AD5667 w/o internal reference.

    Thank you Ian!

  • Hi, 

    I'm not sure how to measure LDAC or CLR

    These are input pins and should be biased. They should be either pulled to VDD or grounded or connected to a GPIO on your Pi. 

    Could you share the schematic of your AD5667 circuit?

    Have you tried a readback from the DAC?

    Hope you could also probe the SDA and SCL using an oscilloscope. 

    Best regards,

    Ian

  • I'm using an Digilent's Analog Discovery (black) multi-tool as my o-scope; here's a picture because I think it would take too long for me to figure out a schematic.

    DAC is on the left; I'm holding the Ch1+/- wires. When I probed it I get nothing (straight line) and when I run my Python code I get some spikes on screen. I can share screenshots of those too if needed. I included code below too. Thank you again, very much appreciated. 

    # Distributed with a free-will license.
    # Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
    # AD5667
    # This code is designed to work with the AD5667_I2CDAC I2C Mini Module available from ControlEverything.com.
    # https://www.controleverything.com/content/Digital-Analog?sku=AD5667_I2CDAC#tabs-0-product_tabset-2
    
    import smbus
    import time
    
    # Get I2C bus
    bus = smbus.SMBus(1)
    
    # I2C address of the device
    AD5667_DEFAULT_ADDRESS				= 0x0E
    
    # AD5667 Command Set
    AD5667_CMD_DAC_A					= 0x00 # Select DAC A Channel
    AD5667_CMD_DAC_B					= 0x01 # Select DAC B Channel
    AD5667_CMD_DAC_ALL					= 0x07 # Select Both DAC Channel
    AD5669_CMD_WRITE_INPUT				= 0x00 # Write to input register
    AD5669_CMD_UPDATE_DAC				= 0x08 # Update DAC registe
    AD5667_CMD_WRITE_UPDATE_ALL			= 0x10 # Write to input register, update all
    AD5667_CMD_WRITE_UPDATE_DAC			= 0x18 # Write to and update DAC channel
    AD5667_CMD_POWER					= 0x20 # Power up
    AD5667_CMD_RESET					= 0x28 # Reset
    AD5667_CMD_LDAC_SETUP				= 0x30 # LDAC register setup
    AD5667_CMD_INT_REF_SETUP			= 0x38 # Internal reference setup
    
    class AD5667():
    	def set_channel(self):
    		"""Select the Channel user want to use from 0-2
    		0 : DAC A Channel
    		1 : DAC B Channel
    		2 : DAC All Channel"""
    		self.channel = int(input("Enter the Channel No.(0-2)= "))
    		while self.channel > 2 :
    			self.channel = int(input("Enter the Channel No.(0-2) = "))
    		
    		return self.channel
    
    	def direct_channel(self, c):
    		self.channel = c
    		return
    
    	def direct_voltage(self, v):
    		self.voltage = v
    		self.data = [self.voltage >> 8, self.voltage & 0xFF]	
    		return
    
    	def set_voltage(self):
    		"""Enter the value from 0-65535 position for channel"""
    		self.voltage = int(input("Enter the Value from (0-65536)= "))
    		while self.voltage > 65535 :
    			self.voltage = int(input("Enter the Value from (0-65536)= "))
    		
    		self.data = [self.voltage >> 8, self.voltage & 0xFF]
    		
    		return self.data
    	
    	def write_voltage(self):
    		if self.channel == 0 :
    			bus.write_i2c_block_data(AD5667_DEFAULT_ADDRESS, (AD5667_CMD_WRITE_UPDATE_DAC | AD5667_CMD_DAC_A), self.data)
    		elif self.channel == 1 :
    			bus.write_i2c_block_data(AD5667_DEFAULT_ADDRESS, (AD5667_CMD_WRITE_UPDATE_DAC | AD5667_CMD_DAC_B), self.data)
    		elif self.channel == 2 :
    			bus.write_i2c_block_data(AD5667_DEFAULT_ADDRESS, (AD5667_CMD_WRITE_UPDATE_DAC | AD5667_CMD_DAC_ALL), self.data)
    	
    	def voltage_conversion(self):
    		"""Convert the data to get the voltage"""
    		voltage = ((self.data[0] * 256 + self.data[1]) / 65536.0) * 5.0	
    		return {'v' : voltage}
    
    	def reset(self):
    		#AD5667_CMD_RESET = 0x28 # Reset	
    		bus.write_i2c_block_data(AD5667_DEFAULT_ADDRESS, (AD5667_CMD_RESET | AD5667_CMD_DAC_A), )
    
    
    

  • Pi with DAC; I'm holding Ch1+/- of my Digilent Analog Discovery (black). I shared a picture because sorting out a schematic would take too long for me. I can provide my code as well.

  • Python code I'm using from the ControlEverything github repo.

    # Distributed with a free-will license.
    # Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
    # AD5667
    # This code is designed to work with the AD5667_I2CDAC I2C Mini Module available from ControlEverything.
    # [ommited because it was flagged]
    
    import smbus
    import time
    
    # Get I2C bus
    bus = smbus.SMBus(1)
    
    # I2C address of the device
    AD5667_DEFAULT_ADDRESS				= 0x0E
    
    # AD5667 Command Set
    AD5667_CMD_DAC_A					= 0x00 # Select DAC A Channel
    AD5667_CMD_DAC_B					= 0x01 # Select DAC B Channel
    AD5667_CMD_DAC_ALL					= 0x07 # Select Both DAC Channel
    AD5669_CMD_WRITE_INPUT				= 0x00 # Write to input register
    AD5669_CMD_UPDATE_DAC				= 0x08 # Update DAC registe
    AD5667_CMD_WRITE_UPDATE_ALL			= 0x10 # Write to input register, update all
    AD5667_CMD_WRITE_UPDATE_DAC			= 0x18 # Write to and update DAC channel
    AD5667_CMD_POWER					= 0x20 # Power up
    AD5667_CMD_RESET					= 0x28 # Reset
    AD5667_CMD_LDAC_SETUP				= 0x30 # LDAC register setup
    AD5667_CMD_INT_REF_SETUP			= 0x38 # Internal reference setup
    
    class AD5667():
    	def set_channel(self):
    		"""Select the Channel user want to use from 0-2
    		0 : DAC A Channel
    		1 : DAC B Channel
    		2 : DAC All Channel"""
    		self.channel = int(input("Enter the Channel No.(0-2)= "))
    		while self.channel > 2 :
    			self.channel = int(input("Enter the Channel No.(0-2) = "))
    		
    		return self.channel
    
    	def direct_channel(self, c):
    		self.channel = c
    		return
    
    	def direct_voltage(self, v):
    		self.voltage = v
    		self.data = [self.voltage >> 8, self.voltage & 0xFF]	
    		return
    
    	def set_voltage(self):
    		"""Enter the value from 0-65535 position for channel"""
    		self.voltage = int(input("Enter the Value from (0-65536)= "))
    		while self.voltage > 65535 :
    			self.voltage = int(input("Enter the Value from (0-65536)= "))
    		
    		self.data = [self.voltage >> 8, self.voltage & 0xFF]
    		
    		return self.data
    	
    	def write_voltage(self):
    		if self.channel == 0 :
    			bus.write_i2c_block_data(AD5667_DEFAULT_ADDRESS, (AD5667_CMD_WRITE_UPDATE_DAC | AD5667_CMD_DAC_A), self.data)
    		elif self.channel == 1 :
    			bus.write_i2c_block_data(AD5667_DEFAULT_ADDRESS, (AD5667_CMD_WRITE_UPDATE_DAC | AD5667_CMD_DAC_B), self.data)
    		elif self.channel == 2 :
    			bus.write_i2c_block_data(AD5667_DEFAULT_ADDRESS, (AD5667_CMD_WRITE_UPDATE_DAC | AD5667_CMD_DAC_ALL), self.data)
    	
    	def voltage_conversion(self):
    		"""Convert the data to get the voltage"""
    		voltage = ((self.data[0] * 256 + self.data[1]) / 65536.0) * 5.0	
    		return {'v' : voltage}
    
    	def reset(self):
    		#AD5667_CMD_RESET = 0x28 # Reset	
    		bus.write_i2c_block_data(AD5667_DEFAULT_ADDRESS, (AD5667_CMD_RESET | AD5667_CMD_DAC_A), )
    

  • Hi, 

    Sorry for the late reply, 

    I see you're using Analog discovery. There should be a protocol analyzer tool there. You could probe SDA and SCL (+ground) and see the validity of your serial comms.

    By the way, is the AD5667 used in a custom PCB? What application are you planning on using it? Hope you can share the schematic with me so I can check it too. (can email it directly)

    Best reards,

    Ian