Forum: Mikrocontroller und Digitale Elektronik DS18S20 Negative Temprratur


von kurt (Gast)


Lesenswert?

Hallo,
Ich Wandele mit der Routine den Gemessenen Wert vom DS18S20 in eine 
Temperratur um.
Bei Plusgraden geht alles einwandfrei,Nur enben nicht bei Minusgraden.
ich habe jetz eine Temperratur von -0.5Grad Angezeigt bekomme ich aber
+0.-5 Grad.
wo mache ich nur den Fehler.
vielleicht kann mir von ihnen einer weiterhelfen.
mfg
1
// wandelt den Messwert, um.
2
void DS18S20_convert_temperatur(void)
3
{  
4
    
5
  
6
    int temp;
7
    int temp1;
8
    int16_t Vorkommastelle;
9
    int16_t Nachkommastelle;  
10
  
11
    if( id[1] ) {                // Negativer Temperaturwert
12
    id[0] ^= 0xFF;               // Einer-Komplement
13
    id[0]++;                     // inkrementieren
14
    }
15
    id[0] >>= 1;                 // rechtes Bit für 0,5 °C rausschieben (durch 2 teilen)
16
    
17
  // Temperatur mit 0,1 °C Genauigkeit berechnen
18
    temp = (int)id[0]*100 - 25 + (int)(id[7] - id[6]) * 100 / id[7];
19
    temp1= temp;
20
    if( id[1])                   // Negativer Temperaturwert
21
     {
22
      temp *= -1;
23
   }
24
25
    else
26
     {
27
           
28
     }
29
  
30
    Vorkommastelle = temp / 100;
31
    Nachkommastelle = (temp1 % 100);
32
    Nachkommastelle = (temp % 100);
33
 
34
35
    sprintf(msg,"%+3d,%1d", Vorkommastelle, Nachkommastelle);    
36
    uart_puts( msg); 
37
    uart_putc( ' ' );
38
}

von Karl H. (kbuchegg)


Lesenswert?

kurt schrieb:
> Hallo,
> Ich Wandele mit der Routine den Gemessenen Wert vom DS18S20 in eine
> Temperratur um.
> Bei Plusgraden geht alles einwandfrei,Nur enben nicht bei Minusgraden.
> ich habe jetz eine Temperratur von -0.5Grad Angezeigt bekomme ich aber
> +0.-5 Grad.

Daraus folgt erst mal: ganz offensichtlich in der Ausgabe

> wo mache ich nur den Fehler.

Machs so:
Wenn der Wert negativ wird, dann malst du erst mal ein '-' hin und 
machst den Wert positiv. Und den positiven Wert kannst du ja richtig 
ausgeben

Hintergrund.

Der Rest einer Division kann auch negativ sein!

   char Sign;



      if( temp < 0 ) {
        Sign = '-';
        temp = -temp;
      }
      else
        Sign = '+';

>     Vorkommastelle = temp / 100;
>     Nachkommastelle = (temp1 % 100);
>     Nachkommastelle = (temp % 100);
>
      sprintf(msg, "%c%3d,%1d", Sign, Vorkommastelle, Nachkommastelle);


PS: Du bist sicher, dass dein temp Wert grundsätzlich korrekt ist? Ich 
kann deine Berechnung da nicht wirklich nachvollziehen.

von kurt (Gast)


Lesenswert?

Es wird doch hier
    if( id[1])                   // Negativer Temperaturwert
     {
      temp *= -1;
     }
Geprüft  ob der Wert Negative ist,Wenn Negative dann wird temp *= -1; 
auch Negativ.

Vor dem Prüfen habe ich mir ja den Temp Wert
    temp = (int)id[0]*100 - 25 + (int)(id[7] - id[6]) * 100 / id[7];
    temp1= temp;
kopiert in temp1 für die Nachkommastellen.

Dann sollte doch auch die Nachkomma stelle richtig angezeigt werden,
aber warum funktioniert das nicht.

ich habs jetzt mal nsch ihren Vorschlag umgesetzt aber die Teperatur 
stimmt jetzt nicht mehr

1
// wandelt den Messwert, um.
2
void DS18S20_convert_temperatur(void)
3
{  
4
    
5
char Sign;
6
    int temp;
7
    int temp1;
8
    int16_t Vorkommastelle;
9
    int16_t Nachkommastelle;  
10
  
11
    if( id[1] ) {                // Negativer Temperaturwert
12
    id[0] ^= 0xFF;               // Einer-Komplement
13
    id[0]++;                     // inkrementieren
14
    }
15
    id[0] >>= 1;                 // rechtes Bit für 0,5 °C rausschieben (durch 2 teilen)
16
    
17
  // Temperatur mit 0,1 °C Genauigkeit berechnen
18
    temp = (int)id[0]*100 - 25 + (int)(id[7] - id[6]) * 100 / id[7];
19
    temp1= temp;
20
    // if( id[1])                   // Negativer Temperaturwert
21
    //  {
22
    //   temp *= -1;
23
    //  }
24
25
    // else
26
    //  {
27
           
28
    //  }
29
      if( temp < 0 ) {
30
        Sign = '-';
31
        temp = -temp;
32
      }
33
      else
34
        Sign = '+';
35
  
36
     Vorkommastelle = temp / 100;
37
     Nachkommastelle = (temp1 % 100);
38
     Nachkommastelle = (Nachkommastelle / 10);
39
 
40
41
     // sprintf(msg,"%3d,%1d", Vorkommastelle, Nachkommastelle);    
42
   sprintf(msg,"%3d,%1d", Sign, Vorkommastelle, Nachkommastelle);
43
     uart_puts( msg); 
44
     uart_putc( ' ' );
45
  
46
 
47
}

von Georg G. (df2au)


Lesenswert?

Die Lösung steht weiter oben schon: kbuchegg: Auch ein Rest kann negativ 
sein.

kurt schrieb:
> // Temperatur mit 0,1 °C Genauigkeit berechnen
>     temp = (int)id[0]*100 - 25 + (int)(id[7] - id[6]) * 100 / id[7];
>     temp1= temp;
temp1 ist hier negativ.

>       if( temp < 0 ) {
>         Sign = '-';
>         temp = -temp;
>       }
>       else
>         Sign = '+';
>
>      Vorkommastelle = temp / 100;

temp1 ist immer noch negativ.
>      Nachkommastelle = (temp1 % 100);
also ist Nachkommastelle auch negativ.

>      Nachkommastelle = (Nachkommastelle / 10);
>
>
>    sprintf(msg,"%3d,%1d", Sign, Vorkommastelle, Nachkommastelle);
Abgesehen davon, dass ich persönlich für 3 Variable auch dreimal "%" 
genommen hätte, kommt es hier zu genau der von dir gezeigten Ausgabe: 
Das Minuszeichen erscheint vor der Nachkommestelle.

von Karl H. (kbuchegg)


Lesenswert?

kurt schrieb:

> ich habs jetzt mal nsch ihren Vorschlag umgesetzt

Nicht wirklich.
Du warst zu schlampig

1
     Vorkommastelle = temp / 100;
2
     Nachkommastelle = (temp1 % 100);
beim % temp nehmen und nicht temp1! Es muss schon immer von derselben 
Zahl ausgegangen werden!


1
   sprintf(msg,"%3d,%1d", Sign, Vorkommastelle, Nachkommastelle);
Zähl die auszugebenden Argumente: es sind 3  (Sign, Vorkomma, Nachkomma)
Zähl die Anzahl der % im Format String: es sind 2

Das passt nicht zusammen.

von kurt (Gast)


Lesenswert?

Hallo.
vielleicht kann mir noch einer Weiterhelfen

1
Als Angezeigten Wert bekomme ich +0.5 obwohl es -0.5 grad sein müssten
2
3
// wandelt den Messwert, um.
4
void DS18S20_convert_temperatur(void)
5
{  
6
    
7
    char Sign;
8
    int temp;
9
    
10
    int16_t Vorkommastelle;
11
    int16_t Nachkommastelle;  
12
  
13
    if( id[1] ) {                // Negativer Temperaturwert
14
    id[0] ^= 0xFF;               // Einer-Komplement
15
    id[0]++;                     // inkrementieren
16
    }
17
    id[0] >>= 1;                 // rechtes Bit für 0,5 °C rausschieben (durch 2 teilen)
18
    
19
  // Temperatur mit 0,1 °C Genauigkeit berechnen
20
    temp = (int)id[0]*100 - 25 + (int)(id[7] - id[6]) * 100 / id[7];
21
22
      if( temp < 0 ) {
23
        Sign = '-';
24
        temp = -temp;
25
      }
26
      else
27
        Sign = '+';
28
  
29
30
     Vorkommastelle = temp / 100;
31
     Nachkommastelle = (temp % 100);     
32
   
33
     sprintf(msg,"%c%3d,%1d", Sign, Vorkommastelle, Nachkommastelle);
34
     uart_puts( msg); 
35
     uart_putc( ' ' );
36
}
37
38
Hier stimmt der wert zwar aber das minus-zeichen ist nicht an der richtigen stelle  +0.-5 als anzeige. 
39
40
Ist der Wert zb -1.3 Dann stimmt die Anzeige
41
42
43
void DS18S20_convert_temperatur(void)
44
{  
45
    
46
47
    int temp;
48
    //int temp1;
49
    int16_t Vorkommastelle;
50
    int16_t Nachkommastelle;  
51
  
52
    if( id[1] ) {                // Negativer Temperaturwert
53
    id[0] ^= 0xFF;               // Einer-Komplement
54
    id[0]++;                     // inkrementieren
55
    }
56
    id[0] >>= 1;                 // rechtes Bit für 0,5 °C rausschieben (durch 2 teilen)
57
    
58
  // Temperatur mit 0,1 °C Genauigkeit berechnen
59
    temp = (int)id[0]*100 - 25 + (int)(id[7] - id[6]) * 100 / id[7];
60
    //temp1= temp;
61
     if( id[1])                   // Negativer Temperaturwert
62
      {
63
       temp *= -1;
64
      }
65
66
     else
67
      {
68
           
69
      }
70
 
71
     Vorkommastelle = temp / 100;
72
     Nachkommastelle = (temp % 100);      
73
     sprintf(msg,"%+3d,%1d", Vorkommastelle, Nachkommastelle);    
74
 
75
     
76
     uart_puts( msg); 
77
     uart_putc( ' ' );
78
  
79
 
80
}

von Karl H. (kbuchegg)


Lesenswert?

kurt schrieb:
> Hallo.
> vielleicht kann mir noch einer Weiterhelfen
>

Lass dir mal temp mit ausgeben. Ich denke, dass da schon was nicht 
stimmt.


      sprintf(msg,"%d  %c%3d,%02d", temp, Sign, Vorkommastelle, 
Nachkommastelle);

von Cyblord -. (cyblord)


Lesenswert?

In C muss man da gar nichts umrechnen. Man steckt das Ergebniss direkt 
in eine int16 Variable und hat dann automatisch plus und minus korrekt. 
Wenn man es durch 16 teilt bekommt man die Temp in Grad. Macht man 
VOHRHER noch mal 10 dann bekommt man sie in zehntel Grad. Bei -0,5 Grad 
steht dann -5 in der Variablen. Ohne Umrechnen oder sonst was.

gruß cyblord

von Karl H. (kbuchegg)


Lesenswert?

cyblord ---- schrieb:
> In C muss man da gar nichts umrechnen.

Er will vom DS1820 auch die zusätzlichen Bytes benutzen um auf die 
'erhöhte' Genauigkeit zu kommen. Dazu ist im Datenblatt eine Formel 
angegeben.

Ist zwar in den meisten Fällen sowieso Schwachsinn, weil die Temperatur 
eh nicht stimmen wird, aber des Menschen Wille ...

Ich denke allerdings, dass da beim zusammensetzen der Bytes schon was 
nicht stimmt.

von Cyblord -. (cyblord)


Lesenswert?

Ups hab ich überlesen. Aber du dürftest Recht haben, da haperts am 
zusammenstecken der Bytes.

von kurt (Gast)


Lesenswert?

ich habe anstatt int16_t Nachkommastelle ein uint8_t Nachkommastelle 
benutzt, so nun wird die Temperatur und das Vorzeichen auch korrekt 
Ausgegeben.


Karl Heinz Buchegger schrieb:
>
> Ich denke allerdings, dass da beim zusammensetzen der Bytes schon was
> nicht stimmt.
Wie macht mann das denn Richtig ihrer Ansicht nach.
mfg

1
void DS18S20_convert_temperatur(void)
2
{  
3
    
4
5
    int temp;
6
    int16_t Vorkommastelle;
7
    uint8_t Nachkommastelle;
8
   
9
    if( id[1] ) {                // Negativer Temperaturwert
10
    id[0] ^= 0xFF;               // Einer-Komplement
11
    id[0]++;                     // inkrementieren
12
    }
13
    id[0] >>= 1;                 // rechtes Bit für 0,5 °C rausschieben (durch 2 teilen)
14
    
15
  // Temperatur mit 0,1 °C Genauigkeit berechnen
16
    temp = (int)id[0]*100 - 25 + (int)(id[7] - id[6]) * 100 / id[7];
17
    
18
     if( id[1])                   // Negativer Temperaturwert
19
      {
20
       temp *= -1;
21
      }
22
23
     else
24
      {
25
          
26
      }
27
 
28
     Vorkommastelle = temp / 100;
29
     Nachkommastelle = (temp % 100);      
30
     Nachkommastelle = (Nachkommastelle / 10);// Zweite Nachkommastelle abtrennen
31
     sprintf(msg,"%+3d,%1d", Vorkommastelle, Nachkommastelle);    
32
 
33
     
34
     uart_puts( msg); 
35
     uart_putc( ' ' );
36
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.