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!

Parents
  • 0
    •  Analog Employees 
    •  Super User 
    on Dec 2, 2020 10:07 AM

    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

Reply
  • 0
    •  Analog Employees 
    •  Super User 
    on Dec 2, 2020 10:07 AM

    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

Children
  • 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!

  • 0
    •  Analog Employees 
    •  Super User 
    on Dec 3, 2020 7:15 AM in reply to luisar3

    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), )