MAX6682 Thermistor-to-Digital Converter

Hello,
I'm having some difficulty reading the MAX6682 digital output. Does anyone have the sketch for it?
I don't know how to properly read the 10-bit considering that the 3 LSBs of the output code represent fractional temperatures.

Just take the value and divide it by 8 (to get whole degrees) or 8.0 to get a floating-point number that includes the fractions of a degree.

I have used code similar to this in the past, with the MAX6682 connected to the SPI pins:

  const int csPin = 10;   // digital pin used for MAX6682 CS

  int pollSensor()
  {
      // Pull CS low and read out result of last conversion
      digitalWrite(csPin, LOW);
      
      int hiByte = (int)(signed char)SPI.transfer(0);  // read high 8 bits and sign-extend
      uint8_t loByte = SPI.transfer(0);                // read low 4 bits + 4 dummy bits
      int reading = (int)(((unsigned int)hiByte << 3) | ((unsigned int)loByte >> 5));  // combine bytes
  
      // Set CS high again to allow other devices to use bus and tell the MAX6682 to start a new conversion
      digitalWrite(csPin, HIGH);
      return reading;
  }

Thanks for the replies. I keep having problems. This is the first time I am working with the Arduino and do not know much about programming! ... Anyway...

I would like to get temperature values with the highest resolution possible ie 1LSB = 0.125 º C. How can I do it?

#include <SPI.h>
#define CS 53 //Selection Pin 
#define MISO  50//MISO 
#define SCK  52//Clock
int readvalue;

void setup(){ 
 Serial.begin(9600);

 //set pin modes 
 pinMode(CS, OUTPUT); 
 pinMode(MISO, INPUT); 
 pinMode(SCK, OUTPUT); 
 
 SPI.begin(); // initialize SPI, covering MOSI,MISO,SCK signals
 SPI.setBitOrder(MSBFIRST);  // data is clocked in MSB first
 SPI.setDataMode(SPI_MODE0);  // latched on rising edge, transitioned on falling edge, active low
}

int MAX6682()
  {
      // Pull CS low and read out result of last conversion
      digitalWrite(CS, LOW);
      
      int hiByte = (int)(signed char)SPI.transfer(0);  // read high 8 bits and sign-extend
      uint8_t loByte = SPI.transfer(0);                // read low 4 bits + 4 dummy bits
      int reading = (int)(((unsigned int)hiByte << 3) | ((unsigned int)loByte >> 5));  // combine bytes
  
      // Set CS high again to allow other devices to use bus and tell the MAX6682 to start a new conversion
      digitalWrite(CS, HIGH);
      return reading;
  }

void loop() { 
  double Dout;
  double out;
  double Vext;
 // double R = 7680.0; // Fixed resistance in the voltage divider
 // double Rt; // Computed resistance of the thermistor
   
  Dout =  MAX6682(); 
  Serial.print("digital out ");
  Serial.println(Dout);
   
  out = Dout*0.125;
  Serial.print("out ");
  Serial.println(out);
   
  Vext = 1.2370 *(Dout*0.010404/8 + 0.174387);
  Serial.print (Vext);
  Serial.println("  volts");
  Serial.println("");
 
 delay(1000); 
}

You haven't said what problems you are having. When you run the program, what does it print? Does what it prints depend on the temperature?

Also, does the shield you are using drop the voltage from the digital outputs on the Arduino to around 3.3 volts into the 6682?

RPCoyle:
Also, does the shield you are using drop the voltage from the digital outputs on the Arduino to around 3.3 volts into the 6682?

The MAX6682 is specified for Vcc up to 5.5V, so that isn't necessary, unless the MAX6682 has been powered from the 3.3V Arduino pin.

Yes the output depends on the temperature:
digital out 183.00
out 22.87
0.51 volts

digital out 186.00
out 23.25
0.51 volts

digital out 228.00
out 28.50
0.58 volts

digital out 229.00
out 28.62
0.58 volts

digital out 212.00
out 26.50
0.56 volts

according to the datasheet:
Dout = (Vrext / Vr+ - 0.174387) * 8 / 0.010404

but the value of Vrext computed does not match with the value I read with the multimeter. I'm powering the MAX6682 with the arduino 5V pin.

equation.png

Sorry LMVN, Looks like the MAX6682 has no problem with 5 volt inputs... I was thinking of the MAX6675 which needs 3.3 volts

Nevertheless, the value of Vr+ is not 1.220 V as stated in the datasheet. The value I read is 580 mV...

LMCM:
Nevertheless, the value of Vr+ is not 1.220 V as stated in the datasheet. The value I read is 580 mV...

The MAX6682 only powers Vr+ up while it is taking a reading.

What value are you using for Rext, and what thermistor are you using?

Rext = 6800 ohm
Thermistor 10 k ohm (AVX - NB20K00103KBA )

When the resistance of thermistor is 10K, the reading should be ((6.8/(10 + 6.8)) - 0.174387)) * 8 / 0.010404, which comes to 177. That's not far from the values you reported. What was the thermistor temperature or measured thermistor resistance when you got the reading of 183?

The thermistor is at 27.6 ºC, the thermistor value is 9125 ohm so the expected Dout = 194... I'm getting Dout = 189, for this situation (using the code below) the computed temperature is 26.57 ºC.

#include <SPI.h>
#define CS 53 //Selection Pin 
#define MISO  50//MISO 
#define SCK  52//Clock
int readvalue;

void setup(){ 
  Serial.begin(9600);

  //set pin modes 
  pinMode(SS, OUTPUT); 
  pinMode(MISO, INPUT); 
  pinMode(SCK, OUTPUT); 

  SPI.begin(); // initialize SPI, covering MOSI,MISO,SCK signals
  SPI.setBitOrder(MSBFIRST);  // data is clocked in MSB first
  SPI.setDataMode(SPI_MODE0);  // latched on rising edge, transitioned on falling edge, active low
}

int MAX6682()
{
  digitalWrite(CS, LOW);// Pull CS low and read out result of last conversion

  int hiByte = (int)(signed char)SPI.transfer(0);  // read high 8 bits and sign-extend
  uint8_t loByte = SPI.transfer(0);                // read low 4 bits + 4 dummy bits
  int reading = (int)(((unsigned int)hiByte << 3) | ((unsigned int)loByte >> 5));  // combine bytes
  
  digitalWrite(CS, HIGH);  // Set CS high again to allow other devices to use bus and tell the MAX6682 to start a new conversion
  return reading;
}

void loop() { 
  float Dout;
  float Rntc;
  float Vext;
  float Dref;
  double Rth;
  double Rfix = 6800;
  double Beta = 3630; // [K]  Parámetro Beta de NTC
  double R0 = 10000;
  double T0 = 298.15;
  float TempK;
  float TempC;
  double xx;
    
  Dout =  MAX6682(); 
  Serial.print("digital out ");
  Serial.println(Dout);

  Dref = ((6.8/(9.125 + 6.8) - 0.174387)) * 8 / 0.010404;
  Serial.print("expected digital out at 25 C => ");
  Serial.println(Dref);

  Vext = 0.52 *(Dout*0.010404/8 + 0.174387);
  Serial.print("Vext =  ");
  Serial.print (Vext);
  Serial.println("  volts");
  
 // Rntc = (Vext*6800)/(0.52-Vext);
  Rntc = ((Rfix * 0.52)/Vext - Rfix);
  Serial.print("NTC ");
  Serial.print(Rntc);
  Serial.println(" ohm");

  TempK = Beta/(log(Rntc/R0)+(Beta/T0));
  Serial.print("Temperature ");
  Serial.print(TempK);
  Serial.println(" Kelvin");
  
   TempC = TempK - 273.15;
  Serial.print("Temperature ");
  Serial.print(TempC);
  Serial.println(" Celcius");
  Serial.println(" ");

  delay(1000); 
}

output:
digital out 189.00
expected digital out at 25 C => 194.24
Vext = 0.22 volts
NTC 9383.48 ohm
Temperature 299.72 Kelvin
Temperature 26.57 Celcius

  1. How accurate is your 6k8 resistor, and how accurate is your multimeter? Your thermistor has a tolerance of +/- 10%, so that alone would account for the error, unless you are you have an accurate measurement of the resistance.

  2. Do you have the required 0.1uF decoupling capacitor, connected very close to the MAX6682 ?

  3. Is the ground side of the thermistor connected as closely as possible to the MAX6682, or is it sharing a ground wire that supplies power as well?

  4. To check the accuracy of the MAX6682, you could replace both the thermistor and Rext by 1% tolerance resistors of the same value (about 10K each), and compare expected and calculated readings.