MCP4725 and I2C node-red-contrib-i2c

Hi all, i just discovered node-red 3 weeks ago and i developed a dashboard to send query to a modbus server with success so i am happy. Now i need to interact with a MCP4725 to send variable voltage to control a device. I found only a node-red ncd for the MCP but it is an old library and doesn't work anymore with the new nodejs and Node red so i need help to use node-red-contrib-i2c if this is a good starting point.
Thank you
Francois

Welcome to the forum!

node-red-contrib-i2c will probably work. You need to look at the datasheet for the MCP4725, to understand what you need to send as commands.

Unless someone here has already used the MCP4725 and can offer help, you will have to work this out yourself. There may also be an alternative DAC that is supported.

Thank you. Anyone else? Experienced this chip ?

Hi all
After many research and after installing a I2C decoder on my computer, i can say that this node works only with a simple device. i understand now this node.
You set the bus number for the device so in my case : 1
You set the Bus Address of the device so for the MCP4725 0x60 so 96 decimal
You set the command so for example, for the MCP4725, the command is 40 (Hex)
Now for the mcp4725, i have 2 bytes to send to set up the voltage. So the msg payload need to start from -32768 to +32767 and it will be translated to binary inside the 2 bytes so for example, if you send -32768 you will see 00 and 80 (Hex)
If you send 32767, you will send FF 7F.
I created a dashboard with a slider to change the voltage out of the MCP4725 and it works perfectly.
The question is now , i want to use a MCP4728 and the problem is that i need to send two different bytes for the third and the last byte at the same time because of this device. The node send only the same value for those 2 bytes. Do you have some ideas ?
Thank you

Hi,
I publish a mcp4728 and mcp4725 node and library on next days. Please wait.

Okay. Thank you :slight_smile:

Hi all
Because i love to find and with the help of chatgpt, here is a function code in node red to calculate the 12 bits of the output voltage for a channel described in the I2C out. Note that i use VREF= VDD so the gain is ignored. To calculate the 12 bits you need to keep the first 4 bits of the first byte with a value depending of the VREF parameter and Gain you want. In my case, i only need VREF=VDD so the datagram is
0x60(address), 0x58 (command for the channel A) and VREF=0 PD1 and PD2 = 0 Gx=x (ignored) and the 12 bits with the second bytes to determine the output voltage.
Here is the function to write

function encodeValue(value) {
value &= 0xFFF;
let firstNibble = 0x1; // this is the codification of VREF=0, PD1 and PD0 to 0 Gx to 1 (yes G is ignored but my mistake)
let secondByte = value & 0xFF;
let encodedValue = (firstNibble << 12) | (value & 0xFFF);
encodedValue = ((encodedValue & 0xFF) << 8) | ((encodedValue >> 8) & 0xFF);
return encodedValue;
}
let value = msg.payload;
let encodedValue = encodeValue(value);
msg.payload = encodedValue;
return msg;

=========================
only one thing is to set a 3 bytes in the I2C OUT node. The msg.payload is a number from 0 to 4095.
I created a slider with a range from 0 to 4095 and it works !

You can chain 4 I2C out node to set up the 4 channels as well.
My 2 cents :slight_smile:

1 Like

Thank you for your node. Why do you use the multiwrite command instead of the single write command ?

I think you mean the modes in mcp4728. The single write mode writes also to eeprom. This makes the writes slow and often write to eeprom reduce the lifetime of eeprom.

That makes sense. I noticed in the single write command that output voltage was not as expected . I don't understand why. did you test in this mode ?

There is also a mcp4728 node.js library on my npm.
The eeprom and eeprom_sync function use the single write command. This functions works expected.

Hi i changed my javascript code to inject a multiwrite command

function encodeValue(value) {
value &= 0xFFF;
let firstNibble = 0x9; // this is the codification of VREF=1, PD1 and PD0 to 0 Gx to 1
let secondByte = value & 0xFF;
let encodedValue = (firstNibble << 12) | (value & 0xFFF);
encodedValue = ((encodedValue & 0xFF) << 8) | ((encodedValue >> 8) & 0xFF);
return encodedValue;
}
let value = msg.payload;
let encodedValue = encodeValue(value);
msg.payload = encodedValue;
return msg;

With this code everything works perfectly. I chained 4 i2c out to replicate the voltage on the 4 channels