Forum: Mikrocontroller und Digitale Elektronik SHT11 und ATmega 128 -> Fehler bei negativen Temperaturen


von Max (Gast)


Lesenswert?

Hallo,

ich habe einen SHT11 an einem ATmega 128 und versuche nun die Werte über 
die UART auszugeben.
Mit der Feuchte funktioniert dies einwandfrei, mit der Temperatur gibt 
es jedoch Probleme.
Prinzipell funktioniert die Ausgabe wie gewünscht, jedoch habe ich 
diesen Winter festgestellt, dass bei einer Temperatur unterhalb von -9,9 
Grad nur noch "Müll" (wirre Zeichen) ausgegeben werden.
Alles über -9,9Grad funktioniert problemlos.

Ich kann jedoch den Fehler in meinem Code nicht finden.
Evtl. kann ja jemand der gerade in der Materie ist mal drüberschauen?

Anbei die relevanten Auszüge aus meinem Programm:
1
**************************************************************************************************
2
main.c
3
4
int main(void)
5
{
6
  UART_Init();                            //Initalisierung der UART
7
8
  while(1)
9
   {
10
      SHT_FEHLERFLAG = 0;          //Fehlerflag auf 0 setzen
11
      UART_Ausgabe();                     //Senden der Temperatur und Feuchtigkeit
12
      delay_ms(1000);             //max. 2 Lesevorgänge pro sec
13
   }
14
}
15
16
void UART_Ausgabe (void)       
17
{
18
  float TEMPERATUR = 0x00;                //Floatvariable für die Temperatur
19
  
20
  TEMPERATUR = 0x00;                    //Floatvariable für die Temperatur = 0
21
  
22
  TEMPERATUR = SHT_Temperatur();           //Schreibe aktuelle Temperatur in Variable
23
  dtostrf(TEMPERATUR, 1, 1, TEMPERATUR_STR);   //Float to String Wandlung
24
  
25
  if(SHT_FEHLERFLAG == 0)          //Filter falls Sensor abgezogen (falsche Werte)
26
    {
27
     UART_Senden_String (TEMPERATUR_STR);    //Senden der aktuellen Temperatur
28
     UART_Senden_String (" ");               //Leerzeichen
29
     UART_Senden_Byte (176);                 //Ausgeben des °
30
     UART_Senden_String ("C");               //Anhängen der Einheit C
31
    }
32
}
33
***************************************************************************************************
34
main.h
35
36
char TEMPERATUR_STR[5];                  //Array für Temperatur
37
char FEUCHTE_STR[5];                     //Array für Feuchte
38
char SHT_FEHLERFLAG;           //Wenn 1= SHT nicht angeschlossen
39
***************************************************************************************************
40
sht.c
41
42
void SHT_Transstart (void)
43
{
44
  MAKE_DATA_OUTPUT;       //Datenpin des SHT11 als Ausgang
45
  MAKE_SCK_OUTPUT;        //Takt des SHT11 als Ausgang
46
  _delay_us(EINPEGELN);
47
  SET_DATA_PIN;           //Datenpin auf High
48
  _delay_us(EINPEGELN);
49
  RESET_SCK_PIN;          //Taktpin auf Low       
50
  _delay_us(EINPEGELN);
51
  SET_SCK_PIN;            //Taktpin auf High
52
  _delay_us(EINPEGELN);
53
  RESET_DATA_PIN;         //Datenpin auf Low
54
  _delay_us(EINPEGELN);
55
  RESET_SCK_PIN;          //Taktpin auf Low
56
  _delay_us(EINPEGELN);
57
  SET_SCK_PIN;            //Taktpin auf High
58
  _delay_us(EINPEGELN);
59
  SET_DATA_PIN;           //Datenpin auf High
60
  _delay_us(EINPEGELN);
61
  RESET_SCK_PIN;          //Taktpin auf Low
62
  _delay_us(EINPEGELN);
63
}
64
65
/******************************************************************************************/
66
/********************************Connectionreset an SHT11**********************************/
67
/******************************************************************************************/
68
69
void SHT_Connectionreset (void)
70
{
71
  unsigned char i = 0x00; //Variable für Zählschleife
72
  
73
  MAKE_DATA_OUTPUT;       //Datenpin des SHT11 als Ausgang
74
  MAKE_SCK_OUTPUT;        //Taktpin des SHT11 als Ausgang
75
  _delay_us(EINPEGELN);
76
  SET_DATA_PIN;           //Datenpin auf High
77
  RESET_SCK_PIN;          //Taktpin auf Low
78
  for(i=0;i<9;i++)        //Schleife wird 9x ausgeführt
79
   { 
80
    SET_SCK_PIN;          //Taktpin auf High     
81
    _delay_us(EINPEGELN);
82
    RESET_SCK_PIN;        //Taktpin auf Low
83
    _delay_us(EINPEGELN);
84
   }
85
  SHT_Transstart();       //Ausgeben der nachfolgenden Transmissionstart Sequenz
86
}
87
88
/******************************************************************************************/
89
/**************************Byte an SHT11 senden und ACK überprüfen*************************/
90
/******************************************************************************************/
91
92
char SHT_Write_byte (unsigned char value)
93
{ 
94
  unsigned char i     = 0x00;     //Variable für Bitmaskierung (Schleife)
95
  unsigned char error = 0x00;     //Variable für ACK- Rückgabewert
96
  
97
  MAKE_SCK_OUTPUT;                //Taktpin des SHT11 als Ausgang
98
  
99
  for (i=0x80;i>0;i/=2)           //Verschiebe Bits für Maskierung
100
  { 
101
     if (i & value)               //(maskiere value mit i)
102
      {                           //Wenn Bit = 1 ist, dann:
103
       SET_DATA_PIN;              //Datenpin auf High
104
       _delay_us(EINPEGELN);
105
      }          
106
     else                         //Wenn Bit = 0 ist, dann:
107
      {
108
       RESET_DATA_PIN;            //Datenpin auf Low         
109
       _delay_us(EINPEGELN); 
110
      }    
111
  _delay_us(EINPEGELN);                                
112
  SET_SCK_PIN;                    //Taktpin auf High (CLK)
113
  _delay_us(EINPEGELN);
114
  RESET_SCK_PIN;                  //Taktpin auf Low
115
  _delay_us(EINPEGELN);
116
  }
117
  
118
  _delay_us(EINPEGELN);
119
  SET_DATA_PIN;                   //Datenpin auf High            
120
  _delay_us(EINPEGELN);
121
  SET_SCK_PIN;                    //Taktpin auf High (ACK)        
122
  _delay_us(EINPEGELN);
123
  MAKE_DATA_INPUT;                //Datenpin des SHT11 als Eingang
124
  
125
  if ((SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN)))  //Wenn Datenpin (ACK) = 1 dann:
126
  {
127
   error = 1;                     //setze "error" auf 1
128
  }
129
  else                            //ist ACK = Low (kein Fehler)
130
  {
131
   error = 0;                     //setze "error" auf 0
132
  }
133
  
134
  _delay_us(EINPEGELN);
135
  RESET_SCK_PIN;                  //Setze den Taktbin auf Low
136
  
137
  _delay_ms(400);                 //Warte auf das Wandlungsergebniss
138
   
139
  return (error);                 //"error" = 1, wenn Fehler aufgetreten (sonst 0)
140
}
141
142
/******************************************************************************************/
143
/**************Byte aus SHT11 lesen, ACK prüfen und ACK ausgeben (bei ACK = 1)*************/
144
/******************************************************************************************/
145
146
char SHT_Read_byte(unsigned char ack)
147
{ 
148
  unsigned char i   = 0x00;       //Variable für Bitmaskierung (Schleife)
149
  unsigned char val = 0x00;       //Variable für Bitlesefunktion
150
  
151
  MAKE_DATA_OUTPUT;               //Datenpin des SHT11 als Ausgang
152
  _delay_us(EINPEGELN);
153
  SET_DATA_PIN;                   //Datenpin auf Ausgang
154
  _delay_us(EINPEGELN);
155
  MAKE_DATA_INPUT;                //Datenpin des SHT11 als Eingang
156
                       
157
  for (i=0x80;i>0;i/=2)           //Verschiebe Bits für Maskierung
158
  {   
159
   SET_SCK_PIN;                   //Taktpin auf High (CLK)
160
   _delay_us(EINPEGELN);                
161
   if ((SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN)))     //Wenn Datenpin = 1, dann:
162
    {
163
     val=(val | i);               //schreibe Wert in "val"
164
    }       
165
   RESET_SCK_PIN;                 //Taktpin auf Low
166
   _delay_us(EINPEGELN);
167
  }
168
  
169
  _delay_us(EINPEGELN);
170
  MAKE_DATA_OUTPUT;               //Datenpin des SHT11 als Ausgang
171
  _delay_us(EINPEGELN);
172
  
173
  if(!ack == 1)                   //Wenn für ACK eine 1 übergeben wurde, dann:
174
  {
175
   SET_DATA_PIN;                  //Datenpin auf High
176
  }
177
  else
178
  {
179
   RESET_DATA_PIN                 //Datenpin auf Low
180
  }
181
  
182
  _delay_us(EINPEGELN);
183
  SET_SCK_PIN;                    //Taktpin auf High (ACK)
184
  _delay_us(EINPEGELN);
185
  RESET_SCK_PIN;                  //Taktpin auf Low
186
  _delay_us(EINPEGELN);
187
  SET_DATA_PIN;                   //Datenpin auf High
188
  _delay_us(EINPEGELN);
189
  
190
return (val);
191
}
192
193
/******************************************************************************************/
194
/***********************Auslesen und Rückgeben (Float) der Temperatur**********************/
195
/******************************************************************************************/
196
197
float SHT_Temperatur (void)
198
{
199
  uint8_t  TEMP_MSB       = 0x00;         //Variable für Temperatur MSN (erstes Byte)    
200
  uint8_t  TEMP_LSB       = 0x00;         //Variable für Temperatur LSB (zweites Byte) 
201
  uint16_t TEMP_16B       = 0x00;         //Variable für 16 Bit Temperaturwert
202
  float    TEMP_FLOAT     = 0x00;         //Variable für Float Temperaturwert
203
  
204
  SHT_Connectionreset();                  //Ausführen eines Connectionresets
205
  SHT_Transstart();                       //Ausgeben der Transmissionstart Sequenz
206
  SHT_Write_byte(0x03);                   //Schreibe Byte für Temp. (Adr.000, Com. 00011)
207
  
208
  TEMP_MSB = SHT_Read_byte(0x01);         //Lese das Temperatur MSN aus (mit ACK -> nächstes Byte)
209
  TEMP_LSB = SHT_Read_byte(0x00);         //Lese das Temperatur LSB aus (ohne ACK -> ohne Checksumme)
210
  
211
  TEMP_16B = TEMP_MSB << 8;               //Füge das Temp. MSB ein und verschiebe es um 8 Stellen
212
  TEMP_16B = TEMP_16B | TEMP_LSB;         //Lege das Temp. LSB drüber, sodass ein 16 Bit Wert entsteht
213
  
214
  TEMP_FLOAT = TEMP_16B;                  //schreibe den "uint16_t" Wert in ein "float" Wert
215
  TEMP_FLOAT = TEMP_FLOAT * 0.01 - 40;    //Umrechnung des Wertes in eine Temperatur (nach Datenblatt)
216
  
217
  if(TEMP_FLOAT >= 100)          //Filter fals Sensor abgezogen (falsche Werte)
218
   {
219
    SHT_FEHLERFLAG = 1;
220
   }
221
  
222
  return(TEMP_FLOAT);                     //Rückgabe des Temperaturwertes ("float")
223
}
224
***************************************************************************************************
225
sht.h
226
227
void    SHT_Transstart      (void);
228
void    SHT_Connectionreset (void);
229
char    SHT_Write_byte      (unsigned char);
230
char    SHT_Read_byte       (unsigned char);
231
float   SHT_Temperatur      (void);
232
float   SHT_Feuchte         (void);
233
234
#define SHT_SCK_DDR      DDRE
235
#define SHT_DATA_DDR     DDRE
236
237
#define SHT_SCK_PORT     PORTE
238
#define SHT_DATA_PORT    PORTE
239
240
#define SHT_DATA_PIN_IN  PINE
241
242
#define SHT_SCK_PIN      PE3
243
#define SHT_DATA_PIN     PE2
244
245
#define SET_DATA_PIN     SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);
246
#define SET_SCK_PIN      SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);
247
#define RESET_DATA_PIN   SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);      
248
#define RESET_SCK_PIN    SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);
249
250
#define MAKE_DATA_OUTPUT SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);
251
#define MAKE_DATA_INPUT  SHT_DATA_DDR = SHT_DATA_DDR & ~(1<<SHT_DATA_PIN); SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);
252
#define MAKE_SCK_OUTPUT  SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);
253
254
#define EINPEGELN        1      //Einpegelzeit zwischen Flankenwechsel in us

von Max (Gast)


Lesenswert?

Kann es evtl. mit der Float zu Stringwandlung zusammen hängen?

The dtostrf() function converts the double value passed in val into an 
ASCII representationthat
will be stored under s.

Ein double value ist ja kein float, oder?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Habe mir jetzt den SHT-11 nicht angesehen, aber das hier benutze
ich für einen SHT-21:
1
      v = ((uint16_t)b[0] << 8) | b[1];
2
      double t = -46.85 + 175.72 * (double)v / 65536.0;

b[0] und b[1] sind dabei die beiden Bytes des Temperaturmesswertes.

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.