Go Down

Topic: Hooking up a 10K NTC Thermistor to an LTC2440 (Read 1 time) previous topic - next topic

Pebbles

Hello everybody,

Disclaimer: I am not and electronics expert, my knowledge is limit so please bear with me :)

I'm doing some research to find the limit of a cooling solution i'm using. I'd would like to measure the temperature stability, not accuracy.
I ordered the Linear DC570A demoboard in the hopes I could hook up a 10K NTC thermistor to it very easily.

I was wrong.  =(

I go the interface running using the following topic Link.

made some adjustments and got the following sketch
Code: [Select]
/*
 Interface between Arduino DM board and Linear Tech LTC2440 24-bit ADC
 Nov. 12 2010 John Beale

  LTC2440  <---------->  Arduino
  11: /CS <- to digital pin 10  (SS pin)
   7: MOSI <- to digital pin 11 (MOSI pin)
  12: MISO -> to digital pin 12 (MISO pin)
  13: SCLK <- to digital pin 13 (SCK pin)
  10: /EXT - ground
   1: GND - ground
   2: VDD3 - 5V supply

*/

#include <SPI.h>  // include the SPI library

// set I/O pins used in addition to clock, data in, data out
const byte slaveSelectPin = 10;  // digital pin 10 for /CS
const byte resetPin = 9;  // digital pin 9 for /RESET
const int nsamples = 5;  // how many ADC readings to average together

// SPI_CLOCK_DIV16 gives me a 1.0 MHz SPI clock, with 16 MHz crystal on Arduino

void setup() {
 
   Serial.begin(115200);      // set up serial comm to PC at this baud rate
   
   pinMode (slaveSelectPin, OUTPUT);
   pinMode (resetPin, OUTPUT);
   digitalWrite(slaveSelectPin,HIGH);  // chip select is active low
   digitalWrite(resetPin,HIGH);  // reset is active low

   SPI.begin(); // initialize SPI, covering MOSI,MISO,SCK signals
   SPI.setBitOrder(MSBFIRST);  // data is clocked in MSB first
   SPI.setDataMode(SPI_MODE0);  // SCLK idle low (CPOL=0), MOSI read on rising edge (CPHI=0)
   SPI.setClockDivider(SPI_CLOCK_DIV16);  // system clock = 16 MHz, chip max = 1 MHz
   
   Serial.println("LTC2440 Test");
}

#include <math.h>

float vcc = 5.00;                       // only used for display purposes, if used
// set to the measured Vcc.
float pad = 10000;                       // balance/pad resistor value, set this to
// the measured resistance of your pad resistor
float thermr = 10000;                   // thermistor nominal resistance

float Thermistor(long RAWADC) {
long Resistance;  
float Temp;  // Dual-Purpose variable to save space.

Resistance=((16777216 * pad / RAWADC) - pad);
Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
Temp = 1 / (0.000831166375923117 + (0.000256436021065264 * Temp) + (0.000000206045827449766 * Temp * Temp * Temp));
Temp = Temp - 273.15;  // Convert Kelvin to Celsius                      

// BEGIN- Remove these lines for the function not to display anything
//Serial.print("ADC: ");
//Serial.print(sum);
//Serial.print("/1677216");                           // Print out RAW ADC Number
//Serial.print(", vcc: ");
//Serial.print(vcc,2);
//Serial.print(", pad: ");
//Serial.print(pad/1000,3);
//Serial.print(" Kohms, Volts: ");
//Serial.print(((sum*vcc)/1677216.0),3);  
//Serial.print(", Resistance: ");
//Serial.print(Resistance);
//Serial.print(" ohms, ");
// END- Remove these lines for the function not to display anything

// Uncomment this line for the function to return Fahrenheit instead.
//temp = (Temp * 9.0)/ 5.0 + 32.0;                  // Convert to Fahrenheit
return Temp;                                      // Return the Temperature
}

// =============================================================================
// Main Loop:
// acquire 'nsamples' readings, convert to units of volts, and send out on serial port

void loop() {

int i;
long secs;
float mins;
double volts;
long in;         // incoming serial 32-bit word
long sum = 0;
float temp;
long RAWADC;

   for (i=0; i<nsamples; i++) {
     in = SpiRead();
     in &= 0x1FFFFFFF; // force high three bits to zero
     in = in>>5;   // truncate lowest 5 bits
     sum += in;
     delay(198);      // (msec). Total Looptime: +2 msec (overhead for comms)
   }

   // volts =  in * 2.5 / 8.388607;  // 0x7fffff = 8388607
   volts = sum * (0.2980232594);  // microvolts
   volts = volts / nsamples;
   RAWADC = sum / nsamples;

   mins = (float) millis() / 60000;   // elapsed time in minutes
temp=Thermistor(RAWADC);       // read ADC and  convert it to Celsius
   Serial.print(volts);
   Serial.print(", ");
   Serial.print(RAWADC);
   Serial.print(", ");
   Serial.println(temp,3);                             // display Celsius

} // end main loop


// =================================================================
// SpiRead() -- read out 4 bytes from LTC2440 chip via SPI interface
// =================================================================

long SpiRead(void) {

 long result = 0;
 long b;
 
//  long result2 = 0;// MOSI/SDI pin 7 HIGH => 7 Hz, best resolution

 digitalWrite(slaveSelectPin,LOW);   // take the SS pin low to select the chip
 delayMicroseconds(1);              // probably not needed, only need 25 nsec delay
 
 b = SPI.transfer(0xff);   // B3
 result = b<<8;
 b = SPI.transfer(0xff);   // B2
 result |= b;
 result = result<<8;
 b = SPI.transfer(0xff);   // B1
 result |= b;
 result = result<<8;
 b = SPI.transfer(0xff);   // B0
 result |= b;
 
 // take the SS pin high to de-select the chip:
 digitalWrite(slaveSelectPin,HIGH);
 return(result);
}


I get readings up to 25C and an RAWADC value of 16777216 /2
It will not go up further then this no matter how i connect the thermistor.
any other connection I tried doesn't give me the correct temperature.

I connected it to the DC570A as followed:
From REF+ to 10K Resistor

From 10K Resistor to 10K Thermistor
From 10K Resistor to IN+

From 10K Thermistor to IN -

IN- is connected straight to GND

Could I get some advice on how to get the full range of the 10K Thermistor?

dhenry

A few things:

1) 99.9% of the seasoned engineers cannot get a 24-bit adc to work. It requires tremendous amount of know-how and art of engineering (layout in particular).

2) One approach to get usable data out of a high resolution adc is to average. It has its downside.

3) In your case, you should get at room temperature close to half of full scale and it varies with temperature.

4) For what you do, the onboard adc is perfectly fine.

Pebbles


A few things:

1) 99.9% of the seasoned engineers cannot get a 24-bit adc to work. It requires tremendous amount of know-how and art of engineering (layout in particular).

2) One approach to get usable data out of a high resolution adc is to average. It has its downside.

3) In your case, you should get at room temperature close to half of full scale and it varies with temperature.

4) For what you do, the onboard adc is perfectly fine.



1). I understand that, that is why I ordered the DC570A demoboard, this is designed to use the LTC2440 within spec.

2). the sketch already averages the values it reads from the DC570A

3). I don't understand what u mean with that. Currently when I hold the thermistor between my figures, it start rising to 25C and stops as soon as it hits it.

4). I do need it. I have used a 12-bit ADC controller(which is closed source and I can't change) which gave me 0,03C resolution. I can easily keep my process stable at that. I want to go further.
24-bit my be overkill but I want try and get that. 20-bit would also be good, but the goal is 24-bit.

dhenry

3) put a probe on the junction of the 10k resistor / 10k ntc and apply heat on the ntc. You should see readings change. If you don't observe corresponding changes in the adc's output, the issue is with your code. Otherwise, with your ntc/resistor divider.

4) I don't know what your system is but controlling temperature to 0.03c is *extremely* ambitious.


Pebbles


3) put a probe on the junction of the 10k resistor / 10k ntc and apply heat on the ntc. You should see readings change. If you don't observe corresponding changes in the adc's output, the issue is with your code. Otherwise, with your ntc/resistor divider.

4) I don't know what your system is but controlling temperature to 0.03c is *extremely* ambitious.




3). I have measured and I see the value changing. at some point read out in the arduino stops changing but the value I measure over the voltage divider is still changing.
I read in the datasheet that IN+ is +VREF/2 and IN- is -VREY/2
Would this mean I only use half of the measurement range which would be -2,5V to +2,5V and I am using 0V to +2,5V?

4). It's not that hard for the system, that's why I want to try and find the limit.

dhenry

Quote
I read in the datasheet that IN+ is +VREF/2 and IN- is -VREY/2
Would this mean I only use half of the measurement range which would be -2,5V to +2,5V and I am using 0V to +2,5V?


Since you are not measuring differentially, have two options:

1) increase the 10k resistor's value. Make it a 20k for example.
2) flip the divider: so that as temperature rises the divider's output goes down from Vref/2. This approach works if you expect temperature to go up from room temperature.

Pebbles


Quote
I read in the datasheet that IN+ is +VREF/2 and IN- is -VREY/2
Would this mean I only use half of the measurement range which would be -2,5V to +2,5V and I am using 0V to +2,5V?


Since you are not measuring differentially, have two options:

1) increase the 10k resistor's value. Make it a 20k for example.
2) flip the divider: so that as temperature rises the divider's output goes down from Vref/2. This approach works if you expect temperature to go up from room temperature.


Alright I'll try and increase the 10k resistor value and see if that works.
I'll let you know if it has worked.

Pebbles

I've tried a 20k resistor and it did not work.
I then used a 150 ohm resistor, this worked. I am getting higher values now.

I will continue experimenting a bit with this.

dhenry

For it to work for your chip, you need a ntc on bottom of the divider; or a ptc on the top of the divider -> so when temperature rises, the output voltage goes down.

Go Up