Forum: Mikrocontroller und Digitale Elektronik AVR - SHT11 liefert zu große Werte


von Gast (Gast)


Lesenswert?

Hallo,

ich versuche mit einem ATMega die Temperatur eines SHT11 auszulesen.
Leider ist in meinem Programm jedoch ein Logikfehler.
Es kommen immer zu große Werte beim auslesen raus.
(auch ohne die Rechnung, sondern in dem 16Bit Wert selber)
Es ändern sich jeweils nur die ersten 8 Bit des 16 Bit Integer.
Der SHT selber ist an PB0 und PB1 angeschlossen, ein Pullup an der DATA- 
Leitung (4k7) und ein 100n ist vorhanden.
Könnte dort mal bitte jemand drüber schauen ob er einen Fehler findet?!?


Gruß
Gast


1
#include <avr/io.h>
2
#include <util/delay.h>                
3
4
//Anschlussdefinition des SHT11
5
#define SHT_SCK_DDR      DDRB
6
#define SHT_DATA_DDR     DDRB
7
8
#define SHT_SCK_PORT     PORTB
9
#define SHT_DATA_PORT    PORTB
10
11
#define SHT_DATA_PIN_IN  PINB
12
13
#define SHT_SCK_PIN      PB0
14
#define SHT_DATA_PIN     PB1
15
16
//Einpegelzeit zwischen einem Flankenwechsel in ms
17
#define EINPEGELN       1
18
19
20
uint16_t TEMP = 0;              //Temp. Variable
21
22
//Prototypen
23
int Start_Temp_Messung (void);
24
int TransmissionStart(void);
25
int Adresse(void);
26
int Temperaturmessung(void);
27
int Tempaufnahme(void);
28
int Taktimpuls(void);
29
int Temp_umrechnung(void);
30
31
////////////////////////////////////////////////////////////////////////////////////////
32
int main(void)
33
{
34
  Start_Temp_Messung();
35
36
  //Testschleife für Breakpoint
37
  while(1) 
38
  {
39
  _delay_ms(1000);
40
  }
41
}
42
////////////////////////////////////////////////////////////////////////////////////////
43
44
////////////////////////////////////////////////////////////////////////////////////////
45
int Start_Temp_Messung(void)
46
{
47
_delay_ms(20);                          //Warte 20ms bis SHT in Sleep-Mode
48
TransmissionStart();                    //TransmissionStart- Sequenz
49
Adresse();                              //Adress- Sequenz (000)
50
Temperaturmessung();                    //Befehl -> Temperaturmessung (00011)
51
Tempaufnahme();                         //Empfangen des 14Bit Temp. Messwertes
52
Temp_umrechnung();                      //Umrechnung 16Bit Wert zu Temp.
53
54
return(0);
55
}
56
////////////////////////////////////////////////////////////////////////////////////////
57
58
////////////////////////////////////////////////////////////////////////////////////////
59
int TransmissionStart(void)
60
{
61
////////////Connection Reset Sequenz/////////////////
62
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen
63
SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);           //Taktpin als Ausgang setzen
64
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
65
Taktimpuls();                                           //Taktsignal -> H -> L
66
Taktimpuls();                                           //Taktsignal -> H -> L
67
Taktimpuls();                                           //Taktsignal -> H -> L
68
Taktimpuls();                                           //Taktsignal -> H -> L
69
Taktimpuls();                                           //Taktsignal -> H -> L
70
Taktimpuls();                                           //Taktsignal -> H -> L
71
Taktimpuls();                                           //Taktsignal -> H -> L
72
Taktimpuls();                                           //Taktsignal -> H -> L
73
Taktimpuls();                                           //Taktsignal -> H -> L
74
Taktimpuls();                                           //Taktsignal -> H -> L
75
Taktimpuls();                                           //Taktsignal -> H -> L
76
////////////Connection Reset Sequenz/////////////////
77
78
//SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen
79
//SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);           //Taktpin als Ausgang setzen
80
81
//Transmission Start Sequenz
82
_delay_ms(EINPEGELN);     
83
84
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
85
SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen
86
87
_delay_ms(EINPEGELN); 
88
89
SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);         //Taktpin auf HIGH setzen
90
91
_delay_ms(EINPEGELN);     
92
93
SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen
94
95
_delay_ms(EINPEGELN);     
96
97
SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen
98
99
_delay_ms(EINPEGELN);     
100
                                         
101
SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);         //Taktpin auf HIGH setzen
102
103
_delay_ms(EINPEGELN);     
104
105
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
106
107
_delay_ms(EINPEGELN); 
108
109
SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen
110
111
_delay_ms(EINPEGELN); 
112
113
return(0);    
114
}
115
////////////////////////////////////////////////////////////////////////////////////////
116
117
////////////////////////////////////////////////////////////////////////////////////////
118
int Adresse(void)
119
{
120
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen
121
SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);           //Taktpin als Ausgang setzen
122
123
//Übermitteln der Adresse (000)
124
_delay_ms(EINPEGELN);   
125
126
SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen
127
128
Taktimpuls();                                           //Taktsignal -> H -> L
129
130
Taktimpuls();                                           //Taktsignal -> H -> L
131
132
Taktimpuls();                                           //Taktsignal -> H -> L
133
return(0);
134
}
135
////////////////////////////////////////////////////////////////////////////////////////
136
137
////////////////////////////////////////////////////////////////////////////////////////
138
int Temperaturmessung(void)
139
{
140
//Übermitteln des Komandos
141
Taktimpuls();                                           //Taktsignal -> H -> L
142
143
Taktimpuls();                                           //Taktsignal -> H -> L
144
145
Taktimpuls();                                           //Taktsignal -> H -> L
146
147
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
148
149
Taktimpuls();                                           //Taktsignal -> H -> L 
150
151
Taktimpuls();                                           //Taktsignal -> H -> L
152
153
_delay_ms(EINPEGELN);
154
SHT_DATA_DDR = SHT_DATA_DDR & ~(1<<SHT_DATA_PIN);       //Datenpin als Eingang setzen
155
SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen (PullUP OFF)
156
157
Taktimpuls();                                           //Taktsignal -> H -> L (ACK)
158
159
_delay_ms(450);                                         //Warte auf Messergebniss
160
//Warteschleife + Watchdog
161
162
return(0);
163
}
164
////////////////////////////////////////////////////////////////////////////////////////
165
166
////////////////////////////////////////////////////////////////////////////////////////
167
int Tempaufnahme(void)
168
{
169
TEMP = 0;
170
171
//Auslesen MSB
172
Taktimpuls();                                           //Taktsignal -> H -> L
173
174
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
175
{
176
TEMP = TEMP | (1<<15);                                  //Schreibe 1 in Bit 16 von MSB
177
}
178
179
Taktimpuls();                                           //Taktsignal -> H -> L
180
181
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
182
{
183
TEMP = TEMP | (1<<14);                                  //Schreibe 1 in Bit 15 von MSB
184
}
185
186
Taktimpuls();                                           //Taktsignal -> H -> L
187
188
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
189
{
190
TEMP = TEMP | (1<<13);                                  //Schreibe 1 in Bit 14 von MSB
191
}
192
193
Taktimpuls();                                           //Taktsignal -> H -> L
194
195
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
196
{
197
TEMP = TEMP | (1<<12);                                  //Schreibe 1 in Bit 13 von MSB
198
}
199
200
Taktimpuls();                                           //Taktsignal -> H -> L
201
202
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
203
{
204
TEMP = TEMP | (1<<11);                                  //Schreibe 1 in Bit 12 von MSB
205
}
206
207
Taktimpuls();                                           //Taktsignal -> H -> L
208
209
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
210
{
211
TEMP = TEMP | (1<<10);                                  //Schreibe 1 in Bit 11 von MSB
212
}
213
214
Taktimpuls();                                           //Taktsignal -> H -> L
215
216
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
217
{
218
TEMP = TEMP | (1<<9);                                   //Schreibe 1 in Bit 10 von MSB
219
}
220
221
Taktimpuls();                                           //Taktsignal -> H -> L
222
223
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
224
{
225
TEMP = TEMP | (1<<8);                                   //Schreibe 1 in Bit 9 von MSB
226
}
227
228
_delay_ms(EINPEGELN); 
229
230
//ACK zwischen den beiden 8- Bit- Feldern
231
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen (ACK)
232
233
_delay_ms(EINPEGELN);   
234
235
SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen
236
237
_delay_ms(EINPEGELN);  
238
239
Taktimpuls();                                           //Taktsignal -> H -> L
240
241
SHT_DATA_DDR = SHT_DATA_DDR & ~(1<<SHT_DATA_PIN);       //Datenpin als Eingang setzen
242
243
_delay_ms(EINPEGELN);
244
245
//Auslesen LSB
246
Taktimpuls();                                           //Taktsignal -> H -> L
247
248
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
249
{
250
TEMP = TEMP | (1<<7);                                   //Schreibe 1 in Bit 8 von MSB
251
}
252
253
Taktimpuls();                                           //Taktsignal -> H -> L
254
255
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
256
{
257
TEMP = TEMP | (1<<6);                                   //Schreibe 1 in Bit 7 von MSB
258
}
259
260
Taktimpuls();                                           //Taktsignal -> H -> L
261
262
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
263
{
264
TEMP = TEMP | (1<<5);                                   //Schreibe 1 in Bit 6 von MSB
265
}
266
267
Taktimpuls();                                           //Taktsignal -> H -> L
268
269
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
270
{
271
TEMP = TEMP | (1<<4);                                   //Schreibe 1 in Bit 5 von MSB
272
}
273
274
Taktimpuls();                                           //Taktsignal -> H -> L
275
276
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
277
{
278
TEMP = TEMP | (1<<3);                                   //Schreibe 1 in Bit 4 von MSB
279
}
280
281
Taktimpuls();                                           //Taktsignal -> H -> L
282
283
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
284
{
285
TEMP = TEMP | (1<<2);                                   //Schreibe 1 in Bit 3 von MSB
286
}
287
288
Taktimpuls();                                           //Taktsignal -> H -> L
289
290
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
291
{
292
TEMP = TEMP | (1<<1);                                   //Schreibe 1 in Bit 2 von MSB
293
}
294
295
Taktimpuls();                                           //Taktsignal -> H -> L
296
297
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
298
{
299
TEMP = TEMP | (1<<0);                                   //Schreibe 1 in Bit 1 von MSB
300
}
301
302
_delay_ms(EINPEGELN);
303
304
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen (ACK)
305
306
_delay_ms(EINPEGELN);  
307
308
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen (NO CRC)
309
310
Taktimpuls();                                           //Taktsignal -> H -> L
311
312
return(0);
313
}
314
////////////////////////////////////////////////////////////////////////////////////////
315
316
int Taktimpuls(void)
317
{
318
_delay_ms(EINPEGELN);
319
320
SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);         //Taktpin auf HIGH setzen 
321
322
_delay_ms(EINPEGELN); 
323
324
SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen 
325
326
_delay_ms(EINPEGELN);
327
328
return(0);
329
}
330
331
int Temp_umrechnung(void)
332
{
333
TEMP = TEMP * 0.01;
334
TEMP = TEMP - 40;
335
return(0);
336
}

von Anselm (Gast)


Lesenswert?

Ich habe dass ganze in Bascom, dort hole ich die Temp. als 2x8Bit ab, 
jeder Block muss quittiert werden.
C kann ich nicht so toll, aber es sieht für mich aus als würdest du die 
Daten auf einmal holen wollen.
[quote]
Two bytes of measurement data and one byte of CRC
checksum (optional) will then be transmitted. The micro
controller must acknowledge each byte by pulling the
DATA line low. All values are MSB first, right justified
[/quote]

Gruß Anselm

von Gast (Gast)


Lesenswert?

Nein, ich frage jeweils ein Bit nach dem anderen ab und quittiere dass 
auch durch ein Hi/Lo Impuls.

PS. Ja, der Code ist durch lauter umbauen und "Rumprobierereien" etwas 
unstrukturiert geworden ;)

von Helmut -. (dc3yc)


Lesenswert?

Sensirion hat doch eine gute Applikationsschrift zur Datenübertragung. 
Das funzt bei mir wunderbar!

Helmut.

von Hans W. (hans_wurst)


Lesenswert?


von MSPProfi (Gast)


Lesenswert?

TEMP sollte mindestens vom Typ float sein, wenn du sowas wie *0.01 
machst. Ausserdem wäre es schön wenn du TEMP dann z.B. fTemp schreiben 
würdest. In Tempaufnahme() kannst du lokal eine int-Variable 
deklarieren, in die du Bits einliest (anstatt TEMP) und dann den 
Temp-Wert vom Sensor zurücklieferst. Den zurückgelieferten Wert 
übergibst du dann Temp_umrechnung().
Liefert der SHT nicht noch eine Prüfsumme die geprüft werden sollte?


float Temp_umrechnung( unsigned int uiMesswert)
{
return( ( float)uiMesswert * 0.01f - 40.0f);
}

von Gast (Gast)


Lesenswert?

Hallo,

die Umrechnung ist kein Problem.
Und ein Floatwert ist auch erst bei der Rechnung notwendig.
Mein Problem liegt aber schon darin dass der 16 Bit Integer Wert (TEMP) 
schon gar nicht richtig ausgelesen wird. (per JTAG)
Es kommt ein viel zu hoher Wert raus, sodass ich beim ausrechnen der 
Temp. per Taschenrechner schon auf knapp 100Grad komme.
Ich vermute es ist ein Timing Problem, bzw. dass irgendwo ein "Takt" 
vergessen wurde, konnte aber nichts finden ;(

Schönen Samstag noch..
GAST

von STK500-Besitzer (Gast)


Lesenswert?

Hast du schon mal was von Schleifen und Feldern gehört?
Benutze diese und dein Programm wird wesentlich übersichtlicher.

[OT]
Du heisst nicht zufällig Sascha?
{/OT]

von Sven .. (badst0ck)


Lesenswert?

Also ich würde die ersten 8 bit einlesen und die mit 256 multiplizieren.
dann die letzten 8 bit und addieren.
Und ein delay von 10ms zwischen den Einlesen der Dataleitung ist auch 
immer gut.
An wieviel Volt hängt denn der SHT11?

von Klugscheißer (Gast)


Lesenswert?

Check doch erstmal die Prüfsumme vom SHT.

Dann lerne mal g'scheit C zu programmieren. Den Spaghetti-Code kannste 
in die Tonne treten.

von (prx) A. K. (prx)


Lesenswert?

Gast wrote:

> Und ein Floatwert ist auch erst bei der Rechnung notwendig.

Nö. Man das auch problemlos auf Festkommaformat ausrechnen um die 
Temperatur beispielsweise in 1/100 Graden zu erhalten. Siehe 
Beitrag "Re: Programmierung des SHT11 mit dem AT90S4433".

von GAST (Gast)


Lesenswert?

Ich werde wohl nochmal von 0 anfangen ;-)

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.