Using Digital Pins to Control Two MCP4725 Modules

I am already using the A4 and A5 pins to control two MCP4725 modules. I also want to control two other MCP4725 modules using a set of digital pins, presumably using the Softwire library.

/* ÖRNEK JSON INPUTU
{
  "inputs": {
    "yag": 10,
    "fuel": 90,
    "temp1": 80,
    "temp2": 78,
    "pressure": 80,
    "speed": 40
  }
}
*/

//Libraries
  #include <ArduinoJson.h>
  #include <Wire.h>
  #include <Adafruit_MCP4725.h>
  #include <AsyncDelay.h>
  #include <SoftWire.h>

//Real I2C Output 
  Adafruit_MCP4725 dac1;
  Adafruit_MCP4725 dac2;
  #define SDA A4
  #define SCL A5
  unsigned short int yagImlec;
  unsigned short int fuelImlec;

//Software I2C Output 
  #define softSDA 2
  #define softSCL 3
  SoftWire sWire = SoftWire(softSDA,softSCL);
  unsigned short int temp1Imlec;
  unsigned short int temp2Imlec;

void setup(void) {

  Serial.begin(115200);

  dac1.begin(0x60);
  dac2.begin(0x61);

  sWire.begin();

  pinMode(servo1Pin, OUTPUT);
  pinMode(servo2Pin, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
}

void loop() {

  parseJSON();
  hardwareI2C();
  softwareI2C();
  
}

void parseJSON() {
  // Stream& input;

StaticJsonDocument<128> doc;

DeserializationError error = deserializeJson(doc, Serial);

if (error) {
  Serial.print(F("deserializeJson() failed: "));
  Serial.println(error.f_str());
  return;
}

JsonObject inputs = doc["inputs"];
yagImlec = map(inputs["yag"],0,100,0,4095);
fuelImlec = map(inputs["fuel"],0,100,0,4095);
temp1Imlec = map(inputs["temp1"],0,100,0,4095);
temp2Imlec = map(inputs["temp2"],0,100,0,4095);
servo1Position = map(inputs["pressure"],0,100,0,255);
servo2Position = map(inputs["speed"],0,100,0,255);
} 

void hardwareI2C() {
  dac1.setVoltage(yagImlec, false);
  dac2.setVoltage(fuelImlec, false);
}

void softwareI2C(){
    sWire.beginTransmission(0X60);
    sWire.llWrite(temp1Imlec);
    sWire.endTransmission();

    sWire.beginTransmission(0X61);
    sWire.llWrite(temp2Imlec);
    sWire.endTransmission();
}

This code does not work.

why do that when you can multiplex all 4 modules using a [TCA9548A]!(Overview | Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout | Adafruit Learning System)

I have heard about this, but would like to know if it's possible to achieve without an additional purchase

@volkanttn

but would like to know if it's possible to achieve without an additional purchase

(not tested)
Possibly you can control multiple MCP4725 over the hardware I2C bus + some IO pins.

  • Connect the address pin of every MCP4725 to an IO pin,
  • Keep all IO pins LOW so the all have effectively the same address == 0x60.
  • To select a specific MCP you set the related IO pin to HIGH and it will have address == 0x61.

Not tested if this works but it might.

If it works I'll add an example to my library - GitHub - RobTillaart/MCP4725: Arduino library for 12 bit I2C DAC - MCP4725

@volkanttn

Datasheet 7.2 Device Addressing

  • A0 bit is determined by the logic state of A0 pin.
    The A0 pin can be tied to VDD or VSS, or can be
    actively driven by digital logic levels. The advantage
    of using the A0 pin is that the users can control
    the A0 bit on their application PCB circuit and
    also two identical MCP4725 devices can be used
    on the same bus line.

So it might just work

From the documentation:
high-level functions provide almost direct compatibility with the Wire library. However, the user must first declare transmit and receive buffers, and configure SoftWire to use them before the high-level functions beginTransmission(), endTransmission(), read(), write() and requestFrom () can be used. Notify SoftWire of the buffers by calling the setTxBuffer() and setRxBuffer() functions, passing in a pointer to a byte or character buffer and the size of the buffer.

I just tried this and this works. Still, for educational purposes I would like to know if it's possible to set up two digital pins as fake SDA SCL pins to control the modules. If anyone reading this knows how to do that, I would love to hear it. But as I've said, the problem CAN be solved this way, it works.

Good to hear that using the A0 pin as SELECT works.

Software I2C

For AVR-only I have used - GitHub - Testato/SoftwareWire: Creates a software I2C/TWI bus on every pins (AVR only) with success for an SHT31 sensor. Yes that is a completely different device however the I2C behavior seems OK.

For ESP32 I have used (also for SHT31)

Note that the interface of these software I2C might be slightly different but not too hard.

disclaimer: not investigated with an MCP4725.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.