Hallo zusammen,
versuche mich nun schon seit einer Weile daran, einen SHT11
(http://www.driesen-kern.de/downloads/dbsht1x7xdeutschdk0704.pdf) an
einem MEGA16 ans laufen zu bringen. Gemäß Datenblatt müßte der Sensor
das nach dem Erhalt eines Befehls die gewünschte Messung durchführen und
DATA auf low ziehen wenn er diese beendet hat. Tut er aber nicht...
Vermute das der Sensor nen Defekt hat, denn die Übertragung ist ja
eigentlich recht simpel.
Habe den Sensor wie in Beitrag "Erfahrungen mit SHT11 Sensor?"
beschrieben mal durchgemessen. Ist demnach scheinbar in Ordnung.
Hat jemand einen funktionierenden C-Code, den er vieleicht selbst im
Einsatz hat? Möglichst in ner Minimalausführung bei der ich nichts oder
höchstens die beiden I/O-Pins umschreiben muß, um den Sensor mal testen
zu können? Einfach um Klarheit zu haben ob der Sensor nun defekt ist
oder meine Programmversuche Fehler haben. Die Codes die ich hier bisher
gefunden habe, führten nicht zum Erfolg -> viel viel umschreiben.
Im Anhang ist ein Auszug aus meinem Aufbau. R2 ist ein Pull-Up, R1 ist
zum Schutz von Sensor und uC vor ungeschickter Programmierung, MEGA16
mit 4MHz.
Vielen Dank im voraus...
Timo
Im MegaEIB Projekt sind Sourcen von Patrick Bernhart für die Ansteuerung
eines SHT11 angegeben.
Im entsprechenden Schaltplan sind Pullups an beiden Leitungen (DATA,
SCK) vorgesehen, statt nur an einer Leitung (DATA). Der Wert der Pullups
ist 2,7K statt 10K. Der 10K Serienwiderstand fehlt. Es wird PORTF0 und
PORTF1 an einem Atmega128 benutzt.
http://www.dehof.de/eib/DE/http://www.dehof.de/eib/DE/atmel.htm
Poste doch mal deinen Code, dann kann man Fehler ausschließen, ansonsten
ist es schwer Dir zu helfen. Ansonsten kann ich nur sagen die Sensirion
Serie ist sehr robust -> hatte bis jetzt noch keine Probleme!
Erstmal besten Dank für die zügigen Antworten.
@ Hans-josef Mennen & Msp 430_crew
Den Beispiel-Code für nen 80C51 von Sensirion kenne ich. Die libsht_0v2
von Timo Dittmar (Beitrag "Lib für Sensirion SHT1x Sensor an AVR") kenne
ich auch (bruht ebenfalls auf dem Sensirion-Code) und verwende diese.
In der libsht.h habe ich
1
/* SHT SCK and DATA Port and Pin definitions */
2
#define SHT_DATA_PORT PORTD
3
#define SHT_SCK_PORT PORTD
4
#define SHT_DATA_DDR DDRD
5
#define SHT_SCK_DDR DDRD
6
#define SHT_DATA_PORT_PIN PIND
7
#define SHT_DATA_PIN PD6
8
#define SHT_SCK_PIN PD7
zu
1
/* SHT SCK and DATA Port and Pin definitions */
2
#define SHT_DATA_PORT PORTA
3
#define SHT_SCK_PORT PORTA
4
#define SHT_DATA_DDR DDRA
5
#define SHT_SCK_DDR DDRA
6
#define SHT_DATA_PORT_PIN PINA
7
#define SHT_DATA_PIN PA2
8
#define SHT_SCK_PIN PA1
geändert.
Die main-Funktion (im Anhang) stammt aus dem Sensirion-Code und wurde
entsprechend angepasst.
@ Stefan B.
Die exakte Größe der Pull-Ups sollte doch eigentlich relativ unkritisch
sein und dienen doch lediglich dazu einem uC-Pin der als Eingang
definiert ist, zu jedem Zeitpunkt einen absoluten Wert zu liefern.
Wozu soll ein Pull-Up an SCK gut sein? Ist doch permanent Ausgang am uC.
Seite 2 von
http://www.driesen-kern.de/downloads/dbsht1x7xdeutschdk0704.pdf sieht
auch nur einen Pull-Up von 10k an DATA vor.
Ich bin von der grundsätzlichen TWI Beschreibung im Atmega16 Datenblatt
ausgegangen (Datenblatt Figure 76 auf Seite 172). Dort sind zwei Pullups
angegeben.
Auch wenn man den TWI per Software nachbildet, empfiehlt Atmel zwei
Pullups (AVR 300: Software TWI Master Interface, Figure 4 auf Seite 3)
Der Wert der Pullups ist genaugenommen von der beabsichtigten
Ubertragungsrate, der Versorgungsspannung und der Leitungskapazität der
Busleitungen abhängig (Datenblatt Table 120 auf Seite 294).
Über 10K oder weniger (Atmel schreibt typ. 4,7K bei Vcc=5V) kann man
reden. 10K ist für die Kommunikation mit dieser Art Sensor anscheinend
ein gängiger Wert.
Add:
> Wozu soll ein Pull-Up an SCK gut sein? Ist doch permanent Ausgang am uC.
Soweit ich TWI verstehe (und das ist nicht viel), hat der Sensor die
Möglichkeit SCK (bzw. SCL in Atmel Nomenklatur) auf low zu ziehen, wenn
er mehr Zeit braucht. Damit wäre SCK am µC nicht nur als Ausgang zu
betrachten... in der oben erwähnten AVR300 wird dies durch die Routine
TWI_get_ack berücksichtigt.
Moin,
bei mir funktioniert der SHT mit der Lib von Timo Dittmar einwandfrei.
Meinst Du das es eine gute Idee ist die Datenleitung mit 10 k zu ziehen
und einen 10 k Serienwiderstand einzubauen?
Ich habe nur einen 4,7 k Pullup in der Datenleitung sonst nichts...
@ Stefan B.
Verstehe, so macht das natürlich Sinn. Da der Sensor ja allerding nur
mit einem "ähnlichen" Protokoll arbeitet, halte ich einen den zweiten
Pull-Up nicht für notwendig (siehe auch Dirks Beitrag). Probiere es
gegebenfalls dennoch mal mit nem zweiten Pull-Up und tausche gegen 4,7k.
@ Dirk
Der 10k Serienwiderstand dient eigentlich nur zum Schutz von Sensor und
uC vor ungeschickter Programierung (uC-Pin Ausgang 0V wärend DATA 5V
oder umgekehrt).
Tausche meinen Pull-Up dann auch mal gegen 4,7k und entferne den 10k
Serienwiderstand. Kannst Du Deine main-Funktion (oder Auszug) mit der Du
die Lib von Timo Dittmar nutzt posten?
Hallo Dirk,
hab nun inzwischen etwas mit Deinem Code gearbeitet. Bin aber leider
noch immer nicht erfolgreicher.
Sehe ich das richtig, das ausschließlich mit
1
error=sht_measure(&daten,&error,0);
2
temperatur=daten;
und
1
error=sht_measure(&daten,&error,1);
2
feuchte=daten;
der Sensor auszulesen ist und die Werte anschließend in den Variablen
"temperatur" und "feuchte" zur Verfügung stehen?
Jupp, den Rest macht ja die Lib. Die habe ich übrigens nur für den Tiny
so stark auskommentiert, weil ich das Ganze sonst nicht in 2kB
untergebracht hätte...
Das dachte ich mir schon... ;)
Erhalte vom Compiler noch folgende Warnung zu Zeile 20 und 26:
../main.c:20: warning: passing argument 1 of 'sht_measure' from
incompatible pointer type
Muß mit dem Datentyp von "daten" zusammenhängen, aber brauch vieleicht
ja garnicht beachtet zu werden. Der Inhalt der Variablen ist immer 0.
Hier ist mal meine main:
1
#include<avr/io.h>
2
#include"lcd.h"
3
#include"float2lcd.h"
4
#include"libsht.h"
5
6
7
intmain(void){
8
9
lcd_init();
10
11
lcd_data('O');
12
lcd_data('K');
13
lcd_data(' ');
14
15
unsignedintfeuchte,temperatur,daten;
16
unsignedcharerror;
17
18
while(1){
19
20
error=sht_measure(&daten,&error,0);//Zeile 20
21
temperatur=daten;
22
23
float_to_lcd(temperatur);
24
lcd_data(' ');
25
26
error=sht_measure(&daten,&error,1);//Zeile 26
27
feuchte=daten;
28
29
float_to_lcd(feuchte);
30
lcd_data(' ');
31
32
}
33
34
return0;
35
36
}
Noch ne Idee? Sollte der Sensor vieleicht doch defekt sein?
Deine Schaltung überprüfen.
Wie gesagt, bei mir funktioniert das einwandfrei. Die Compilerwarnung
habe ich auch...
Hast Du die Beschaltung jetzt geändert?
Wie sieht denn Dein Code jetzt aus?
Beschaltung habe ich geändert... 10k Serienwiderstand raus... Pull-Up
auf 4,7k...
Die main-Funktion habe ich ja eben gepostet, libsht.c und libsht.h aus
Deinem Projekt übernommen und angepasst (PA1 für SCK, PA2 für DATA,
etc). Also so:
1
/* SHT SCK and DATA Port and Pin definitions */
2
#define SHT_DATA_PORT PORTA
3
#define SHT_SCK_PORT PORTA
4
#define SHT_DATA_DDR DDRA
5
#define SHT_SCK_DDR DDRA
6
#define SHT_DATA_PORT_PIN PINA // ! the PINx register of the DATA Port !
So... Habe ein Programm
(http://www-user.tu-chemnitz.de/~heha/viewzip.cgi/hs_freeware/sht11.zip/)
gefunden, mit dem der SHT11 am LPT-Port ausgewertet werden kann...
Sensor funktioniert...
Ist Port A am MEGA16 vieleicht aus irgendeinem anderen Grund nicht ohne
weiteres voll verwendbar? Vieleicht änhlich wie Port C mit JTAG?
Hallo Timo,
hast du dem Thread zu meiner lib ganz gelesen und den "Patch" von
rockclimber eingebaut? In der lib wird habe ich leider vergessen den
SCK Pin auch als Ausgang zu schalten.
Also entweder direkt bei deinen Ini Routinen den Pin als Ausgang setzen
oder:
[..]
Also folgende Zeile in libsht.h ergänzt:
#define MAKE_SHT_SCK_PIN_OUTPUT SHT_SCK_DDR |= ( 1 << SHT_SCK_PIN)
und in libsht.c in der Funktion sht_softreset(void) folgende Zeile vorn
angefügt:
MAKE_SHT_SCK_PIN_OUTPUT;
[... Zitat rockclimber]
Grüße
von dem anderen Timo :-)
Hallo Timo,
habe mir mal dein Programm angesehen (allerdings nur den sht teil :-)
und noch ein paar Fehler gefunden:
Du übergibst der sht_measure() Funktion einen uint daten. sht_measure
verlangt aber einen Zeiger des Types sht_value.
Dieser Typ ist in der sht.h definiert und ist ein union aus einem float
und einem uint.
Danach übergibst du Daten an Temperatur bzw Feuchte und gibst sie
vermutlich mit float_to_lcd() aus. Da diese Funktion nicht in der
klimalogger.zip Datei dabei ist kann ich nur spekulieren, dass diese
Funktion einen float erwartet und diesen dann auf dem LCD ausgibst. Das
kann nicht funktionieren, da die sht_measure() Funktion in dem union nur
die Rohdaten als uint in p_sht_value.i zurückgibt.
Um die menschen lesbaren Werte zu erhalten muss die Funktion
sht_raw_to_physical(sht_value *p_humidity ,sht_value *p_temperature)
aufgerufen werden. Diese Funktion berechnett aus den rohdaten in
*p_humidity und *p_temperature die physikalischen Werte. Diese stehen
danach im float Teil (sht_value.f) der unions bereit. Die rohdaten
werden dabei überschrieben.
Sorry für die vielen Fragen die sich durch den fehlenden Beispielcode
und das gewöhnungsbedürftige Design der Bibliothek ergeben.
Grüße Timo
Zusammenfassung:
sht_measure(sht_value *p_sht_value, unsigned char *p_checksum, unsigned
char mode)
liefert in p_sht_value.i die Rohdaten.
sht_raw_to_physical(sht_value *p_humidity ,sht_value *p_temperature)
berechnet aus Temperatur und Feuchte Rohdaten die echte Temperatur und
die relative Luftfeuchte. Diese stehen dann in p_humidity.f bzw.
p_temperature.f als float Wert bereit.
Hallo auch Timo, :)
den Patch von rockclimber hatte ich gelesen und auch eingebaut.
Die Funktion float_to_lcd() stammt von mir und gibt wie Du schon sehr
richtig spekuliert hast, ein float auf einem LCD aus. Verkraftet auf
Grund der C-Konventionen aber auch ein Integer.
Aber vielen Dank für die Erläuterung der Datentypen. Werde das gleich
mal angehen und erstatte dann nochmal Meldung. ;)
Gruß
Timo