View previous topic :: View next topic |
Author |
Message |
hemnath
Joined: 03 Oct 2012 Posts: 242 Location: chennai
|
LMT85 temperature sensor measurement |
Posted: Wed Aug 12, 2020 8:22 am |
|
|
HI,
PIC18F2620, Crystal: 1Mhz internal oscillator
LMT85 temperature sensor.
Code: |
#device ADC=10
float adc_value;
//main
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0);
setup_comparator(NC_NC_NC_NC);
|
Code: |
void temperature_meas()
{
unsigned int16 adc_read;
float sqrt_value;
set_adc_channel(0);
delay_us(20);
adc_read = read_adc();
adc_value = (float) adc_read;
sqrt_value = sqrt(((-10.888) * (-10.888)) + (4 * 0.00347 * (1777.3 - adc_value))); // formula taken from datasheet
adc_value = ((10.888 - sqrt_value)/(2 * (-0.00347))) + 30;
lcd_cmd(0x80);
printf(lcd_data, "%3.1f C", adc_value);
}
|
Displaying incorrect temperature value. Please help. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Wed Aug 12, 2020 8:42 am |
|
|
All the equations, assume you have Vadc, in mV. You don't.
Assuming 5v supply, then:
adc_value = adc_read*4.8828;
(5000/1024 steps) |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Thu Aug 13, 2020 6:18 am |
|
|
just a comment...
Floating point math takes a very,very long time with a PIC so it's best to run the PIC at maximum clock rate.
You'll have to recode the ADC setup for it's clock rate (info is in the ADC section of the datasheet).
You can use 'scaled integers' instead of FP math. They are a LOT faster. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Thu Aug 13, 2020 6:30 am |
|
|
and (of course), if you do increase the clock frequency, you will have to
change the ADC clock source. 'Internal' is not recommended above 1Mhz. |
|
|
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
Integer Math rules |
Posted: Mon Aug 31, 2020 10:54 am |
|
|
I try to avoid any floating point math due to the
speed hit and inacurracy.
Convert your formula into large integers for enough accuracy as needed.
Likely, you only need 1 degree C accuracy since the sensor has worse accuracy.
Example using MCP9701 temp sensor:
Code: |
#DEFINE MCP9701offset 400
#DEFINE MCP9701scale 1950
void MeasureTemp() { // uses MCP9701A temp senser
int32 j=0;
int16 a;
a=GetADC(TempCH);
// fast 1st order FIR averaging
Monitor.TempRaw=FIRavg(a,Monitor.TempRaw);
j=Monitor.TempRaw&0xFFFF;
j*=Vreference; j/=ADCscale; // scales to ~ 1mV/count
if(j>MCP9701offset) {
j-=MCP9701offset;
j*=Thermal.gain; // 100=100% coef from eerom
if(j>MCP9701scale) { j/=MCP9701scale; }
if(Thermal.offset>100) { j+=(Thermal.offset-100); } // coef from eerom
if(Thermal.offset<100) { j-=(100-Thermal.offset); }
}
else {j=0;}
XferLW.asLong=j; // use a union to change long into word
Monitor.DegC=XferLW.asWord[0]; // read 0C minimum, 127C max
//.... look for over/under temp, set flags, yada yada...
} |
;-) |
|
|
|