MCP4725 12bit DAC issues

/*
  In this tutorial we will [attempt to] connect a MCP4725 DAC IC with Arduino Uno
  and provide analog input value to Arduino pin A0 by using a MAX6675 SPI thermocouple module.

  https://circuitdigest.com/microcontroller-projects/arduino-dac-tutorial-interfacing-mcp4725-dac

*/

// Include dependant SPI Library
#include <SPI.h>

// Include Libraries from Adafruit
// Dependant upon Adafruit_Sensors Library
#include "max6675.h"

// Define Constants
int gndPin2 = 22;// Gnd = Ground pin
int vccPin2 = 24;// Vcc = Power pin

int thermoCLK = 26;// SCK = Serial Clock pin
int thermoCS = 28; // CS = Chip Select pin
int thermoDO = 30; // SO = Serial Out pin

// Initialize MAX6675 sensor for normal 16mhz Arduino
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);


#include<Wire.h>                  //Include Wire library for using I2C functions 
#include <LiquidCrystal_I2C.h>    //Include LCD library for using LCD display functions 

#define MCP4725 0x60              //MCP4725 address as 0x60 Change yours accordingly

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);// use I2C Scanner to find the address: 0x27 or something like that

unsigned int adc;
byte buffer[3];


// Define Constants
const int gndPin1 = 50;// Gnd = Ground pin
const int vccPin1 = 52;// Vcc = Power pin



const int a = 32; // Set fom 0 to 255 for a given brightness via PWM

const int LCDPin = 3; // the pin that the LCD LED is attached to PWM pin 3






void setup() {

  // use Arduino pins
  pinMode(gndPin1, OUTPUT); digitalWrite(gndPin1, LOW);    // declare Gnd pin
  pinMode(vccPin1, OUTPUT); digitalWrite(vccPin1, HIGH);   // declare Vcc pin

  pinMode(gndPin2, OUTPUT); digitalWrite(gndPin2, LOW);    // declare Gnd pin
  pinMode(vccPin2, OUTPUT); digitalWrite(vccPin2, HIGH);   // declare Vcc pin



  pinMode(LCDPin, OUTPUT); // declare pin 3 to be a PWM output


  Wire.begin();                //Begins the I2C communication
  lcd.begin();                 //Sets LCD in 20X4 Mode
  lcd.print("CIRCUIT DIGEST");
  delay(1000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Arduino");
  lcd.setCursor(0, 1);
  lcd.print("DAC with MCP4725");
  delay(2000);
  lcd.clear();


}

void loop() {

  delay(500);  // Delay so MAX6675 sensor can stabalize


  analogWrite(LCDPin, a); // set the brightness of PWM pin 3:




  buffer[0] = 0b01000000;            //Sets the buffer0 with control byte (010-Sets in Write mode)
  adc = analogRead(A0) * 4;          //Read Analog value from pin A0 and convert into digital (0-1023) multiply with 4 gives (0-4096)

  float ipvolt = (5.0 / 4096.0) * adc; //Finding voltage formula (A0)
  buffer[1] = adc >> 4;              //Puts the most significant bit values
  buffer[2] = adc << 4;              //Puts the Least significant bit values


  unsigned int analogread = analogRead(A1) * 4 ; //Reads analog voltage from A1 [Need to multiply by 4 for the 0-4096 bit reason]

  float opvolt = (5.4 / 4096.0) * analogread; //Finding Voltage Formula (A1) [Chose 5.4 to make readings match]

  Wire.beginTransmission(MCP4725);         //Joins I2C bus with MCP4725 with 0x60 address

  Wire.write(buffer[0]);            //Sends the control byte to I2C
  Wire.write(buffer[1]);            //Sends the MSB to I2C
  Wire.write(buffer[2]);            //Sends the LSB to I2C

  Wire.endTransmission();           //Ends the transmission

  lcd.setCursor(0, 0);
  lcd.print("A IP:");
  lcd.print(adc);                   //Prints the ADC value from A0
  lcd.setCursor(10, 0);
  lcd.print("V:");                  //Prints the Input Voltage at A0
  lcd.print(ipvolt);
  lcd.setCursor(0, 1);
  lcd.print("D OP:");
  lcd.print(analogread);             //Prints the ADC value from A1 (From DAC)
  lcd.setCursor(10, 1);
  lcd.print("V:");
  lcd.print(opvolt);                 //Prints the Input Voltage at A1 (From DAC)

  lcd.setCursor(0, 2);
  lcd.print("F = ");
  lcd.print(thermocouple.readFahrenheit());
  lcd.print("C = ");
  lcd.print(thermocouple.readCelsius());



  delay(500);
  lcd.clear();
}

I know that the SPI buss data can be somehow fed to the DAC buffer in real time, but the question is "how?'. Figuring out how to allocate the bits is tricky to me and I've searched high and low online with minimal references to this issue.

I know that I'm attempting to seamlessly mesh an SPI device to an I2C device and I am humbled by those willing to point me in the right direction.

I know that the SPI buss data can be somehow fed to the DAC buffer in real time, but the question is "how?

Define "real time"!
Describe what you're trying to achieve!

You don't even use the SPI bus but some slow software emulation. Was that by intention?

/*
  In this tutorial we will [attempt to] connect a MCP4725 DAC IC with Arduino Uno
  and provide analog input value to Arduino pin A0 by using a MAX6675 SPI thermocouple module.

  https://circuitdigest.com/microcontroller-projects/arduino-dac-tutorial-interfacing-mcp4725-dac

*/

Arduino UNO doesn't have pins with numbers over 21. Probably the comment is simply wrong but you should at least tell us what Arduino you're using.

My bad. I am using an Arduino Mega.

As for "real time", I mean as quickly as possible DSP-wise.

My thermocouple is a MAX6675 that uses SPI by default.

I see lots of analog thermocouple circuits out there but I need to work with what I have on hand.

I have a few MAX6675 thermocouples and I want to somehow take the data from these SPI devices and feed this data into a MCP4725 I2C DAC Breakout Development Board module 12Bit Resolution.

Again, this isn't exactly my choice and I want to work with what I have on hand.

These SPI K-type thermocouple modules are cheap and all over the place. MAX6675 Thermocouple Temperature Sensor Module Type K SPI Interface For Arduino | eBay

My goal: Simply put, I want to measure temperature with my MAX6675 digital thermocouple board and then take the digitized thermocouple readings and "turn them into" an analog out with my DAC.

I'd prefer to be able to do so in such a way that my project essentially acts as an Analog Temperature Sensor; via the DAC and outputs an analog voltage into any given Arduino Analog Input pin and reads the temperature on the serial monitor As If I am actually using an analog sensor like the LM35D Analog Temperature Sensor instead of a complicated Rube Goldberg machine.

The hardest part for me is the interfacing within the different layers of abstraction of the software environment, how to buffer the bits, when/where/how to call interrupts and so on...

The hardware interfacing is a piece of cake though. :slight_smile:

Thermocouple.jpg

MCP4725.jpg

I just came across this thread and I found that someone else that wants to basically do the same thing but with a different sensor.
(Same idea as mine.)

https://forum.arduino.cc/index.php?topic=554160.0

I want to do the same thing but the code give me an int error.

incompatible types in assignment of 'int' to 'int [5]'

I have this code and it wont compile due to a common error but I just can't seem to make the correlation to rectify the error.

#include <Wire.h>
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 dac;

// Set this value to 9, 8, 7, 6 or 5 to adjust the resolution
#define DAC_RESOLUTION    (8)




#include <LiquidCrystal.h>
/*#define TCAADDR 0x70
      void tcaselect(uint8_t i) {
      if (i > 7) return;
      Wire.beginTransmission(TCAADDR);
      Wire.write(1 << i);
      Wire.endTransmission(); 
    }
    */
const int sensor_addr   = 0x00;
const int read_delay    = 20;


int rbuf[5];
float P, T, Pconv, Tconv;
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2); //Digital pins to which you connect the LCD

void setup() {

  dac.begin(0x62);
  dac.setVoltage(Pconv, false);

  lcd.begin(16,4);


}

void loop() {

  // NPA201 barometric pressure sensor
  int i;
     Wire.begin();                // join i2c bus (address optional for master)
     Serial.begin(250000);        // start serial communication
     
      Wire.beginTransmission(sensor_addr); // transmit to device
      Wire.write(0xAC);                    // send command for full sensor read
      Wire.endTransmission();              // stop transmitting
   
      delay(read_delay);                   // datasheet suggests at least 20 milliseconds
   
      if (Wire.requestFrom(sensor_addr, 5) >= 0) {
        i = 0;
        for (i = 0; i < 5; i++) {
          rbuf = Wire.read();// problem...
        }

      // Join two bytes for to make 16-bit readings for pressure and temp
      P = word(rbuf[1],rbuf[2]);
      T = word(rbuf[3],rbuf[4]);

      // Convert using formula in data sheet
      Tconv = T / 65535 * (85+40) - 40;
      Pconv = P / 65535 * (1260 - 260) + 260;


      Serial.print (rbuf[0]); Serial.print(" "); Serial.print ("rbuf[0] /"); //Serial.print(byte(rbuf[0]));
      Serial.print (rbuf[1]); Serial.print(" "); Serial.print ("rbuf[1] /"); //Serial.print(byte(rbuf[1]));
      Serial.print (rbuf[2]); Serial.print(" "); Serial.print ("rbuf[2] /"); //Serial.print(byte(rbuf[2]));
      Serial.print (rbuf[3]); Serial.print(" "); Serial.print ("rbuf[3] /"); //Serial.print(byte(rbuf[3]));
      Serial.print (rbuf[4]); Serial.print(" "); Serial.print ("rbuf[4] /"); //Serial.print(byte(rbuf[4]));
      Serial.print (rbuf[5]); Serial.print(" "); Serial.print ("rbuf[5] "); Serial.print(byte(rbuf[5]));
      Serial.print (T); Serial.print(" "); Serial.print ("T "); Serial.print(byte(T));
      Serial.print (P); Serial.print(" "); Serial.print ("P "); Serial.print(byte(P));

     
      Serial.println();

/*
//lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Pres: ");
lcd.print ((Pconv/68.94744825)-0.0);
lcd.print("psi");
lcd.print(" ");

//lcd.clear();
lcd.setCursor(0,1);
lcd.print ("Temp: ");
lcd.print ((Tconv*9/5)+32);
lcd.print("F");
lcd.print(" ");

lcd.setCursor(0,2);

lcd.print (T);
lcd.print(" ");

lcd.setCursor(0,3);
lcd.print (Tconv);
lcd.print(" C");
//lcd.print(" ");
*/
  //lcd.backlight();
  lcd.setCursor(0,0); lcd.print(Pconv); lcd.setCursor(7,0); lcd.print("mb"); //lcd.setCursor(10,0); lcd.print("P="); lcd.setCursor(12,0); lcd.print(P);
  lcd.setCursor(0,1); lcd.print(Pconv/68.94744825); lcd.setCursor(5,1); lcd.print("psi"); lcd.setCursor(9,1); lcd.print(Pconv/33.8639); lcd.setCursor(14,1); lcd.print("Hg");
  lcd.setCursor(0,2); lcd.print(Tconv); lcd.setCursor(5,2); lcd.print("*C"); lcd.setCursor(10,2); //lcd.print("T=");lcd.setCursor(12,2); lcd.print(T);
  lcd.setCursor(9,2); lcd.print((Tconv*1.8)+32); lcd.setCursor(14,2); lcd.print("*F");
  lcd.setCursor(0,3); lcd.print(millis()/1000);
  //lcd.setCursor(0,1);
  //lcd.print(T);
  // lcd.setCursor(0,2);
 // lcd.print(Tconv);
  // lcd.setCursor(0,3);



      delay(1000);                  // delay in msec
      }

}

Error code:

exit status 1
incompatible types in assignment of 'int' to 'int [5]'

The answer should be obvious but it doesn't seem to be. :disappointed_relieved:

I would appreciate any guidance out there with this particular issue. :slight_smile:

Fix:

for (i = 0; i < 5; i++) {
          rbuf[i] = Wire.read();// problem...
        }

I want to do the same thing but the code give me an int error.

You probably copied the mangled code from above.

Notice this point where the printing turns to italic
if (Wire.requestFrom(sensor_addr, 5) >= 0) {
i = 0;
for (i = 0; i < 5; i++) {
rbuf = Wire.read();

  • }*
  • // Join two bytes for to make 16-bit readings for pressure and temp*
  • P = word(rbuf[1],rbuf[2]);*
  • T = word(rbuf[3],rbuf[4]);*
    There should have been rbuf[i] for the array index, but without code tags the i got interpreted as set the text to italic. This is one reason why code tags should be used.
    ```
    *#include <Wire.h>
    #include <Adafruit_MCP4725.h>
    Adafruit_MCP4725 dac;

// Set this value to 9, 8, 7, 6 or 5 to adjust the resolution
#define DAC_RESOLUTION 8

#include <LiquidCrystal.h>
/*#define TCAADDR 0x70
      void tcaselect(uint8_t i) {
      if (i > 7) return;
      Wire.beginTransmission(TCAADDR);
      Wire.write(1 << i);
      Wire.endTransmission();
    }
*/
const int sensor_addr  = 0x00;
const int read_delay    = 20;
int rbuf[5];
float P, T, Pconv, Tconv;
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2); //Digital pins to which you connect the LCD

void setup() {

dac.begin(0x62);
  dac.setVoltage(0, false);
  lcd.begin(16, 4);
}

void loop() {

// NPA201 barometric pressure sensor
  int i;
  Wire.begin();                // join i2c bus (address optional for master)
  Serial.begin(250000);        // start serial communication

Wire.beginTransmission(sensor_addr); // transmit to device
  Wire.write(0xAC);                    // send command for full sensor read
  Wire.endTransmission();              // stop transmitting

delay(read_delay);                  // datasheet suggests at least 20 milliseconds

if (Wire.requestFrom(sensor_addr, 5) >= 0) {
    i = 0;
    for (i = 0; i < 5; i++) {
      rbuf[i] = Wire.read();
    }

// Join two bytes for to make 16-bit readings for pressure and temp
    P = word(rbuf[1], rbuf[2]);
    T = word(rbuf[3], rbuf[4]);

// Convert using formula in data sheet
    Tconv = T / 65535 * (85 + 40) - 40;
    Pconv = P / 65535 * (1260 - 260) + 260;
   
    Serial.print (rbuf[0]); Serial.print(" "); Serial.print ("rbuf[0] /"); //Serial.print(byte(rbuf[0]));
    Serial.print (rbuf[1]); Serial.print(" "); Serial.print ("rbuf[1] /"); //Serial.print(byte(rbuf[1]));
    Serial.print (rbuf[2]); Serial.print(" "); Serial.print ("rbuf[2] /"); //Serial.print(byte(rbuf[2]));
    Serial.print (rbuf[3]); Serial.print(" "); Serial.print ("rbuf[3] /"); //Serial.print(byte(rbuf[3]));
    Serial.print (rbuf[4]); Serial.print(" "); Serial.print ("rbuf[4] /"); //Serial.print(byte(rbuf[4]));
    Serial.print (rbuf[5]); Serial.print(" "); Serial.print ("rbuf[5] "); Serial.print(byte(rbuf[5]));
    Serial.print (T); Serial.print(" "); Serial.print ("T "); Serial.print(byte(T));
    Serial.print (P); Serial.print(" "); Serial.print ("P "); Serial.print(byte(P));

Serial.println();

/*
      //lcd.clear();
      lcd.setCursor(0,0);
      lcd.print ("Pres: ");
      lcd.print ((Pconv/68.94744825)-0.0);
      lcd.print("psi");
      lcd.print(" ");

//lcd.clear();
      lcd.setCursor(0,1);
      lcd.print ("Temp: ");
      lcd.print ((Tconv*9/5)+32);
      lcd.print("F");
      lcd.print(" ");

lcd.setCursor(0,2);

lcd.print (T);
      lcd.print(" ");

lcd.setCursor(0,3);
      lcd.print (Tconv);
      lcd.print(" C");
      //lcd.print(" ");
    */
    //lcd.backlight();
    lcd.setCursor(0, 0); lcd.print(Pconv); lcd.setCursor(7, 0); lcd.print("mb"); //lcd.setCursor(10,0); lcd.print("P="); lcd.setCursor(12,0); lcd.print(P);
    lcd.setCursor(0, 1); lcd.print(Pconv / 68.94744825); lcd.setCursor(5, 1); lcd.print("psi"); lcd.setCursor(9, 1); lcd.print(Pconv / 33.8639); lcd.setCursor(14, 1); lcd.print("Hg");
    lcd.setCursor(0, 2); lcd.print(Tconv); lcd.setCursor(5, 2); lcd.print("*C"); lcd.setCursor(10, 2); //lcd.print("T=");lcd.setCursor(12,2); lcd.print(T);
    lcd.setCursor(9, 2); lcd.print((Tconv * 1.8) + 32); lcd.setCursor(14, 2); lcd.print("F");
    lcd.setCursor(0, 3); lcd.print(millis() / 1000);
    //lcd.setCursor(0,1);
    //lcd.print(T);
    // lcd.setCursor(0,2);
    // lcd.print(Tconv);
    // lcd.setCursor(0,3);
    delay(1000);                  // delay in msec
  }
}

```

My gosh. I am having similar interfacing issues with my MCP4725 12 bit DAC breakout board as well. May I please join this discussion?

My gosh. I am having similar interfacing issues with my MCP4725 12 bit DAC breakout board as well. May I please join this discussion?

You have three threads going on this topic. Picking up from this one with poorly posted code and a different sensor from you is not a good idea.

https://forum.arduino.cc/index.php?topic=651919.msg4394748#msg4394748

https://forum.arduino.cc/index.php?topic=651752.msg4394729#msg4394729

https://forum.arduino.cc/index.php?topic=651752.msg4393765#msg4393765

@Arduino_n00b

One more cross post or hijack and you will have 7 days rest to work out what those two terms mean.

FINAL WARNING !

Bob.

Let's get back to basics.

  1. can you use the Adafruit Max6675 library to read the thermocouple? Do you know how to assign the temperature to a variable, and not just print it?

  2. What temperature range do you expect to measure, and how do you want to map that temperature to the 0-5 volts analog output available from the MCP4725?

  3. I suggest that you use the Adafruit MCP4725 library to communicate with the dac. It is available through the library manager. You will use a simple command dac.setVoltage() to set the output voltage.

When you have the basics sorted out, come back.

@ballscrewbob

Okay. No problem.
(ouch)

I want to especially thank cattledog for being helpful as well as patient.

Your help allowed me to compile the code beautifully.

I'm still learning how to code with Arduino, let alone use this forum and gleam through the thousands upon thousands of threads.

I'm not an A.I. Avatar yet. :wink: