Messure temperature with a mega324

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have an existing project that uses mega324.
I'll try a use the change in watchdog timer speed to find a temperature of the chip.
So before I use time I will ask if anyone is using this method, and how accurate can the result be.
I would like to have an accuracy of 5 deg C within 10-50 C, and I only have time for a calibration at room temperature (20-25 C).
Is there any different way to do it? (that do not require components)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In practice, the internal temperature sensor is only about 5C accurate from the data sheet equations.
If you 'calibrate' it for 25C it should be plenty good enough for 10-50C.

Ah-ha. You want to use the Watchdog RC to check the temperature ! I am sure this is quite possible, but I doubt that it would be better than the internal temp sensor.

Looking at the Typical curves, the RC is fairly level with VCC but varies with temperature.

The obvious thing is to write a test program that uses both methods. Then compare.

Without a 'calibration', I would have zero confidence in the RC method. The internal bandgap is more closely controlled and reliable than either the R or the C.

Untested. Just me typing before engaging brain.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is no intern temp sensor.
the board have a stable 5V and run from a 16MHz xtal, so no problems there.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The ATmega328P has a temperature sensor.
It looks as if none of the ATMEGAxx4 family has the sensor. But you do have more ADC options. e.g. differential and amplifiers.

So you have no choice but attempt the RC.

I might play with both options on a 328P purely for comparison purposes.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

here's how I was trying to do it on a mega32.

float degc,degf;
float usec;  //actual usecs to write a byte, measured with xtal
float ratio; //measured to ideal (8448) usecs
float rcfreq;
float m,b,k;
unsigned int dt;
unsigned int ok;

//------8mhz rc osc vs temp---------------
//-40   25   80   degc  delta temp=120 degC
// 8300 8100 7740 KHz   delta freq=560 khz

//--------------------
void calcmb(void){
//rise=2degc run=.013mhz
//x1,y1=1mhz,25degc x2,y2=1.013mhz,23degc
//m= -153.846   b=178.846
//m= -2.0/.013; //rise/run
//b=178.846; //b=y-mx

  m= -0.214285; //rise=120 deg  run=560khz    -120/560 deg/khz
  b= 1760.7085; //b=y-mx        x,y=8100,25   b = 25- -0.214285*8100
  k=1.010;
}

//---------------------
void kup(void){

  k *= 1.001;
  cprintf("% 7.3f \r",k);
}

//---------------------
void kdn(void){

  k *= 0.999;
  cprintf("% 7.3f \r",k);
}

//--------------------
void calctemp(void){
//calc temperature by timing eeprom write timing,
//should take 8448 usecs using 1mhz clk. Colder is faster.
//timer1 with ps=2 counts 2mhz, overflows at 32768usec, 500ns per tic

  TCNT1=0;                     //clear timer
  ok=EEPROMwrite(0x1023,0xff); //write an ff to last eeprom loc
  while(EECR & 0x02){};        //bit 2 is we   wait for eeprom write (8448 usecs)
  dt=TCNT1;                    //number of 500ns t1 tics 500ns with ps=2, div by 8
  usec=((float)dt)*0.500;      //cvt 500ns tics to actual realtime usecs
  ratio=8448.0/usec;           //ratio of normal to measured freq 8448usec=25 degc
  rcfreq=8100.0*ratio*k;       //KHz
  degc= m*rcfreq + b;          //
  degf=degc*1.8+32.0;
  cprintf("tics  usecs   ratio   k       rcfreq  degc    degf \n");
  cprintf("% 5d % #7.1f % #7.3f % #7.3f % #7.3f % #7.1f % #7.1f \n",
    dt,usec,ratio,k,rcfreq,degc,degf);
}

Have to change pct space back to pct

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Main question is how accurate is it!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The graphs in the ds are sort of averages, so I'd say the reading would have to be calibrated once to be within a few deg. I think.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From the "Figure 29-172.ATmega328P: Watchdog Oscillator Frequency vs. Temperature", the typical frequency varies by 5.5kHz in 60C i.e. 90Hz/C or 0.45kHz per 5C @ 115kHz
So I wrote an Arduino sketch:

#include 

volatile uint16_t wdt_cycles;

void setup(void)
{
    TCCR1A = 0;
    TCCR1B = (3<<CS10);      // 16MHz div64 = 250kHz (4us)
    cli();
    wdt_reset();
    WDTCSR = (1<<WDCE);    //timed sequence only needed for WDE
    WDTCSR = (1<<WDIE) | (0<<WDP0);  // just use interrupt
    sei();
    Serial.begin(9600);
    Serial.println("Hello WDT set for 16ms interrupt");
}

void loop(void)
{
    uint16_t cycles = wdt_cycles;
    Serial.print("WDT_cycles = ");
    Serial.print(cycles);
    Serial.print(" WDT period(ms) = ");
    Serial.print(0.004 * cycles);
    Serial.print(" WDT freq(kHz) = ");
    Serial.print(250.0 * 2048.0 / cycles);
    Serial.println();
    delay(1000);
}

#define SAMPLES 8
ISR(WDT_vect)
{
    static uint16_t prev, n, count_buf[SAMPLES];
    uint16_t current = TCNT1;   // IRQ latency affects value
    count_buf[n] = current - prev;
    prev = current;
    if (++n >= SAMPLES) n = 0;
    current = 0;
    for (uint8_t i = 0; i < SAMPLES; i++) current += count_buf[i];
    wdt_cycles = current / SAMPLES;
}

In practice, I put my finger on the TQFP and the freq goes from 116.02kHz to 115.73kHz which is 270Hz or 3C!

Seeduino 328:

WDT_cycles = 4196 WDT period(ms) = 16.78 WDT freq(kHz) = 122.02

Seeduino 328:

WDT_cycles = 4411 WDT period(ms) = 17.64 WDT freq(kHz) = 116.07

UNO clone:

WDT_cycles = 4054 WDT period(ms) = 16.22 WDT freq(kHz) = 126.30

So I would not recommend the method !

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But the whole idea is to measure how much the temperature dependent freq pulls, in order to use it as a temp sensor? Sounds like its working if the freq changes when you put your finger on it. Note that I actually use a y=mx+b from the chart in the datasheet to back calc the temp from the freq.

Imagecraft compiler user