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)
Messure temperature with a mega324
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.
There is no intern temp sensor.
the board have a stable 5V and run from a 16MHz xtal, so no problems there.
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.
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
Main question is how accurate is it!
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.
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:
#includevolatile 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.
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.