Forum: Mikrocontroller und Digitale Elektronik DHT22 Vorzeichen


von roger (Gast)


Lesenswert?

Ich arbeite mit dem DHT22/AM2302 , Die Temperaturwerte stimmen soweit 
auch unter null Grad.

Mein Problem liegt darin das Vorzeichen mit auszugeben.

Bei zb. -12.8Grad erhalte ich als Ausgabe +112.8Grad.

1
int sensor_byte = 0;
2
int kl = 0;
3
char buffer[15];
4
5
 kl = (sensor_data[2] << 8) + sensor_data[3];
6
   // negative
7
  if ( kl & 0x8000)
8
  {
9
  
10
   *temp = (kl & 0x7FFF)*-1;
11
   
12
  }
13
 
14
    else
15
  {
16
     *temp = (sensor_data[2] << 8) + sensor_data[3];
17
  }
18
19
 sprintf(buffer, "%+d.%d ", temp /10, temp %10));

von dhhdj (Gast)


Lesenswert?

wie ist denn temp definiert?

von roger (Gast)


Lesenswert?

dhhdj schrieb:
> wie ist denn temp definiert?

als int temp;

von asdfasd (Gast)


Lesenswert?

Zuweisung an "*temp" und lesen aus "temp"?!? Da müsste der Compiler aber 
meckern. Auch sonst einiges ... merkwürdig ;-)
1
int temp = (sensor_data[2] << 8) + sensor_data[3]; // one's-complement
2
int abstemp = temp & 0x7fff;
3
if (temp & 0x8000)
4
    temp = -abstemp;
5
sprintf(buffer, "%+d.d", temp / 10, abstemp % 10);

Beachte das "abstemp % 10", modulo von negativen Zahlen ...

von PittyJ (Gast)


Lesenswert?

Einmal wird temp als Pointer benutzt
 *temp =
einmal als normaler int
 temp /10

Du solltest dich für eine Variante entscheiden und dann durchgängig 
benutzen.

von roger (Gast)


Lesenswert?

1
//Aufruf in der Main
2
char buffer[15];
3
am2302(&humidity, &temp);
4
5
6
//Ausgabe
7
 sprintf(buffer, "%+d.%d ", temp /10, temp %10));
8
9
10
11
12
13
am2302( int*temp)
14
{
15
int sensor_byte = 0;
16
int kl = 0;
17
18
19
 kl = (sensor_data[2] << 8) + sensor_data[3];
20
   // negative
21
  if ( kl & 0x8000)
22
  {
23
  
24
   *temp = (kl & 0x7FFF)*-1;
25
   
26
  }
27
 
28
    else
29
  {
30
     *temp = (sensor_data[2] << 8) + sensor_data[3];
31
  }
32
}

von Jim M. (turboj)


Lesenswert?

roger schrieb:
> // negative
>   if ( kl & 0x8000)
>   {
>
>    *temp = (kl & 0x7FFF)*-1;
>
>   }

Da ist IIRC 1-er Komplement. Heutzutage verwendet man aber 2er 
Komplement, da funktioniert das so nicht.

Beispiel, original Bytes 0xFF 0xFF:
1
0xFFFF = -1
2
(0xFFFF &0x7FFF) = 32767 = 0x7FFF
3
4
(0xFFFF &0x7FFF) *(-1) = -32767 = 0xFFFF8001

Besser wäre:
1
if ( kl & 0x8000) {
2
  *temp = 0xFFFF0000 | kl;
3
}

*temp ist hier ein 32-bit int.

von Joe F. (easylife)


Lesenswert?

1
int temp;
2
3
temp = ((sensor_data[2] & 0x7F) << 8) | sensor_data[3];
4
if (sensor_data[2] & 0x80) { // highest bit indicating negative temperature
5
 temp = -temp;
6
}

von roger (Gast)


Lesenswert?

Joe F. schrieb:
> int temp;
>
> temp = ((sensor_data[2] & 0x7F) << 8) | sensor_data[3];
> if (sensor_data[2] & 0x80) { // highest bit indicating negative
> temperature
>  temp = -temp;
> }

So erhalte ich als Ausgabe +65425 bei -9.8 Grad

sprintf(buffer, "%+d.%d ", temp /10, temp %10));

von Wolfgang (Gast)


Lesenswert?

roger schrieb:
> So erhalte ich als Ausgabe +65425

Dann guck doch mal, wieviel Bit dein int hat. Die Bit-Puhlerei wird nur 
mit einem int16_t funktionieren, aber dann könnte in temp nicht 65425 
drin stehen

von roger (Gast)


Lesenswert?

Wolfgang schrieb:
> roger schrieb:
> So erhalte ich als Ausgabe +65425
>
> Dann guck doch mal, wieviel Bit dein int hat. Die Bit-Puhlerei wird nur
> mit einem int16_t funktionieren, aber dann könnte in temp nicht 65425
> drin stehen

Deklariert als 16Bit int16_t

von Joe F. (easylife)


Lesenswert?

roger schrieb:
> So erhalte ich als Ausgabe +65425 bei -9.8 Grad
>
> sprintf(buffer, "%+d.%d ", temp /10, temp %10));

Das kann ja nicht sein. Da fehlt ja dann mindestens der "." bei der 
Ausgabe.

Prüfe mal, was in sensor_data[2] und sensor_data[3] steht, bzw. gibt 
diese Werte auch mal mit aus.
1
int16_t temp;
2
uint8_t sensor_data[4];
3
 
4
sensor_data[2] = 0x80;  // negativ
5
sensor_data[3] = 98;    // 9.8°
6
7
temp = ((sensor_data[2] & 0x7F) << 8) | sensor_data[3];
8
if (sensor_data[2] & 0x80) { // highest bit indicating negative temperature
9
  temp = -temp;
10
}
11
12
printf("%+d.%d ", temp/10, abs(temp)%10);

gibt bei mir "-9.8 " aus.



Kleiner Schönheitsfehler noch:
1
sprintf(buffer, "%+d.%d ", temp /10, temp %10));

sollte besser
1
sprintf(buffer, "%+d.%d ", temp/10, abs(temp)%10));

lauten, sonst hast du negative Vorzeichen auch vor den Nachkommastellen.

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.