with a bit of averaging or oversampling 0.5 resolution is achievable, the software solution is at least cheap and easy to try outhaving 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 outhaving in mind the accuracy I need is not that critical (+/- 2°C is okay),
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... :-(
Roger
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 .
Here's the code: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")
What's wrong with it?
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?
Last edited by flotulopex; - 16th April 2015 at 13:24. Reason: typo
Roger
That's because you have left justified the ADC result in ADRESL and ADRESH.
Set the adcon0 to %10000001.
Also you have this calculation:
What about LM35_Vout being less than LM35_VGND?Code:Temperature = (LM35_Vout - LM35_VGND) * 100
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:
IoannisCode: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
Last edited by Ioannis; - 16th April 2015 at 13:48.
Sorry, I forgot this one. I was focused on the "mysterious" values I was reading.
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.Originally Posted by me
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: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 = %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
Roger
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)
Regards,
TABSoft
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![]()
Roger
Bookmarks