MCP4725 DAC Communication issue

Hello to everyone,

I’m writing here since after many days I cannot properly communicate with an MCP 4725 DAC using the toradex i2c library.

I’m developing an application in C# where I have an MCP4725 connected to a laser galvanometer.

I have to send values to the DAC to control the lens position for the laser beam deflection.

I don’t understand exactly how I can write in a right way the code to send a fast write command or a Standard command to the DAC register and/or eeprom.

I’ve written some code that works correctly but I have a strange issue I can’t understand.
Infact with this code I move correctly the laser beam where I want but the issue is that each time I send a new value I see a 30cm laser wake trail, also if I send the same value (the laser should not move so it isn’t a galvanometer issue). It’s like the DAC out voltage decrease a little before the new voltage will be set.

The code I wrote is the following:

public void WriteRegister(int iValue)
{
	if (bReverse)
		iValue = MAX_VALUE - iValue;

	//Fast Mode
	uint bufferLenght = 3;
	Byte[] DataToWrite = new Byte[bufferLenght];
	DataToWrite[0] = 192;
	DataToWrite[1] = (byte)((iValue & 3840) >> 8);
	DataToWrite[2] = (byte)(iValue & 255);
	try
	{
		unsafe
		{
			fixed (byte* for_Casting_Intptr_to_Byte = DataToWrite)
			{
				returnValue = i2c.I2c_Write(i2cHandle, (IntPtr)for_Casting_Intptr_to_Byte, bufferLenght);
				if (returnValue == 0)
					throw new Exception();                                            ///< If Write operation returns 0
			}
		}
	}
	catch (Exception ex)
	{
		Program.cGlobals.cLogging.LogMessage("Scrittura Configurazione Fallita - Codice Errore: " + ex.Message);
	}
}

I’ve tryied also to send a standard command with this code:

//Write DAC Register (not fast)
uint bufferLenght = 4;
Byte[] DataToWrite = new Byte[bufferLenght];
DataToWrite[0] = 192;
DataToWrite[1] = MCP4726_CMD_WRITEDAC;           // cmd to update the DAC
DataToWrite[2] = (byte)(iValue >> 4);            // the 8 most significant bits... (D11.D10.D9.D8.D7.D6.D5.D4)
DataToWrite[3] = (byte)((iValue & 15) << 4);     // the 4 least significant bits... (D3.D2.D1.D0) 

But it’s not working.

I hope someone could help me, I will really appreciate…

Thanks in advance.

Dear @emmettbrown

I have to explain how our i2c library handles the protocol bytes:

In the terminology of our library, the i2c protocol is assembled as follows

vvv  In our library:  vvv
[slaveAddr][RnW] [RegisterAddr] [data0]        [data1]        [data2] ...
7bits      1bit  0..16bits      8bits          8bits          8bits

0x60       0     (none)         iValue>>8      iValue&0xff
^^^ MCP4725 Fast mode ^^^

0x60       0     (none)         0x40           iValue>>4      (iValue&0x0f)<<4
^^^ MCP4725 Write DAC ^^^

Therefore what you need to do is to configure some parameters using the I2C_SetConfigInt() function:

  • SlaveAddrSize = 7 (this is the default anyway, so no need to set it)
  • SlaveAddr = 0x60
  • RegisterAddrSize = 0

After this you need to write the following data

  • for fast mode:
    [ iValue >> 8 , iValue & 0xff)
  • or for DAC Write
    [ 0x40, iValue>>4, iValue&0x0f]

The slave address is added automatically in front of every write.

Regards, Andy

Thank you very much @andy.tx , I’ve just solved setting the parameter:

RegisterAddrSize = 0

I don’t understand why since with other I2c devices with the register size is normally 8 bits. Infact I read and write normally LSM303C, TMP102 and LCD Display with 8 bits register size.

Why here the register size is 0?

Anyway thank you very much for your support

Dear @emmettbrown

I quickly checked the datasheets. Both the LSM303C and the TMP102 actually do have an address byte.

  • For the LSM303C the address byte is called subaddress (SUB)
  • For the TMP102 the address byte is called Pointer Register

Regards, Andy

Many thanks, you made me understand :slight_smile: