mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DS18S20 - extended resolution bei Temperaturen um 0°C


Autor: Biff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich beschäftige mich seit einiger Zeit mit dem DS18S20. Nun habe ich 
versucht, die Temperatur für Auflösungen größer 9Bit gemäß der Formel im 
Datenblatt zu berechnen:


Das funktioniert auch, nur bei Minus-Temperaturen um die 0°C zeigt mir 
mein Display riesige Werte an. Ich vermute, dass der Fehler daraus 
resultiert, dass mir der Sensor für COUNT_REMAIN Werte größer 12 schickt 
und TEMP_READ nach der notwendigen Zweierkomplementbildung 0 ist. Damit 
hätte ich bei der Addition am Ende einen negativen Wert, der meine 
riesigen Werte erklären würde. Muss ich das ganze irgendwie 
softwareseitig abfangen, also z.B. durch folgende Prüfung?
if ((TEMP_READ == 0) && (COUNT_REMAIN > 12))
{
COUNT_REMAIN = 12;
}

Zur Zeit habe ich das so realisiert, nur eigentlich geht mir dann mit 
dieser Abfrage Genauigkeit verloren. Hat irgendjemand dasselbe Problem 
und dafür eine Lösung parat?

Danke,

Biff

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Biff schrieb:

> Ich vermute

Das ist ganz schlecht.
Mit Vermutungen kann man kein Programm schreiben.
Lass dir die Werte ausgeben, dann WEISST du es!

(und kannst nebenbei auch mal händisch alles durchrechnen und nachsehen, 
was sich bei Zwischenergebnissen so alles tut)

Ich denke, du hast eher irgendwo einen signed-unsigned Fehler. Aber ohne 
Code und dem Wissen über die beteiligten Datentypen der Variablen sind 
das alles nur Mutmassungen.

Autor: Biff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

anbei die Funktion, die die Werte vom DS18S20 ausliest. Bei der 
Berechnung habe ich bereits verschiedene Versionen ausprobiert, da ich 
erst dachte, dass es an meiner Formel liegt. Ich habe dann eine andere 
Berechnung genutzt, aber auch da habe ich das gleiche Problem.

uint16_t w1_getmultitemp(uint8_t actsensor)

  {

    uint8_t i, temp_msb = 0;
    uint16_t temp = 0, temp_lsb = 0, count_remain = 0;
    
    

    w1_reset();

    w1_writebyte(MATCH_ROM);                  //1wire: Match ROM-Befehl senden

    for (i = 0; i < 8; i++)
    {
    
      w1_writebyte(sensor[actsensor][i]);            //Sensor-Adresse senden
     }

    w1_writebyte(CONVERT_T);                  //1wire: Convert T-Befehl senden

    w1_ready();

    w1_reset();
     w1_writebyte(MATCH_ROM);                  //1wire: Match ROM-Befehl senden

    for (i = 0; i < 8; i++)
    {
    
      w1_writebyte(sensor[actsensor][i]);            //Sensor-Adresse senden
     }

    w1_writebyte(READ_SP);                    //1wire: Convert T-Befehl senden


    temp_lsb = w1_readbyte();                  //Temperatur LSB
    temp_msb = w1_readbyte();                  //Temperatur MSB
    w1_readbyte();                        //Th-Register
    w1_readbyte();                        //Tl-Register
    w1_readbyte();                        //Reserve (0xFF)
    w1_readbyte();                        //Reserve (0xFF)
    count_remain = w1_readbyte();                //count remain
    w1_readbyte();                        //count per°C (0x10)
    w1_readbyte();                        //CRC

    w1_reset();

    if (temp_msb)                        //wenn die Temperatur < 0°C
    {
      temp_lsb = (~temp_lsb + 1) & 0x00FF;          //2er-Komplement
    }

    //neue Version der Berechnung:
    temp_lsb = temp_lsb >> 1;
    temp_lsb = temp_lsb << 4;                  //Multiplikation mit 16
    temp = temp_lsb + 12;

    if ((temp_lsb == 0) && (count_remain > 12))
    {
    temp = temp - 12;
    }

    else
    {
    temp = temp - count_remain;
    }

    temp = temp * 25;
    temp = temp >> 2;                      //Division mit 4

    /*alte Version der Berechnung:
    temp_lsb = temp_lsb >> 1;
    temp_lsb = temp_lsb * 100;

    count_remain = count_remain * 100;
    count_remain = count_remain >> 4;              //Division durch 16

    temp = temp_lsb - 25 + 100 - count_remain;
    */

    if (temp_msb)                        //wenn die Temperatur < 0°C
    {
      temp = temp | 0x8000;                  //Setzen des MSB als Indikator für Minustemperaturen
    }
  

    return(temp);

  }



Meine Frage ist, ob der Sensor bei Minus-Temperaturen überhaupt die 
Kombination TEMP_READ = 255 und COUNT_REMAIN > 12 schickt? Weil dann 
käme es bei der Formel im Datenblatt zu einem negativen Resultat, 
nachdem man das Zweierkomplement von TEMP_READ gebildet und den Wert 
einmal nach rechts geschoben hat.

Danke,

Biff

Autor: visitor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Müsste die Zeile nicht verodert werden ?

if ((TEMP_READ == 0) || (COUNT_REMAIN > 12))
{
COUNT_REMAIN = 12;
}

Autor: Biff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo visitor,

eigentlich ja nicht, da es dieses Problem mit der Formel ja nur dann 
gibt, wenn der Wert TEMP_READ == 0 ist und COUNT_REMAIN > 12 ist. Wenn 
eine der Bedingungen nicht erfüllt ist, dann kann es gemäß der Formel ja 
nicht passieren, dass am Ende der Subtraktion ein Wert kleiner 0 
herauskommt. Deswegen habe ich diese beiden Bedingungen "verunded".

Biff

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Sensor funktioniert so wie du es möchtest. Hab ihn selber schon mal 
so benutzt. Nur du rechnest falsch und verschluderst wahrscheinlich 
irgendwo Vorzeichen. Überall nur uint Variablen. Denk mal drüber nach, 
prüfe alle Zwischenergebnisse und du kommst selber drauf. Karl-Heinz 
schrieb es ja auch schon oben.

Autor: Biff (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe jetzt mal Karl-Heinz' Ratschlag befolgt und mir die Messwerte 
ausgeben lassen. Die Kombination aus TEMP_READ == 0 und COUNT_REMAIN 
scheint es nicht zu geben. Für alle die es interessiert ist im Anhang 
der Log, interessant für mein Problem sind die Zeilen 169-228. Somit 
liegt mein Problem in meiner Berechnung. Ich werde mal gucken, ob ich 
hier im Forum ein Beispielcode finde. Danke erstmal,

Biff.

Autor: Gustl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich hatte in der Vergangenheit auch schon mal dass Problem. Meine Lösung 
:

// Temperatur = (((16*aucScratchpad[0])+12-aucScratchpad[6])*25)/4

usExtTemperature =  (aucScratchpad[0]>>1);
usExtTemperature = usExtTemperature * 16;
usExtTemperature = usExtTemperature + 12;
if(aucScratchpad[6] > 12)
{
  usExtTemperature = usExtTemperature - 12;
}
else
{
  usExtTemperature = usExtTemperature - aucScratchpad[6];
}
usExtTemperature = usExtTemperature * 25;
usExtTemperature = usExtTemperature >> 2;

Autor: eProfi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die aufschlussreichen Logs, leider fehlen ein paar 
Zeilen, z.B.
000;000;075;070;255;255;016;016;

Es gibt etliche Fallstricke beim Rechnen mit signed ints, z.B. (-1)/2=+0

Wer seinen Algorithmus testen will, hier die korrekte Zuordnung:
Mein Testobjekt: DS1820 von Pollin 180014 (2,50)
 0  1   6  7  9bit   12bit  12bit-Äquivalent
ff 00  01 10 127,5 127,6875  07fb  max. Temp (lötkolbengetestet ;-))
ff 00  02 10 127,5 127,6250  07fa
ff 00  03 10 127,5 127,5625  07f9
ff 00  04 10 127,5 127,5000  07f8
ff 00  05 10 127,5 127,4375  07f7
ff 00  06 10 127,5 127,3750  07f6
ff 00  07 10 127,5 127,3125  07f5
ff 00  08 10 127,5 127,2500  07f4
ff 00  09 10 127,0 127,1875  07f3
....
02 00  0c 10   1,0   1,0000  0010
02 00  0d 10   1,0   0,9375  000F
02 00  0e 10   1,0   0,8750  000E
02 00  0f 10   1,0   0,8125  000D
02 00  10 10   1,0   0,7500  000C
01 00  01 10   0,5   0,6875  000B
01 00  02 10   0,5   0,6250  000A
01 00  03 10   0,5   0,5625  0009
01 00  04 10   0,5   0,5000  0008
01 00  05 10   0,5   0,4375  0007
01 00  06 10   0,5   0,3750  0006
01 00  07 10   0,5   0,3125  0005
01 00  08 10   0,5   0,2500  0004
00 00  09 10   0,0   0,1875  0003
00 00  0a 10   0,0   0,1250  0002
00 00  0b 10   0,0   0,0625  0001
00 00  0c 10   0,0   0,0000  0000
00 00  0d 10   0,0  -0,0625  ffff
00 00  0e 10   0,0  -0,1250  fffe
00 00  0f 10   0,0  -0,1875  fffd
00 00  10 10   0,0  -0,2500  fffc
ff ff  01 10  -0,5  -0,3125  fffb
ff ff  02 10  -0,5  -0,3750  fffa
ff ff  03 10  -0,5  -0,4375  fff9
ff ff  04 10  -0,5  -0,5000  fff8
ff ff  05 10  -0,5  -0,5625  fff7
ff ff  06 10  -0,5  -0,6250  fff6
ff ff  07 10  -0,5  -0,6875  fff5
ff ff  08 10  -0,5  -0,7500  fff4
fe ff  09 10  -1,0  -0,8125  fff3
fe ff  0a 10  -1,0  -0,8750  fff2
fe ff  0b 10  -1,0  -0,9375  fff1
fe ff  0c 10  -1,0  -1,0000  fff0
fe ff  0d 10  -1,0  -1,0625  ffef
fe ff  0e 10  -1,0  -1,1250  ffee
fe ff  0f 10  -1,0  -1,1875  ffed
fe ff  10 10  -1,0  -1,2500  ffec
fd ff  01 10  -1,5  -1,3125  ffeb
Für die 12bit-4Nachkommastellen-Ausgabe kann man die die Periodizität 
nutzen: die letzten beiden Ziffern sind jedes 4. Mal gleich.

Ich gebe nur 2 Nachkommastellen mit LookUp aus:
char s[32]="00061319253138445056636975818894";
if(temp12<0){tabs12=-temp12;sign='-';}else{tabs12=temp12;sign='+';}
...
put(s[help=2*(tabs12&15)];put(s[help+1]);

In den Anhängen findet Ihr ein neues Testfile (gleich aufgebaut wie die 
o.g. Logs), ein Programm, das das Testfile auf verschiedene Arten 
umrechnet und die Ausgabe dieses Programms.

: Bearbeitet durch Moderator
Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wozu soll das hier gut sein

    if (temp_msb)                        //wenn die Temperatur < 0°C
    {
      temp_lsb = (~temp_lsb + 1) & 0x00FF;          //2er-Komplement
    }


Ich würde ehrlich gesagt da nicht grossartig auf Bitebene rumpfriemeln.

Du kriegst erst mal die beiden Bytes für die Temperatur. Die werden vom 
DS freundlicherweise schon im 2-er Komplement geschickt.
D.h. die beiden Bytes setzt ich in einer int16_t Variablen zusammen und 
hab dann schon einen fix/fertigen Wert (inklusive Vorzeichen), der dem 
doppelten der tatsächlichen Temperatur entspricht.

Und ab da rechne ich alles nur noch mit signed integer Variablen 
(int16_t), so wie es im Datenblatt angegegeben ist, wobei ich es 
tunlichst unterlasse schlauer als mein Compiler zu sein.

Autor: JoachimB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Biff,

wo lässt Du den Wert "count per °C" ?
Soweit ich deinen Code verstanden habe, liest Du den Wert Count_per_C 
nicht in eine Variable. Du kannst deshalb in deiner Berechnung auch 
keine sinnvollen Ergebnisse erzielen.
das Geheimnis der Sensoren besteht darin, dass die Spanne von einem Grad 
Celsius eine Anzahl Counts liefert, die sich über den Messbereich 
ändert.
z.B. von 10-11°C 73 Counts und von 20 bis 21°C 80 Counts.

Gruß
Joachim

Autor: Bingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe hier

http://gandalf.arubi.uni-kl.de/avr_projects/tempse...
http://gandalf.arubi.uni-kl.de/avr_projects/tempse...

Und extended temp for 18s20 - the easy way
  //  only work on 12bit-base

  if( fc == DS18S20_FAMILY_CODE ) { // 9 -> 12 bit if 18S20

    /* Extended res. measurements for DS18S20 contributed by Carsten Foss */

    meas &= (uint16_t) 0xfffe;    // Discard LSB, needed for later extended precicion calc

    meas <<= 3;                   // Convert to 12-bit, now degrees are in 1/16 degrees units

    meas += ( 16 - sp[6] ) - 4;   // Add the compensation and remember to subtract 0.25 degree (4/16)

  }

/Bingo

Autor: Carsten W. (carsten_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

hier ist noch ein Beispiel:
...
int tmp;
...
DIS.E[i].Value = OWIReceiveByte(Pin);
DIS.E[i].Value |= (OWIReceiveByte(Pin) << 8);
OWIReceiveByte(Pin);
OWIReceiveByte(Pin);
OWIReceiveByte(Pin);
OWIReceiveByte(Pin);
tmp = DIS.E[i].Value >> 1;
tmp = tmp << 4;
tmp -= 4;
tmp += (16 - OWIReceiveByte(Pin));
DIS.E[i].Value = tmp;
...

Gruß
Carsten

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Von mir wieder einmal ein Runde Kraftfutter,
HighDensityCode vom Feinsten:

Die komplette Auswertung des gelesenen Temperaturwertes samt
 - Umwandlung in druckbare Zeichen,
 - Unterdrückung führender Nullen,
 - Verschiebung des Vorzeichens
 - zwei Nachkommastellen
in 10 Zeilen (ohne die Kommentare). Ich kann gar nicht verstehen, wie 
man hierfür kilometerlangen Code schreiben kann.

Ohne Verwendung von printf, *, / oder % ,
ergibt auch auf kleinen µC einen Mini-Code.
unsigned char d[9]; //Dallas DS1820 Scratchpad
int t; //absolute degrees
int f; //fractions (1/16ø) of absolute degrees
//char,fractional digits and the
//sign (if zero, the sign was already printed)
char c,g[16]="0011233455667889",h[16]="0639518406395184",s;

if(d[1]){s='-';f=(4+d[6])&15;
  if(d[6]>11)t=128-d[0]/2;else t=127-d[0]/2;}
else{s='+';t=d[0]/2  ;f=(28-d[6])&15;
  if(d[6]>12){if(d[0]){t--;}else{s='-';f=d[6]-12;}}}

if(t>99){putch(  s);s=0;putch('1');t-=100;}
else    {putch(' ');if(t>9){putch(s);s=0;}else putch(' ');}
c='0';while((t-= 10)>=0)c++;if(s)putch(s);else{putch(c);}
putch(58+t);putch(',');putch(g[f]);putch(h[f]);putch('°');putch('C');


Hier die Vorversion ohne 0-Unterdrückung und Vorzeichenverschieben
7 Zeilen ;-)
if(d[1]){c='-';f=(4+d[6])&15;
  if(d[6]>11)t=128-d[0]/2;else t=127-d[0]/2;}
else{c='+';t=d[0]/2;f=(28-d[6])&15;
  if(d[6]>12){if(d[0]){t--;}else{c='-';f=d[6]-12;}}}

putch(c);if(t>99){putch('1');t-=100;}else putch('0');
c=47;while(c++,(t-=10)>=0);putch(c);putch(58+t);
putch(',');putch(g[f]);putch(h[f]);putch('°');putch('C');


Code funktioniert nur bei Sensoren, die als CountPerDegree fest 16 
haben.

Für die gibt eine weitere Berechnung des 12-Bit-Wertes:
if(a[1]){temp12=63491+8*a[0]-((a[6]-1)&7);}
else    {temp12=    3+8*a[0]-((a[6]-1)&7);}
if(temp12<0){tabs12=-temp12;sign='-';} //Absolutwert berechnen
else        {tabs12= temp12;sign='+';}

frac=tabs12&15;//Nachkomma in 1/16°
grad=tabs12/16;//muss signed sein, damit divBySub funktioniert

Guten Appetit!
Anregungen, Kommentare, Verbesserungen ... immer gern gesehen!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>in 10 Zeilen (ohne die Kommentare). Ich kann gar nicht verstehen, wie
>man hierfür kilometerlangen Code schreiben kann.

Weil es übersichtlicher ist und nicht so ein scheisse
formatierter Schrott wie von dir.

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Von mir wieder einmal ein Runde Kraftfutter,
HighDensityCode vom Feinsten:

Die komplette Auswertung des gelesenen Temperaturwertes samt
 - Umwandlung in druckbare Zeichen,
 - Unterdrückung führender Nullen,
 - Verschiebung des Vorzeichens
 - zwei Nachkommastellen
in 10 Zeilen (ohne die Kommentare). Ich kann gar nicht verstehen, wie 
man hierfür kilometerlangen Code schreiben kann.

Ohne Verwendung von printf, *, / oder % ,
ergibt auch auf kleinen µC einen Mini-Code.
unsigned char d[9]; //Dallas DS1820 Scratchpad
int t; //absolute degrees
int f; //fractions (1/16°) of absolute degrees
//char,fractional digits and the
//sign (if zero, the sign was already printed)
char c,g[16]="0011233455667889",h[16]="0639518406395184",s;

if(d[1]){s='-';f=(4+d[6])&15;
  if(d[6]>11)t=128-d[0]/2;else t=127-d[0]/2;}
else{s='+';t=d[0]/2;f=(28-d[6])&15;
  if(d[6]>12){if(d[0]){t--;}else{s='-';f=d[6]-12;}}}

if(t>99){putch(  s);s=0;putch('1');t-=100;}
else    {putch(' ');if(t>9){putch(s);s=0;}else putch(' ');}
c='0';while((t-=10)>=0)c++;if(s)putch(s);else putch(c);
putch(58+t);putch(',');putch(g[f]);putch(h[f]);putch('°');putch('C');


Hier die Vorversion ohne 0-Unterdrückung und Vorzeichenverschieben
7 Zeilen ;-)
if(d[1]){c='-';f=(4+d[6])&15;
  if(d[6]>11)t=128-d[0]/2;else t=127-d[0]/2;}
else{c='+';t=d[0]/2;f=(28-d[6])&15;
  if(d[6]>12){if(d[0]){t--;}else{c='-';f=d[6]-12;}}}

putch(c);if(t>99){putch('1');t-=100;}else putch('0');
c=47;while(c++,(t-=10)>=0);putch(c);putch(58+t);
putch(',');putch(g[f]);putch(h[f]);putch('°');putch('C');


Code funktioniert nur bei Sensoren, die als CountPerDegree fest 16 
haben.

Für die gibt eine weitere Berechnung des 12-Bit-Wertes:
if(d[1]){temp12=63491+8*d[0]-((d[6]-1)&7);}
else    {temp12=    3+8*d[0]-((d[6]-1)&7);}
if(temp12<0){tabs12=-temp12;sign='-';} //Absolutwert berechnen
else        {tabs12= temp12;sign='+';}

frac=tabs12&15;//Nachkomma in 1/16°
grad=tabs12/16;//muss signed sein, damit divBySub funktioniert

Guten Appetit!
Anregungen, Kommentare, Verbesserungen ... immer gern gesehen!


Also gut, hier formatiert und kommentiert:
Habe den Code noch minimal geändert. Für t und f reicht  char.
Das sind ein paar hundert Bytes Code.
//Idea and code (C) by eProfi
//for better understanding  look at the table in
//www.mikrocontroller.net/topic/202928#1999183
//output format:
//  1      2      3    4  5   6    7
//sign hundreds tens ones , 1/10 1/100

const PROGMEM char
  g[16]="0011233455667889",//first  fractional digit
  h[16]="0639518406395184",//second fractional digit

unsigned char d[9];     //Dallas DS1820 Scratchpad
char t;                 //temperature in absolute degrees
char f;                 //fractionals (1/16°) of absolute degrees
char c,s;               //sign (if zero, the sign was printed already)

if(d[1]){s='-';         //case1 : temp is -0.31 or lower --> negative anyways
  f=(4+d[6])&15;
  t=127-d[0]/2;         //case1a: temp is -x.31 to -x.94 --> "round down"
  if(d[6]>11)t++;}      //case1b: temp is -x.00 to -x.25 --> "round up"
else{s='+';t=d[0]/2;    //case2 : temp is -0.25 or higher
  f=(28-d[6])&15;
  if(d[6]>12){          //case2a: temp is  x.81 to  x.94  or  -0.25 to -0.06
    if(d[0])t--;        //case2b: temp is  x.81 to  x.94 --> "round down"
    else{s='-';         //case2c: temp is -0.25 to -0.06, overwrite +sign
      f=d[6]-12;}}}     //        and recalc fractionals

if(t>99){putch(s);s=0;  //absolute temp is higher than 99 (and lower than 128)
  putch('1');t-=100;}   //sign-digit is the sign, hund-digit is 1
else{putch(' ');        //absolute temp is lower than 100, sign-digit is a space
  if(t>9){putch(s);s=0;}//if 10..99: hund-digit is the sign
  else    putch(' ');}  //if  0.. 9: hund-digit is a space

c='0'-1;                //calculate tens
while(c++,(t-=10)>=0);  //this should be faster than c='0';while((t-=10)>=0)c++;
if(s)putch(s);          //if sign was not printed yet, do it now at tens-digit
else putch(c);          //tens-digit

putch(58+t);putch(',' );//ones-digit   '0'+10+t, as t is negative here
putch(g[f]);putch(h[f]);//the fractional digits are not calculated
putch('°' );putch('C' );//but stored in 2 arrays




Und hier der komplette Code für die Berechnung über den 12bit-Wert:
//Idea and code (C) by eProfi
//for better understanding  look at the table in
//www.mikrocontroller.net/topic/202928#1999183
//output format:
//  1      2      3    4  5   6    7
//sign hundreds tens ones , 1/10 1/100

const PROGMEM char
  g[16]="0011233455667889",//first  fractional digit
  h[16]="0639518406395184",//second fractional digit

  unsigned char d[9];     //Dallas DS1820 Scratchpad
  char t;                 //temperature in absolute degrees
  char f;                 //fractionals (1/16°) of absolute degrees
  char c,s;               //sign (if zero, the sign was printed already)
  int  t12;               //12bit temperature value

  t12=3+8*a[0]-((a[6]-1)&7);//alternate way of calculation
  if(a[1]){t12-=128*16;}  //correct by -128°
  if(t12>=0){s='+';}      //calc absolute temp
  else{t12=-t12;s='-';}

  f=t12&15;               //fractionals
  t=t12>>4;//must be signed int  for the calculation of tens-digit (while)

  if(t>99){putch(s);s=0;  //absolute temp is higher than 99 (and lower than 128)
    putch('1');t-=100;}   //sign-digit is the sign, hund-digit is 1
  else{putch(' ');        //absolute temp is lower than 100, sign-digit is a space
    if(t>9){putch(s);s=0;}//if 10..99: hund-digit is the sign
    else    putch(' ');}  //if  0.. 9: hund-digit is a space

  c='0'-1;                //calculate tens
  while(c++,(t-=10)>=0);  //this should be faster than c='0';while((t-=10)>=0)c++;
  if(s)putch(s);          //if sign was not printed yet, do it now at tens-digit
  else putch(c);          //tens-digit

  putch(58+t);putch(',' );//ones-digit   '0'+10+t, as t is negative here
  putch(g[f]);putch(h[f]);//the fractional digits are not calculated
  putch('°' );putch('C' );//but stored in 2 arrays

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grrr..
Vergesst die erste Hälfte des Posts, ist die Kopie des oberen.
Der neuen Codes steht in der zweiten Hälfte.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.