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
}

: Bearbeitet durch User
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.

: Bearbeitet durch User
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.