View previous topic :: View next topic |
Author |
Message |
MCUprogrammer
Joined: 08 Sep 2020 Posts: 221
|
LM35DZ reading |
Posted: Wed Jan 11, 2023 2:22 am |
|
|
CCS 5.113
Hello
I want to read temperature with LM35DZ. I'm trying to read fast and print the correct value on the screen. It reads the temperature, but the temperature always increases by 2 degrees. I haven't seen 0.1 precision. But when I look with an avometer, the millivolts are increasing one by one. What should I do?
Code: |
#include <16F886.h>
#fuses NOWDT
#device ADC = 8
#use delay(crystal = 20MHz)
#define LCD_ENABLE_PIN PIN_B1
#define LCD_RS_PIN PIN_B0
#define LCD_RW_PIN 0
#define LCD_DATA4 PIN_B2
#define LCD_DATA5 PIN_B3
#define LCD_DATA6 PIN_B4
#define LCD_DATA7 PIN_B5
#include <lcd_rw.c>
#define ADC_VREF_VOLTAGE 4.90
#define ADC_RESOLUTION 255
void main(void)
{
unsigned int8 LM35Value = 0;
float LM35Voltage = 0.0;
float LMtemp = 0.0;
lcd_init();
setup_adc_ports(sAN0 | sAN1 | sAN2,VSS_VDD);
setup_adc(ADC_CLOCK_DIV_32);
while(TRUE)
{
set_adc_channel(0);
delay_us(20);
LM35Value = read_adc();
LM35Voltage = ((ADC_VREF_VOLTAGE / ADC_RESOLUTION )*LM35Value)*1000; //The voltage value of the signal in mV is calculated after the digital conversion process.
LMtemp = (LM35Voltage / 10); // 1 degree increment every 10mV
lcd_gotoxy(1,1);
printf(lcd_putc, "Temp(LM):%2.1f%cC ",LMtemp,223);
}
}
|
_________________ Best Regards...
MCUprogrammer
_______________________________
Work Hard |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Jan 11, 2023 6:08 am |
|
|
Wow, someone using my favorite analog temperature sensor !
A 5 volt range / 8 bits gives you .01960 volts per bit.
You need to change a couple of items
1) configure the ADC to read 10 bits instead of 8
2) change the ADC data variable to 16 bits.
3) change adc resolution variable to 10 bits.
It's hard for me to see light green on white (joys of being 70 this year ? ).
I used of 100s of the LM35DZ for my remote energy control systems, never had any problems with them. Be sure to power from a well filtered supply. I had .68mfd cap on the output to 'smooth' the response. Since 'temperature control' is a slow process,consider using the 'Olympic averaging' method. You read the sensor 10 times, toss out the highest and lowest reading, then average the 8 remaining. It's both fast and accurate. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Wed Jan 11, 2023 6:27 am |
|
|
and (of course), using the supply for Vref, decreases massively the
accuracy you will be able to achieve.
Also, save maths!...
Code: |
LMtemp= ((ADC_VREF_VOLTAGE / ADC_RESOLUTION )*LM35Value)*100; //The voltage value of the signal in mV is calculated after the digital conversion process.
//LMtemp = (LM35Voltage / 10); // 1 degree increment every 10mV
|
Pointless to multiply by 1000, then divide by 10. Results in larger code
and a lot of extra time. Just multiply by 100, and you have the required
result!... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Jan 11, 2023 8:29 am |
|
|
hmm...just thought of this
using 'scaled integers' instead of 'float point math' is a LOT faster, smaller code and more accurate... |
|
|
MCUprogrammer
Joined: 08 Sep 2020 Posts: 221
|
|
Posted: Thu Jan 12, 2023 7:58 am |
|
|
Hi
Yes, I did what you said yesterday. I saw it increase 0.5 degrees. I removed the olympic reading. I threw a 1uf capacitor to the ADC input, it reads very stable. But what I want to do is increase it by 0.1 degree. How can I do that. _________________ Best Regards...
MCUprogrammer
_______________________________
Work Hard |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Jan 12, 2023 8:12 am |
|
|
Please post your program so we 'copy/paste/compile/test.
Jay |
|
|
MCUprogrammer
Joined: 08 Sep 2020 Posts: 221
|
|
Posted: Thu Jan 12, 2023 8:16 am |
|
|
Code: |
#include <16F886.h>
#fuses NOWDT
#device ADC = 10
#use delay(crystal = 20MHz)
#define LCD_ENABLE_PIN PIN_B1
#define LCD_RS_PIN PIN_B0
#define LCD_RW_PIN 0
#define LCD_DATA4 PIN_B2
#define LCD_DATA5 PIN_B3
#define LCD_DATA6 PIN_B4
#define LCD_DATA7 PIN_B5
#include <lcd_rw.c>
#define ADC_VREF_VOLTAGE 4.90
#define ADC_RESOLUTION 1023
#define samples 10
int16 sum,max,min;
unsigned int16 LM35_adcvalue;
float LMtemp = 0.0;
void main(void)
{
lcd_init();
setup_adc_ports(sAN0 | sAN1 | sAN2,VSS_VDD);
setup_adc(ADC_CLOCK_DIV_32);
while(TRUE)
{
set_adc_channel(0);
delay_us(50);
LM35_adcvalue = read_adc();
LMtemp = ((ADC_VREF_VOLTAGE / ADC_RESOLUTION )*LM35_adcvalue)*100; //The voltage value of the signal in mV is calculated after the digital conversion process. 1 degree increment every 10mV
lcd_gotoxy(1,1);
printf(lcd_putc, "Temp(LM):%2.1f%cC ",LMtemp,223);
}
} |
_________________ Best Regards...
MCUprogrammer
_______________________________
Work Hard |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Jan 12, 2023 9:08 am |
|
|
hmm..
LM35 is 10mv/*C so...
21.0*C = 210 mv
21.1*C = 211 mv
21.2*C = 212 mv
Vref= 4.90 volts
10 bit ADC (1024 bits)
4.90 /1024 is .004785 , so really 5 mv resolution ( 1 bit = 5mv )
so...you need to have a .5*C change in temperature before the PIC can compute the change. IE it 'sees' 21.1 the same as 21.2...
You need to feed the LM35 into a x5 opamp to increase the resolution.
This means a temperature of 21.0*C sends 1.050 volts to the PIC's ADC.
Now you'll be able to 'see' the small change.
You'll need to do some testing to see what the actual opamp gain is ,even with 1% reisitors, you won't get exactly a gain of 5, so you'll need to multiply by the real gain value. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 478 Location: Montenegro
|
|
Posted: Thu Jan 12, 2023 9:43 am |
|
|
As mentioned in a previous post, you can't reach 0,1deg with your current setup. Each step of A/D is 4,78mV and you want to detect 1mV change. Won't happen.One solution was offered with an opamp. Another solution is to use an external voltage reference for ADC, say 1,024V (one point zero two four volts ). In that case you get exactly 1mV ADC resolution or 0,1deg. The limitation is that you can measure only up to 102 degrees. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Fri Jan 13, 2023 1:48 am |
|
|
Worth possibly pointing out that though the IC itself has a resolution of
0.1C, it only has an 'accuracy' of 0.5C. The non linearity is also only
0.25C, so though with a more accurate ADC, he could display 0.1C
steps, these will really be meaningless.
He could get a resolution of 0.24C, by switching to using a 2.5v reference.
This would then give 0.24C/step of the ADC, and with a proper reference
the result will be much more repeatable and accurate. |
|
|
MCUprogrammer
Joined: 08 Sep 2020 Posts: 221
|
|
Posted: Fri Jan 13, 2023 2:58 am |
|
|
So how do I write a code for VREF 1024 on the PIC18F45K22 processor. I have added the following code of the header file. Code: |
setup_vref(VREF_1v024);
setup_adc_ports(sAN0, VSS_FVR); |
_________________ Best Regards...
MCUprogrammer
_______________________________
Work Hard
Last edited by MCUprogrammer on Fri Jan 13, 2023 3:50 am; edited 4 times in total |
|
|
MCUprogrammer
Joined: 08 Sep 2020 Posts: 221
|
|
Posted: Fri Jan 13, 2023 3:38 am |
|
|
when i use VDD
(4.90 / 1023)*adcval)*100;
~23 degrees adcval : 48
It shows ((1.024/1023)*48)*100 = 4.80 degrees. So how do I set this up properly? _________________ Best Regards...
MCUprogrammer
_______________________________
Work Hard |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Fri Jan 13, 2023 7:05 am |
|
|
re: Vref. of 1.024.
OK, it took me ahwhile to find this (buried in the AC characteristics pages, not the DC ones....
According to table 27-21 of the datasheet, parameter A21...
Vrefhigh for the ADC must be a MINIMUM of VDD/2
Which means for a VDD of 5 volts, Vref to the ADC must be >_ to 2.5 volts, so you can't use 1.024.
you should post the raw ADC numbers(ADCvalue) as well as the calculated temperature.
it could be a 'math' problem or 'casting' |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Fri Jan 13, 2023 7:15 am |
|
|
You cannot use 1.024 as the Vref for the ADC. The minimum Vref for
the ADC to work properly is 2.2v. Your chip does not have a proper internal
Vref. The programmable voltage is just a division of the supply. The
internal fixed voltage reference cannot be used to feed the ADC, it is
just a voltage that can be _read_ by the ADC to given a measure of
the supply voltage. Very low accuracy. You need to add a hardware
external voltage reference.
From the data sheet:
Quote: |
The ADC voltage reference is software selectable to
either VDD or a voltage applied to the external reference
pins.
|
|
|
|
MCUprogrammer
Joined: 08 Sep 2020 Posts: 221
|
|
Posted: Fri Jan 13, 2023 7:47 am |
|
|
So what do I do to measure with 0.1 precision? _________________ Best Regards...
MCUprogrammer
_______________________________
Work Hard |
|
|
|