PDA

View Full Version : 16f877 with LM335 problem



CrazyCooter
- 12th January 2007, 07:11
Hi all,

am having problem with displaying deg C using the LM 335 temp sender
i believe i have set the AD settings right for 16F877 RA0 pin
have attached the prog and circuit

thanks

HenrikOlsson
- 12th January 2007, 08:56
Hi,
I've never used this sensor but are you sure you have it wired correct?
As in you schematic,viewed from the top with the flat side "up" the left most pin should be GND. The middle pin then goes to the analog in of the PIC with a 12k pullup. At least that's how I read the datasheets example for the basic temp sensor circuit.

/Henrik Olsson.

Acetronics2
- 12th January 2007, 09:03
Hi, Cooter

Your conversion formula is wrong ...

°K = °C +273.15... and your scaling doesn't meet anything known.

now, you MUST Download your sensor datasheet ... and wire it decently.

Can't work at this time !!!

Alain

skimask
- 12th January 2007, 14:31
Hi, Cooter

Your conversion formula is wrong ...

°K = °C +273.15... and your scaling doesn't meet anything known.

now, you MUST Download your sensor datasheet ... and wire it decently.

Can't work at this time !!!

Alain

Oh ya, that circuit's is out in the weeds somewhere.
And when you do get it working, the easiest way I've found to calibrate the system is to dip the sensor in ice water and set the reading to match, not change any resistors or rewire anything, just adjust the math on the PIC to match.
And are you sure the A/D is working right? Have you tried putting a pot across the A/D input? Does that respond correctly?

CrazyCooter
- 16th January 2007, 07:49
hi all,
am trying to understand how to implament the ADC on the pic 16f877
my code is for a LM335 temp sensor connected to RA0(pin 2)
the VDD and VSS is from a 7805 voltage reg that also supplies the LM335

Cant get ADC to work from my circuit. or is it my code??????????????
why cant i use decimal ie 0.46 in my maths routine?????????????

This has had me up all week trying to get it to work

PLZ someone guide me in the correct direction


'PIC 16f877 with a LM335 temp sender
'
'
define osc 20 ' 20mhz oscillator
' LCD ROUTINES
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4 '4,5,6,7
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 3
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 2
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
' Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
define ADC_CLOCK 3 ' Set clock source
Define ADC_SAMPLEUS 50 ' Set sampling time in uS
AD_RAW var word ' Create adval to store result
AD_RESULT var word


TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10001110 ' Set PORTA analog and RIGHT justify result
ADCON0 = %10000001 ' Configure and turn on A/D Module

Pause 500 ' Wait .5 second

loop:
ADCIN 0, AD_RAW ' Read channel 0 to ad_raw
AD_RESULT = (ad_raw *0.48828) - 273.15 ' Convert Kelvins to Degrees C

Lcdout $fe, 1 ' Clear LCD
Lcdout "TEMP ", DEC AD_Result ," C" ' Display the decimal value

Pause 100 ' Wait .1 second

Goto loop ' Do it forever
End

Ioannis
- 16th January 2007, 08:42
Did you really bought the copy of PBP you have????

Did it came with it a MANUAL ???

Did you read the MANUAL ????

Didn't find any reference as to that PBP is NOT supporting floating maths ???

I am looking forward to you replying to the above so that we can continue support here.

Ioannis


P.S. If you are just connect the sensor to the PIC directly, your useful range will be limited (0C-100C is from 2,7315 to 3,7315 Volts). I suggest to use opamps and extend the range of the sensor from 0C->0Volts to 100C->5 Volts.

skimask
- 16th January 2007, 14:14
Did you really bought the copy of PBP you have????

Did it came with it a MANUAL ???

Did you read the MANUAL ????

Didn't find any reference as to that PBP is NOT supporting floating maths ???



Amazing isn't it?

savnik
- 16th January 2007, 14:34
Did you really bought the copy of PBP you have????

Did it came with it a MANUAL ???

Did you read the MANUAL ????

Didn't find any reference as to that PBP is NOT supporting floating maths ???

I am looking forward to you replying to the above so that we can continue support here.


Ton pethanes ton anthropo.

skimask
- 16th January 2007, 15:10
Ton pethanes ton anthropo.

Wish I spoke it! :)
Even google'd it...everything came up in Greek. Imagine that! I'm lost :)

savnik
- 16th January 2007, 15:48
Ton pethanes ton anthropo.
You die the man

Acetronics2
- 16th January 2007, 19:20
You die the man

Sorry,

but what do you mean ??? ...

Alain

savnik
- 16th January 2007, 20:20
Sorry,

but what do you mean ??? ...

Alain
The translation is not exactly.
In greek is a metaphoric phrase.

CrazyCooter
- 17th January 2007, 05:21
Did you really bought the copy of PBP you have????

Did it came with it a MANUAL ???

Did you read the MANUAL ????

Didn't find any reference as to that PBP is NOT supporting floating maths ???

I am looking forward to you replying to the above so that we can continue support here.

Ioannis


P.S. If you are just connect the sensor to the PIC directly, your useful range will be limited (0C-100C is from 2,7315 to 3,7315 Volts). I suggest to use opamps and extend the range of the sensor from 0C->0Volts to 100C->5 Volts.

thanks for the quick responce

got PBP 2.47 from DONTRONICS here in melbourne

Yes. Read the 213 pages and even been looking up web sites with references. downloaded the data sheet read the A2D converter module.. CH 11 pg 127

ok just found 1 error in setting the TRISA had 8 bits set to 1 should have been 6 ie TRISA %111111 not TRISA %11111111

still not workin. even connected a 5k lin pot and got no responce.


and as Ioannis said using an opamp to extend the range i will be now

MY CODE WILL NOT COMPILE WITH THIS LINE
AD_RESULT = (ad_raw *0.48828) - 273.15

Had to do it this way
ad_result = (ad_raw * 48828)/1000
ad_result = ad_result/100
ad_result = (ad_result *27315)/100
WHY????????????????????????????????????????
HMMMMMMM very frustrating

skimask
- 17th January 2007, 05:29
MY CODE WILL NOT COMPILE WITH THIS LINE
AD_RESULT = (ad_raw *0.48828) - 273.15

Had to do it this way
ad_result = (ad_raw * 48828)/1000
ad_result = ad_result/100
ad_result = (ad_result *27315)/100
WHY????????????????????????????????????????
HMMMMMMM very frustrating

What do you mean why? Did you read the post earlier? Did you really read it? Let me quote one line from that earlier post:

"Did you read the MANUAL ????

Didn't find any reference as to that PBP is NOT supporting floating maths ???"

How many times do we have to point out to you that PBP does not support floating point math! And if you don't understand the term 'floating point', well, quite frankly 'floating point' means that the decimal is 'floating'...it can move wherever it needs to go according to the math being performed!
PBP DOES NOT SUPPORT FLOATING POINT MATHS! The decimal point is stuck in one place, all the way to the right, no matter what you do, the decimal point will always be to the right...no fractions, no tenths, no hundreths, no nothing. If you divide 10 by 3, you'll get 3, nothing more nothing less. If you use the remainder function, yes, in the case above, you'll get a 1 from it, but it's still not FLOATING POINT...

Somebody get me a drill!!!

CrazyCooter
- 17th January 2007, 06:31
Thanks skimask for pointing that out.

ok so i am 1 step closer to getting this to work now.

so the only way to do floating point maths then is with asm right?

and thats why my code will not work correctly with the LM335 and the ADC?

Acetronics2
- 17th January 2007, 07:19
QUOTE << Hi, Skimask

You can also remember Every number can be close-rounded as the division of two integers ... ( PI = 22/7 i.e. )

That give some brain work to find the couple of the year ... but a small GWBASIC ( LOL !!! ) program can easily sort them.

With the use of the DIV32 function ... that enables more than you ever dreamed !!!

Alain >>

Hi, Scooter

Sometimes, life is really funny ... that comes from 5 threads down on the list ...

Ioannis
- 17th January 2007, 09:12
Sorry,

but what do you mean ??? ...

Alain

What savnik (Geia sou!) said was that I made too many questions like in an interrogation, one after another, so I exhausted him to death!

Sorry for that, I couldn't resist...

As for the floating maths, CrazyCooter, you can do real maths with the routines from Microchip (check the melabs site for this), write your own routines, use decimal numbers only with tricks that were many times discussed here or do not use decimal at all.

For example, 2.3 may be represented as 23 and displayed as "2", ".", "3"

Also check the manual and forum for applications of DIV32, */ and // operators. These are what you need to do the job.

Ioannis

Acetronics2
- 17th January 2007, 09:25
Thanks Ioannis,

The man dies, when you KILL the man ...

I just didn't understant who was who ...

Alain

skimask
- 17th January 2007, 13:34
Thanks skimask for pointing that out.

ok so i am 1 step closer to getting this to work now.

so the only way to do floating point maths then is with asm right?

and thats why my code will not work correctly with the LM335 and the ADC?

Sure, because a byte/word/bit/whatever has a decimal point in it when written in plain text...

It's possible to do plenty of floating point when using straight PBP, as many digits as you want, as much accuracy as your heart desires......the question is, can you?

CrazyCooter
- 18th January 2007, 07:03
It's possible to do plenty of floating point when using straight PBP, as many digits as you want, as much accuracy as your heart desires......the question is, can you?

I have no understanding of asm so would take me a very long time to understand and implement.

2 decimal places is more than accurate enought for what i want to be doing
and all the adc will be from 0V to 5V in 10 bit

as Ioannis said "check the manual and forum for applications of DIV32, */ and // operators. These are what you need to do the job."

thanks everyone see how i go trying this

flotulopex
- 10th April 2015, 22:18
If you are just connect the sensor to the PIC directly, your useful range will be limited (0C-100C is from 2,7315 to 3,7315 Volts). I suggest to use opamps and extend the range of the sensor from 0C->0Volts to 100C->5 Volts.

Can anyone please help me with a schematic on how to achieve what Ioannis is suggesting or is the example below not far away from what I'm looking for?

How do I "electronically" rescale 2,7315Volts to an ideal "0V" and/or a 3,7315Volts to an ideal "5V"?

I don't know... :confused:

As I'd like to use my sensor to control a freezer, the temperature range I need goes from -30°C to +30°C.

I found quite some info, for example here (http://cirkitguy.blogspot.ch/2012/11/smart-digital-thermometer-design1.html) and I've already ordered some LM358 opamps to build this circuit.

It looks like this circuit will output 0V at 0°C and 1V at 100°C. It is still "loosing" 4 precious volts, isn't it?

How can this circuit be modified to, again ideally, match something like -30°C = 0V and +30°C = 5V?



http://2.bp.blogspot.com/-p6gsR7BJo-I/UJav9V4F8DI/AAAAAAAAACo/lWTHB0MALVg/s1600/123.jpg

Aussie Barry
- 11th April 2015, 01:05
Why not use the LM35?
This sensor is calibrated directly in Celcius, has a linear 10mV/degree C scale factor, is rated for -55 to +150 C range and does not require any external calibration or trimming to provide typical accuracies of =/-0.25C at room temperature and +/-0.75C over the full -55 to +150C range.

Cheers
Barry
VK2XBP

flotulopex
- 11th April 2015, 11:14
Thanks for the idea Barry.

It's just, I have a LM335 in the drawer.... ;)

I can give it a go with the LM35 - need to order one but here, in Switzerland, the LM35 is ten times more expensive than the LM335 :mad:

Anyway, I would still like to understand how the LM335 could be used with an opamp.

Ioannis
- 13th April 2015, 16:28
Attached is one idea. First op-amp works as an adder (or subtracter). It removes the DC offset voltage from the + input. So output is around 0-0,58 volts for -30 to 30 deg.

Then the second op-amp works as an DC amplifier to boost the 0,58 to 5 volts. So you have to make two adjustments, trimmer R9 at 2,4315 volts and R10 to get 5 Volts for 30 deg.

Also very critical is to select op-amps that are able to work at 5Volts and be rail to rail. I thing LMC662 is such a chip.

Ioannis

7784

flotulopex
- 14th April 2015, 05:07
Ioannis,

Thank you very much for the schema and your comment.

I need to check what the opamps in my drawer can do and if they don't, I'll order some to test this.

It makes it quite a "large" circuit in comparison of the usage of a single LM35.

What would be the advantage of this circuit vs a LM35 please?

Ioannis
- 14th April 2015, 07:18
If it seems too complicated, you can remove R5, R6, R8 making exact adjustment more critical.

The circuit will give you more resolution for the range you asked, -30 to +30 for a 0 to 5 volts output or about 0,083 volt/deg celsious.

Also it gives you an output for negative temperatures.

For the LM35 you will get 10mV/C. This means you will get from 0-0,3 volts for 0-30 C. If you want to measure from -30, then you must raise the ground of the LM35 above say 0,3 or better 0,6 volts. Maybe with a diode. Your output then will not be referenced to ground but from the pins of the LM35 (out and LM35 gnd). Your span for -30 to +30 will be 0,6 volts. If you need to drive an ADC then it would be better to amplify this small signal too.

HTH,
Ioannis

Dave
- 14th April 2015, 11:54
I think you are better off with the LM335 as it's output is 10mv/deg K. The LM35 is 10mv/deg.c. There is going to be a problem with the accuracy below 0 deg C. when using the LM35. If you would like rather than analog you could use a TMP-03/04 from Analog Devices which is a pulse width output. I have used these before and work quite well. Just a thought...

flotulopex
- 14th April 2015, 17:21
I think you are better off with the LM335 as it's output is 10mv/deg K. The LM35 is 10mv/deg C.

Hum...can you explain a little more please?

I thought Kelvin were used to express a temperature difference and Celsius/Fahrenheit would represent a value. I must be wrong.

Ioannis
- 14th April 2015, 17:46
Deg Kelvin references differently. 0 deg Kelvin is the absolute zero. The point that every thermal motion stops. To convert it to Celsius, just add 273,15. So the 0 Celsius is 273,15 Kelvin and 0 Kelvin -273,15 celsius.

Ioannis

flotulopex
- 14th April 2015, 19:00
Thanks Ioannis.

This (schema) is where I have come up to now - using the simple simplest, maybe too simple (...) The opamp acts as a voltage doubler (seems enough for what I need).

BTW, I'm using a 16F690 with 10 bits ADC.
7786
At 24°C, the LM35 outputs 1,199V so the opamp's Vout shows 2,396V.

Now, what is the LM35 going to output at 0°C or even less, around -20°C?

Since 1,199V represent 24°C, can I say that at 0°C, I will have 0,959Volts (LM35 Vout)?

Talking "temperature", what is the reference when adjusting temperature sensors at home?

Is it this?
7787
Noooooooooooooo...... :tongue:

NB: You're absolutely right about Kelvins. In the field, talking with cooling systems engineers, to make sure we don't get messed up while setting up machines, we (wrongly) use Kelvins to express a temperature difference or threshold and degrees to set a temperature value ;)

Ioannis
- 14th April 2015, 19:38
I don't think it will work for minus temps the way you got it.

Your output as I said earlier, would be directly from the LM35, meaning from the output pin AND the GND pin of the LM35. NOT the circuit Ground.

Now, that leads us to another problem. Your new output will be 0 volts at 0 C, positive at positive temps but negative below zero (LM35 output would seem more negative than the LM35 ground). So the opamp would not be able to handle this negative voltageas you designed it.

You are going to need a differential amplifier, such as the first opamp in my design.

Ioannis

flotulopex
- 14th April 2015, 19:59
Okay,

I'll give a try to your circuit.

Will a LM358N opamp do the job or does it absolutely need to be LMC662?

Another thing, having in mind the accuracy I need is not that critical (+/- 2°C is okay), what is a "simple" way to measure a freezer's temperature?

Would a thermistor do the trick in an acceptable way too?

Ioannis
- 14th April 2015, 20:16
A thermistor is far from linear. I would not use it now, at least without first trying other things.

I came up with a simpler solution to your problem. Drop the op-amp and drive the LM35 output to one ADC of your PIC. Now drive the raised GND of the LM35 to another ADC input of your PIC.

Since the two voltages, referenced to ground, are positive, you can do a calculation in your program. (LM35output-LM35Gnd)*100 and you will have your temp. Be careful here because the subtraction will give you a negative result if the real temp is below zero.

So now you have a circuit absolutely minimal.

I would suggest to use a PIC with 10bits ADC and increase the resolution with oversampling to 12 bits with Darrel Taylor's oversampling routines when you have it working.

Ioannis

flotulopex
- 14th April 2015, 21:53
Thanks Ioannis,

You're right: less than that is almost impossible :cool:


Now drive the raised GND of the LM35 to another ADC input of your PIC
I need to ADC measure the raised GND only once since it will never change - or am I missing something?

And "yes", for sure I'll have values to measure that will be below 0°C; in fact, they will have to be always under 0°C or I'll have a problem with the food inside the freezer :tongue:

flotulopex
- 15th April 2015, 06:19
The two diodes connected to the ground of LM35 will change their value due to temperature change.

So this is the reason for why two ADC channels are needed.

Since I'll have to locate the LM35 inside the freezer, shall I put these two diodes as close as possible to the LM35, meaning, the sensor and the diodes will be located inside the freezer? Or is it not necessary?

Ioannis
- 15th April 2015, 06:55
You got it right about the temp instability of the diodes.

And since both (diode and LM35) have positive coefficient regarding the temperature, i'd put both in the same thermal spot.

Remeber, NOT to use the LM35D

Ioannis

richard
- 15th April 2015, 07:09
if you wire a lm335 like this
would not a adc reading of 512 = about -22C and a adc read of 569 = about 0 C
not very much resolution but workable

or am I missing something

Ioannis
- 15th April 2015, 07:57
Of course it it workable if you accept the 2,59 counts per degree. Noise will be an issue also and especially in this case I would insist on using oversampling to 12 bits to iron out the noise as much as possible.

Ioannis

richard
- 15th April 2015, 10:06
having in mind the accuracy I need is not that critical (+/- 2°C is okay),

with a bit of averaging or oversampling 0.5 resolution is achievable, the software solution is at least cheap and easy to try out

flotulopex
- 16th April 2015, 08:24
Hello,

I have built the circuit and I'm now testing.

I'll send some pictures from the the values I read from the LM35 in a moment - very strange values, not stable at all... :-(

flotulopex
- 16th April 2015, 13:18
So this is where I am right now.

First, here's my hardware. What you won't see on the schema is the serial comm lead connected to PIC's PORTB.7 .
7797

Here's the code:
' PIC 16F690 Fuses
@ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_HS_OSC &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF

'_________________________________________________ ______________________________
' Registers 76543210
OPTION_REG = %10000000 'OPTION REGISTER
ANSEL = %00000100 'Select analog inputs Channels 0 to 7
ANSELH = %00000010 'Select analog inputs Channels 8 to 11
ADCON0 = %00000001 'A/D control register
ADCON1 = %00000000 'A/D control register
CM1CON0 = %00000000 'Comparator1 Module
CM2CON0 = %00000000 'Comparator2 Module
INTCON = %00000000 'INTerrupts CONtrol
TRISA = %00000100 'Set Input/Output (0 to 5)
PORTA = %00000000 'Ports High/Low (0 to 5)
TRISB = %00000000 'Set Input/Output (4 to 7)
PORTB = %00000000 'Ports High/Low (4 to 7)
TRISC = %10000000 'Set Input/Output (0 to 7)
PORTC = %00000000 'Ports High/Low (0 to 7)

'_________________________________________________ ______________________________
' Defines
DEFINE OSC 4
DEFINE ADC_BITS 10

'_________________________________________________ ______________________________
' Variables
LM35_Vout var word ' AN2 PORTA.2
LM35_VGND var word ' AN9 PORTC.7
Temperature var word
DataVar VAR WORD(12)
DataTemp var WORD
Counter_A var WORD

'_________________________________________________ ______________________________
' Program

MAIN:
' LM35_Vout
FOR counter_A = 0 to 11
adcin 2, DataVar(counter_A)
next counter_A
Counter_a = 0
GOSUB SORT
LM35_Vout = DataTemp


' LM35_VGND
FOR counter_A = 0 to 11
adcin 9, DataVar(counter_A)
next counter_A
Counter_a = 0
GOSUB SORT
LM35_VGND = DataTemp

Temperature = (LM35_Vout - LM35_VGND) * 100

GOSUB DISPLAY

pause 1000

Goto main:


'_________________________________________________ ______________________________
' Subroutine

DISPLAY:
Serout2 PORTB.7,84,["Temp.: ", dec4 temperature," LM35_Vout: ", dec4 LM35_Vout," LM35_VGND: ", dec4 LM35_VGND,13]
RETURN

'_________________________________________________ ______________________________
' Subroutine

SORT:
' Melanie NEWMAN's array sorting routine
' Aquire 12 values, delete 4 lower and 4 top values, average 4 remaining values

If DataVar(counter_A + 1) < DataVar(counter_A) then
DataTemp = DataVar(counter_A)
DataVar(counter_A) = DataVar(counter_A + 1)
DataVar(counter_A + 1) = DataTemp
If Counter_A > 0 then Counter_A = Counter_A - 2
endif
Counter_A = Counter_A + 1
If Counter_A < 11 then GOTO SORT

' Average four middle values
DataTemp = 0
For Counter_A = 4 to 7
DataTemp = DataTemp + DataVar(counter_A)
next Counter_A

DataTemp = DataTemp / 4

Return



And here is the reading I get right now, knowing the temperature sensor is on my desk close to three other thermometers showing 21°C. Promised, I won't forget to format the "Temp." display in the final version (i.e. "9456" => "94,56°C") :rolleyes:

7796



What's wrong with it? :confused:

I have set and defined a 10 bits ADC result. How can I get values over 1023?

I might be wrong with the ADCON0.7 setting but I'm not used to modify it so I'm not sure about that.

Any other idea?

Ioannis
- 16th April 2015, 13:43
That's because you have left justified the ADC result in ADRESL and ADRESH.

Set the adcon0 to %10000001.

Also you have this calculation:



Temperature = (LM35_Vout - LM35_VGND) * 100


What about LM35_Vout being less than LM35_VGND?

I expected you would do this and noted in earlier post (#33) :)

The simplest way is to have an if-then check first like this:



if LM35_Vout >LM35_VGND then
Temperature = (LM35_Vout - LM35_VGND) * 100
else
if LM35_Vout <= LM35_VGND then
Temperature = (LM35_VGND - LM35_Vout) * 100
endif


Ioannis

flotulopex
- 16th April 2015, 14:52
...What about LM35_Vout being less than LM35_VGND?

I expected you would do this and noted in earlier post (#33) :)

Sorry, I forgot this one :o . I was focused on the "mysterious" values I was reading.




I might be wrong with the ADCON0.7 setting but I'm not used to modify it so I'm not sure about that.

I changed to ADCON0.7 = 1 and the values I read look much better. Still the Temperature value has to be divide by 2 to give the correct reading.

7799



Even if it's not the main subject here, can you shortly explain what the difference between ADCON0.7 = 0 and ADCON0.7 = 1 is?


The temporary code is now:
' PIC 16F690 Fuses
@ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_HS_OSC &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF

'_________________________________________________ ______________________________
' Registers 76543210
OPTION_REG = %10000000 'OPTION REGISTER
ANSEL = %00000100 'Select analog inputs Channels 0 to 7
ANSELH = %00000010 'Select analog inputs Channels 8 to 11
ADCON0 = %10000001 'A/D control register
ADCON1 = %00000000 'A/D control register
CM1CON0 = %00000000 'Comparator1 Module
CM2CON0 = %00000000 'Comparator2 Module
INTCON = %00000000 'INTerrupts CONtrol
TRISA = %00000110 'Set Input/Output (0 to 5)
PORTA = %00000000 'Ports High/Low (0 to 5)
TRISB = %00000000 'Set Input/Output (4 to 7)
PORTB = %00000000 'Ports High/Low (4 to 7)
TRISC = %10000000 'Set Input/Output (0 to 7)
PORTC = %00000000 'Ports High/Low (0 to 7)

'_________________________________________________ ______________________________
' Defines
DEFINE OSC 4
DEFINE ADC_BITS 10

'_________________________________________________ ______________________________
' Variables
LM35_Vout var word ' AN2 PORTA.2
LM35_VGND var word ' AN9 PORTC.7
Temperature var word
DataVar VAR WORD(12)
DataTemp var WORD
Counter_A var WORD

'_________________________________________________ ______________________________
' Program

MAIN:
' LM35_Vout
FOR counter_A = 0 to 11
adcin 2, DataVar(counter_A)
next counter_A
Counter_a = 0
GOSUB SORT
LM35_Vout = DataTemp


' LM35_VGND
FOR counter_A = 0 to 11
adcin 9, DataVar(counter_A)
next counter_A
Counter_a = 0
GOSUB SORT
LM35_VGND = DataTemp

if LM35_Vout >LM35_VGND then
Temperature = ((LM35_Vout - LM35_VGND) * 100) / 2
endif
if LM35_Vout <= LM35_VGND then
Temperature = ((LM35_VGND - LM35_Vout) * 100) / 2
endif

GOSUB DISPLAY

pause 1000

Goto main:


'_________________________________________________ ______________________________
' Subroutine

DISPLAY:
Serout2 PORTB.7,84,["Temp.: ", dec2 (temperature/100),",",dec1 (temperature/10),"°C LM35_Vout: ", dec4 LM35_Vout," LM35_VGND: ", dec4 LM35_VGND,13]
RETURN

'_________________________________________________ ______________________________
' Subroutine

SORT:
' Melanie NEWMAN's
' This subroutine sorts, in this example, 12 elements,
' MyData array in sequence placing the smallest value into MyData[0] and
' the largest value into MyData[11]...

If DataVar(counter_A + 1) < DataVar(counter_A) then
DataTemp = DataVar(counter_A)
DataVar(counter_A) = DataVar(counter_A + 1)
DataVar(counter_A + 1) = DataTemp
If Counter_A > 0 then Counter_A = Counter_A - 2
endif
Counter_A = Counter_A + 1
If Counter_A < 11 then GOTO SORT

' Average four middle values
DataTemp = 0
For Counter_A = 4 to 7
DataTemp = DataTemp + DataVar(counter_A)
next Counter_A

DataTemp = DataTemp / 4

Return

Tabsoft
- 16th April 2015, 16:19
Roger,

Check out section 9.1.6 "Result Formatting" of the Datasheet.
It shows the difference in the two formatting options.

In essence Right Shifted will place the 10-bit value in bits 9 through 0 (MSB is bit9).
Left Shifted will place the 10-bit value in bits 15 through 6 (MSB is bit15)

So if your ADC reading is 250 then here would be the values.
Right Shifted = 250 (%0000 0000 1111 1010)
Left Shifted = 1600 (%0011 1110 1000 0000)

flotulopex
- 16th April 2015, 16:28
Thanks Tabsoft,

I already read that chapter may times but I just can't understand what this feature is meant for.

Why would one choose either option?

I need an example of both usage, maybe this could help :o

Ioannis
- 16th April 2015, 20:00
If you want to use only 8 bit (may be it is enough for specific application) then the left justified result will give yout the number in the ADRESH directly. No shifting or dividing required.

But for the full 10 bit results you have to right justify the bytes in the ADRESH-ADRESL to be correct.

Ioannis

flotulopex
- 17th April 2015, 06:31
Okay, I think, I've got it now. Next problem: I need to remember it :D