This is awesome!
Where did you get this formula from?
Where did you get this formula from?
Temp = 0.0943 * ADC_COUNTS - 23
Temp = 0.0943 * ADC_COUNTS - 23
I would use a TDC - time to digital converter. Multiple ways of doing it. The simplest is to use two comparators to measure the rise time between two points fractional voltages. Since this time is proportional to the RC time constant, you can choose a combination of C and your comparator thresholds to get an easily calibrated and conveniently scaled direct reading of the resistance (or of the capacitance, if that is what you were interested in).Next I will show you how to do it without an ADC.
You make an ASM that uses the RC to establish the period, which means that the frequency is inversely proportional to the resistance and, hence, directly proportional to the temperature. You then count how many cycles you see on the pin in a fixed amount of time. Choose the 'fixed amount of time' wisely, and you make the computation on the cycle count consist of a shift and/or adding a constant.See if you can guess what is coming next...
MrChips, I understand you have used a binary division in your code as it would execute faster and possibly be smaller in code, however C compilers will usually link in both mult and divide libraries once the user starts doing 32bit multiplications.Now suppose you didn't want to use floating point arithmetic or you wanted to write the code in assembler. How would you calculate
temp = 0.0953 * ADC_COUNTS - 23
You can scale 0.0953 by multiplying with 65536 = 6180
The equation becomes:
temp = 6180 * (ADC_COUNTS)/ 65536 - 23
Thus multiply ADC_COUNTS by 6180 using 32-bit precision and select the upper 16 bits of the result, then subtract 23.
...
Sorry about any confusion.Now suppose you didn't want to use floating point arithmetic or you wanted to write the code in assembler. How would you calculate
temp = 0.0943 * ADC_COUNTS - 23
You can scale 0.0943 by multiplying with 65536 = 6180
The equation becomes:
temp = 6180 * (ADC_COUNTS)/ 65536 - 23
Thus multiply ADC_COUNTS by 6180 using 32-bit precision and select the upper 16 bits of the result, then subtract 23.
To adjust the equation in order to calibrate for gain and offset shifts, all you have to trim are the two values 6180 and 23.
;define registers
A EQU 16
B EQU 17
C EQU 18
;index registers
X EQU 26
XHI EQU 27
*********************************************************
* Thermistor Interface
*********************************************************
;thermistor is on PD6
THERM EQU 6
;get frequency measurement
;for Thermistor sensor
getTherm LDI XHI $FF
LDI X $FF
;set for 1-sec timebase
;init value = 34286 = $85EE
CBR flags TOV1mask
LDI A $85
OUT TCNT1H A
LDI A $EE
OUT TCNT1L A
LDI A 4 ;start timer1
OUT TCCR1B,A
;charge THERM capacitor
getF1 SBRC flags TOV1
BRA getF0 ;exit
ADIW X 1
SBI PORTD THERM
SBI DDRD THERM
LDI C 5
CALL delayC
CBI DDRD THERM ;disconnect
CBI PORTD THERM ;remove weak P/U
getF2 SBIS PIND THERM
BRA getF1
SBRS flags TOV1
BRA getF2
getF0 SBI DDRD THERM ;set output LO
CBI PORTD THERM
RET
temperature1 = log(((10240000/adc_raw)-9930));
temperature1 = 1 / (0.001171329051429 + (0.000224841652249 + (0.000000142860438 * temperature1 * temperature1 )) * temperature1 );
temperature1 = temperature1 - 273.15;
temperature2 = (6180 * adc_raw) / 65536 - 23;
It's an indoor/outdoor thermometer. The upper digits are temp inside, and the lower digits are supposed to be outside. The sensor is at the end of a 1.6m cable. Which is wrapped around on my desk.What are the two readings 27.2C and 26.9C on your commercial thermometer?
How are you calculating and displaying to 1 decimal place on your LCD?
Are you using fprints( ) for example?
sprintf(out_temp1, "%.1f", temperature1);
The declaration:I presume you are using floating point arithmetic in C?
The equation I gave you is intended for integer arithmetic. The value 23 is already truncated. I will give you the correct values if you are doing floating point math.
unsigned char adc_value[5]; //max value will be 1023=4 char and 1 place for the /0 total 5 bytes
unsigned char lcd_message1[20];
unsigned char lcd_message2[20];
unsigned char out_temp1[10], out_temp2[10];
unsigned char i;
float adc_raw;
float temperature1, temperature2;
Looking forward to it.Finally, I still have to show how you can improve on the linearity by adding a resistor in parallel with the thermistor (may not today, too busy).
temperature2 = 0.0942833 * adc_raw - 22,9818;