mikrocontroller.net

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


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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


#include <avr/io.h>
#include <util/delay.h>                

//Anschlussdefinition des SHT11
#define SHT_SCK_DDR      DDRB
#define SHT_DATA_DDR     DDRB

#define SHT_SCK_PORT     PORTB
#define SHT_DATA_PORT    PORTB

#define SHT_DATA_PIN_IN  PINB

#define SHT_SCK_PIN      PB0
#define SHT_DATA_PIN     PB1

//Einpegelzeit zwischen einem Flankenwechsel in ms
#define EINPEGELN       1


uint16_t TEMP = 0;              //Temp. Variable

//Prototypen
int Start_Temp_Messung (void);
int TransmissionStart(void);
int Adresse(void);
int Temperaturmessung(void);
int Tempaufnahme(void);
int Taktimpuls(void);
int Temp_umrechnung(void);

////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
  Start_Temp_Messung();

  //Testschleife für Breakpoint
  while(1) 
  {
  _delay_ms(1000);
  }
}
////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////
int Start_Temp_Messung(void)
{
_delay_ms(20);                          //Warte 20ms bis SHT in Sleep-Mode
TransmissionStart();                    //TransmissionStart- Sequenz
Adresse();                              //Adress- Sequenz (000)
Temperaturmessung();                    //Befehl -> Temperaturmessung (00011)
Tempaufnahme();                         //Empfangen des 14Bit Temp. Messwertes
Temp_umrechnung();                      //Umrechnung 16Bit Wert zu Temp.

return(0);
}
////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////
int TransmissionStart(void)
{
////////////Connection Reset Sequenz/////////////////
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen
SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);           //Taktpin als Ausgang setzen
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
Taktimpuls();                                           //Taktsignal -> H -> L
////////////Connection Reset Sequenz/////////////////

//SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen
//SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);           //Taktpin als Ausgang setzen

//Transmission Start Sequenz
_delay_ms(EINPEGELN);     

SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen

_delay_ms(EINPEGELN); 

SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);         //Taktpin auf HIGH setzen

_delay_ms(EINPEGELN);     

SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen

_delay_ms(EINPEGELN);     

SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen

_delay_ms(EINPEGELN);     
                                         
SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);         //Taktpin auf HIGH setzen

_delay_ms(EINPEGELN);     

SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen

_delay_ms(EINPEGELN); 

SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen

_delay_ms(EINPEGELN); 

return(0);    
}
////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////
int Adresse(void)
{
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen
SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);           //Taktpin als Ausgang setzen

//Übermitteln der Adresse (000)
_delay_ms(EINPEGELN);   

SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen

Taktimpuls();                                           //Taktsignal -> H -> L

Taktimpuls();                                           //Taktsignal -> H -> L

Taktimpuls();                                           //Taktsignal -> H -> L
return(0);
}
////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////
int Temperaturmessung(void)
{
//Übermitteln des Komandos
Taktimpuls();                                           //Taktsignal -> H -> L

Taktimpuls();                                           //Taktsignal -> H -> L

Taktimpuls();                                           //Taktsignal -> H -> L

SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen

Taktimpuls();                                           //Taktsignal -> H -> L 

Taktimpuls();                                           //Taktsignal -> H -> L

_delay_ms(EINPEGELN);
SHT_DATA_DDR = SHT_DATA_DDR & ~(1<<SHT_DATA_PIN);       //Datenpin als Eingang setzen
SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen (PullUP OFF)

Taktimpuls();                                           //Taktsignal -> H -> L (ACK)

_delay_ms(450);                                         //Warte auf Messergebniss
//Warteschleife + Watchdog

return(0);
}
////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////
int Tempaufnahme(void)
{
TEMP = 0;

//Auslesen MSB
Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<15);                                  //Schreibe 1 in Bit 16 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<14);                                  //Schreibe 1 in Bit 15 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<13);                                  //Schreibe 1 in Bit 14 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<12);                                  //Schreibe 1 in Bit 13 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<11);                                  //Schreibe 1 in Bit 12 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<10);                                  //Schreibe 1 in Bit 11 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<9);                                   //Schreibe 1 in Bit 10 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<8);                                   //Schreibe 1 in Bit 9 von MSB
}

_delay_ms(EINPEGELN); 

//ACK zwischen den beiden 8- Bit- Feldern
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen (ACK)

_delay_ms(EINPEGELN);   

SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen

_delay_ms(EINPEGELN);  

Taktimpuls();                                           //Taktsignal -> H -> L

SHT_DATA_DDR = SHT_DATA_DDR & ~(1<<SHT_DATA_PIN);       //Datenpin als Eingang setzen

_delay_ms(EINPEGELN);

//Auslesen LSB
Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<7);                                   //Schreibe 1 in Bit 8 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<6);                                   //Schreibe 1 in Bit 7 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<5);                                   //Schreibe 1 in Bit 6 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<4);                                   //Schreibe 1 in Bit 5 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<3);                                   //Schreibe 1 in Bit 4 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<2);                                   //Schreibe 1 in Bit 3 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<1);                                   //Schreibe 1 in Bit 2 von MSB
}

Taktimpuls();                                           //Taktsignal -> H -> L

if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
{
TEMP = TEMP | (1<<0);                                   //Schreibe 1 in Bit 1 von MSB
}

_delay_ms(EINPEGELN);

SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen (ACK)

_delay_ms(EINPEGELN);  

SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen (NO CRC)

Taktimpuls();                                           //Taktsignal -> H -> L

return(0);
}
////////////////////////////////////////////////////////////////////////////////////////

int Taktimpuls(void)
{
_delay_ms(EINPEGELN);

SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);         //Taktpin auf HIGH setzen 

_delay_ms(EINPEGELN); 

SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen 

_delay_ms(EINPEGELN);

return(0);
}

int Temp_umrechnung(void)
{
TEMP = TEMP * 0.01;
TEMP = TEMP - 40;
return(0);
}


Autor: Anselm (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Helmut -dc3yc (dc3yc)
Datum:

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

Helmut.

Autor: Hans Wurst (hans_wurst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Sensirion hat doch eine gute Applikationsschrift

http://www.sensirion.com/en/pdf/product_informatio...

Autor: MSPProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);
}

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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]

Autor: Sven .. (badst0ck)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Klugscheißer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: GAST (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich werde wohl nochmal von 0 anfangen ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.