LM335 och AVR

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

LM335 och AVR

Inlägg av PaNiC »

Det dröjer längre mellan gångerna jag behöver fråga om programmeringshjälp, men nu är det dags igen.
Värdet från LM335 finns i ADCH och ADCL. Nu ska detta räknas om till riktiga grader Kelvin.
Vad jag har gjort är:

Kod: Markera allt

int t = ((ADCH<<8)|ADCL);
t = (((5*t)/1023)*100);
sprintf(str, "%.3d\r\n", t);
Här tappar jag bort tiotalen och entalen. Antar att det är för att decimalerna inte hanteras riktigt, men hur går jag runt det?
Aref = 5V.
ie
EF Sponsor
Inlägg: 1379
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

Inlägg av ie »

En bra övning är att göra uträkningen med min och max-värden binärt på papper för att kolla. Då kommer du nog att märka att (5*t)/1023 gör att några bitar hamnar "utanför" bitplatserna i din int-variabel. Du skulle i så fall behöva multiplicera med 100 (om talet inte är för stort från början) innan du delar med 1023.

Dessutom borde du inte se några decimaler över huvud taget eftersom du jobbar med int.

Utan att ha kollat noggrannare skulle jag dessutom misstänka att du skulle dela med 1024 (vilket enkelt kan göras med en shiftoperation).
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

Inlägg av PaNiC »

Talet blir för stort om jag börjar med att multiplicera med 100.
Jag ser inga decimaler heller, utan jag syftade till de teoretiska som blir efter divisionen med 1023.
ie
EF Sponsor
Inlägg: 1379
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

Inlägg av ie »

Jag vet inte vad LM335 ger för värde. Kan du ge exempel på vad t innehåller (binärt) efter första raden?
haklu
Inlägg: 36
Blev medlem: 7 augusti 2008, 16:32:33
Ort: Örebro

Inlägg av haklu »

LM335 verkar mäta mellan 233 och 373 K och ger 10mV per K. Vid 373 K så ska alltså t vara 373*1024/500=764. Om man använder en unsigned int så borde man alltså kunna multiplicera t med floor(2^16/764)=85 utan att få overflow.

(t*5/1024)*100 = t*500/1024 = t*125/256

Om man ska kunna mäta nära 100 grader C så kan man alltså inte ta hela multiplikationen med 125 på en gång, men man kan börja med att multiplicera med 25 och skifta ner ett steg (dividera med 2) och sedan multiplicera med de resterande 5 och skifta de resterande 7 stegen.

unsigned int t = ((ADCH<<8)|ADCL);
t *= 25;
t >>= 1;
t *= 5;
t >>= 7;
sprintf(str, "%.3d\r\n", t);

PS. Detta var förövrigt min första post i detta trevliga forum efter att ha läst en hel del intressant.
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

Inlägg av PaNiC »

haklu, din lösning är provad och fungerar. Tackar, och välkommen till forumet!

le, för intressets skull, runt 620 (viss feltolerans finns) vid rumstemp, dvs 1001101100.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Notera att en kombination av en lookup tabell och
eventuellt en linjär aproximation mellan tabellvärderna
sannolikt är betydligt snabbare än alla beräkningar.
Om det nu spelar någon roll...
Skriv svar