www.mikrocontroller.net

Forum: Codesammlung Lib für Sensirion SHT1x Sensor an AVR

Autor: Timo Dittmar (Gast)
Datum: 06.08.2006 17:33
Dateianhang: libsht.c (9,6 KB, 780 Downloads) | formatierter Code

Tach,

in der letzten Zeit wollte ich ein in bischen mit den SHT1x Sensoren
von Sensirion spielen. Leider habe aber keinen sofort lauffähigen Code
ergoogeln können. Deshalb hab ich mal auf Basis der entsprechenden
Sensirion Application Notes einen eigenen Treiber geschrieben.

Vieleicht kann ja noch jemand etwas damit anfangen.
Kommentare sind erwünscht :-)

Wenn ich Zeit dafür finde oder sich die Notwendigkeit ergibt werde ich
den Treiber dahingehend erweitern das man die Daten mit dem CRC WErt
überprüfen kann.

Grüße Timo
Autor: Timo Dittmar (Gast)
Datum: 06.08.2006 17:33
Dateianhang: libsht.h (3,5 KB, 571 Downloads) | formatierter Code

Upps,

hier auch noch die die .h Datei
Autor: Timo Dittmar (Gast)
Datum: 27.08.2006 17:52
Dateianhang: libsht_0v2.zip (6,2 KB, 551 Downloads)

neue Version der Bib, jetzt mit CRC Test und Routinen für Interrupt
gesteuertes Auslesen.

Die Interrupt Steuerung ermöglicht es etwas sinnvolles währeend der
200ms die der Sensor für die Messung benötigt zu verwenden.

Da ich vermutlich bei der endgültigen Version meines Projektes eher ein
Problem mit der Rechenzeit als mit zu großen Programmen haben werde, ist
die Routine für den CRC Test recht Flash intensiv. (>500 Byte)

Wie gesagt, vielleicht kann es ja jemand brauchen.
Autor: Dirk (Gast)
Datum: 14.03.2007 15:22

Moin Timo,

mir hat der Code sehr geholfen, auch wenn ich die Hälfte rauskommentiert
habe um mein Programm in einem Tiny AVR unterzubringen...


Bis dann

Dirk
Autor: hansl (Gast)
Datum: 14.03.2007 15:47

servus timo,

prima, nun muss ich nur noch herausfinden woher ich nen sht11 bekomme :)

den kapazitativen feuchtemesser von philips, vor dem ich mich
nun schon so lange fuerchte, kann ich nun in seinem plastikbeutel
belassen, auf das irgendjemand mit dem richtigem werkzeug sich dem
ding mal annimmt.

hast du vielleicht auch nen tip wie man an die netten module von
sensirion herankommen kann?

danke
 hansl
Autor: Michael S. (mst)
Datum: 15.03.2007 10:52

Farnell hat den im Programm... knapp 20EUR;
Autor: Roland (Gast)
Datum: 15.03.2007 14:16

Den Sensor kann man auch direkt vom Distributor beziehen.
http://www.driesen-kern.de
Driesen und Kern liefert auch an privat.

Gruß
Roland
Autor: Timo Dittmar (Gast)
Datum: 15.03.2007 19:41

@Dirk :
   schön wenn es was gebracht hat. Nachdem ich den Code hier
reingestellt hatte, habe ich im Netzt natürlich noch einige Beispiele
gefunden. Aber so ist das ja immer :-) Was hast du auskommentiert?

@hansl
   Ich hatte meine damals bei www.mikromaus.de bestellt, da waren sie
aber >20Euro.

Leider hatte ich keine Zeit mehr am Code weiterzuarbeiten. Bei dem
Projekt damals hatte ich für die Berechnung der physikalischen Werte
einfach floating points und keine Festkommaarithmetik verwendet. Auf
einem Mega16 der nur nach ein 2x20 LCD ansteuert kamm man sich diese
Verschwendung von Rechenzeit leisten.


Grüße Timo
Autor: dennis (Gast)
Datum: 26.04.2007 13:34

zum testen reicht ja erstmal ein sample:

http://www.sensirion.com/en/02_sensors/03_humidity...

d.
Autor: TurboCity (Gast)
Datum: 10.05.2007 20:32

Also ich bekomme nicht einmal durch den Softreset (error=1).

Meine Sequenz:

  unsigned char error =0;
  unsigned char checksum;
  sht_value humidity;
  sht_value temperature;

  error=sht_softreset();
  if (error)
  { sprintf(buffer, "SHT11 Error (SoftReset) %i\n", error);
    uart_puts(buffer);
  }

        error=sht_measure(&humidity, &checksum, HUMI);
  if (error)
  { sprintf(buffer, "SHT11 Error (HUMI) %i\n", error);
    uart_puts(buffer);
  }
  error=sht_measure(&temperature, &checksum, TEMP);
  if (error)
  { sprintf(buffer, "SHT11 Error (TEMP) %i\n", error);
    uart_puts(buffer);
  }

  sht_raw_to_physical(&humidity, &temperature);

  sprintf(buffer, "Temp=%.2f Humi=%.1f\n",temperature.f, humidity.f);
  uart_puts(buffer);

Ist das die falsche Reihenfolge ?
Ich habe den Code mit einem 4Mhz und einem 7.318Mhz Quarz probiert.

Please help :-)
Autor: Timo Dittmar (Gast)
Datum: 11.05.2007 00:25

Hallo TurboCity,

ich habe leider schon seit einen dreiviertel Jahr nicht mehr mit den SHT
Sensoren gearbeitet (liegt aber alles noch auf dem Schreibtisch :-).

Hast du ein Digitaloszi um dir clock und daten anzusehen? Ist etwas
schwierig da die Frequenz der Daten im Vergleich zu der Wartezeit
zwischen dem Start der Messung und dem Auslesen der Daten hoch ist. Also
Oszi mit ausreichender Speichertiefe oder verzögert triggern.

Ich erinnere mich dass ich damals große Probleme mit dem
pullup-Widerstand hatte. Der interne des AVRs hatte nicht funktioniert.

Falls du noch keinen 100nF Kerko am Sensor hast, solltest du dem Sensor
einen gönnen. (selbst wenn es nichts bringt ist es schon psychologisch
wichtig ;-)

Mit welcher Spannung versorgst du den SHT? Wenn es unter 4,5V sind, ist
Datenrate mit der sht_write_byte die Daten ausgibt zu hoch. (siehe
Datenblatt des SHT, das ist noch so ein undokumentierte Feature meiner
Bibliothek :-) Einfach ein delay_us(1) anstelle der nops einfügen.

Ansonsten modifiziere die Bibliothek so das du dir schon während des
resets  Statusmeldungen ausgibt.

Was pasiert wenn die den Fehler des Softreset einfach ignorierst und
mindestens 20ms wartest bevor du den nächsten Befehl an den SHT sendest?

Mehr Ideen habe ich jetzt auch nicht :-)


Grüße Timo
Autor: TurboCity (Gast)
Datum: 11.05.2007 10:35

Hallo Dittmar,

besten Dank für Deine Kommentare.

Leider habe ich kein Oszi zur Verfügung (stelle aber immer mehr fest,
dass man so etwas unbedingt benötigt.)

Die 100nF sind vorhanden, plus einem 1k Pullup (alternativ habe ich auch
4k7 probiert) auf der Datenleitung.

Spannung sind gemessene 5.0V.

Wenn ich die Fehlermeldung ignoriere und 20ms warte, so bekomme ich
error=2 von der read-Funktion zurück.

Da Du keine Anmerkungen zur Reihenfolge hattest, gehe ich mal davon aus,
dass diese funktionieren sollte :-)


Viele Grüße,
TurboCity

Autor: Timo Dittmar (Gast)
Datum: 13.05.2007 17:55

Hallo TurboCity,

ja, die Reihenfolge der aufgerufenen Funktionen ist in Ordnung.
Allerdings sollte man laut Datenblatt nach dem Reset 11ms warten bevor
man das nächste Kommando losschickt.

Leider habe ich auch keine Idee mehr warum es nicht funktioniert. Die
Fehlermeldung 2 bedeutet, dass der Sensor kein ack nach dem senden des
Befehls, als auch nach der Wartezeit immer noch nicht reagiert hat.

Ich denke ab jetzt kommt man nur noch mit einem Oszi weiter.


Viel Glück noch

Timo
Autor: A. Dubhorn (Firma privat) (toranaga)
Datum: 15.05.2007 14:41

Hi Timo,

die Lib sieht recht praktisch aus, nur wie fummel ich die jetzt um, das
ich zwei SHT nacheinander ansteuern kann. Es müsste nur der Datenpin
irgendwie übergeben werden, nur schiesst das #define da etwas quer.

cu
Andreas
Autor: TurboCity (Gast)
Datum: 15.05.2007 14:45

Kann man irgendwie feststellen (ohne Oszi), ob der SHT11 überhaupt ein
Lebenszeichen von sich gibt ?

Vielleicht ist mein Chip ja kaputt ?
Autor: Timo DIttmar (Gast)
Datum: 16.05.2007 00:57

Hallo

@ A. Dubhorn

also um mehrere SHT Sensoren an verschiedenen Datenpin anzusteuern würde
ich das statische Makro umändern.
So etwas in der Art:
#define SET_SHT_DATA(SHT_DATA_PIN) SHT_DATA_PORT |= ( 1 <<
((SHT_DATA_PIN)))

die #define SHT_DATA_PIN PD6 Anweisung rausschmeißen und die Funktionen
so anpassen das man den Pin übergeben kann  z.B. so:
unsigned char sht_write_statusreg(unsigned char *p_sht_value, unsigned
char pin)

natürlich müssen die anderen Makros die auf den Datenpin zugreifen und
jeder Aufruf der Makros in den Funktionen angepasst werden. sollte aber
möglich sein.
Poste den Code doch mal wenn du fertig bist.

@ Turbocity

Nicht das ich wüste.  Man könnte überprüfen ob der Stromverbrauch
innerhalb der Specs liegt, allerdings ist das nur ein sehr indirekter
Hinweis.

Grüße Timo
Autor: rockclimber (Gast)
Datum: 17.05.2007 19:10

Hallo Timo, hallo TurboCity,

erstmal vielen Dank an Timo für die feine lib!

Ich glaube, ich hatte am Anfang das gleiche Problem wie TurboCity. Der
Sensor gab einfach keinen Muks von sich. Die lib ist ja wunderbar
strukturiet, also hab ich mir erst nicht alle Details angeschaut. Nach
einigem Probieren hab ich dann aber doch genauer hingeschaut und
festgestellt, dass das clock-pin nicht richtig initialisiert wurde.
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;

Und siehe da, es funktionierte! Ganz ohne teuren Oszi ;-)

Viele Grüße
rockclimber

PS: stehe jetzt auch vor der Aufgabe, einen zweiten SHT abzufragen. Die
clock-Leitung können sich beide chips ja teilen. Data ist aber etwas
aufwändiger...
Autor: Karleido (Gast)
Datum: 20.05.2007 20:44

Schau mal hier nach
http://www.wetterstationsforum.de/phpBB/viewtopic.php?t=7903
Hier wird das THERMO- HYGROMETER WS 9400 von Conrad beschrieben.
Im Inneren steckt ein SHT1x.

Gruß
Karl
Autor: Timo Dittmar (Gast)
Datum: 21.05.2007 19:26

Hallo, rockclimber, TurboCity


Danke rockclimber: jetzt sehe ich es auch: der clk-Pin wird in der
Bibliothek nicht initialisiert.
Mir ist das leider nie aufgefallen da ich damals in meinem Testprogramm
am Anfang den ganzen Port als Ausgang gesetzt hatte. (das war auch noch
das LCD dran)
Peinlich, peinlich.



Grüße Timo
Autor: TurboCity (Gast)
Datum: 21.05.2007 20:05

Vielen Dank an Timo und rockclimber. Jetzt funktioniert es einwandfrei.
(verneig)

Da muss man auch erst einmal drauf kommen, dass der Port nicht
initialisiert wird. Ich bedanke mich für die gesparten debug-Sessions
:-)

Und Timo: Super Lib !!
Autor: Severin (Gast)
Datum: 01.06.2007 15:57

Hallo zusammen,

vielen Dank erstmal an den Ersteller der Lib, die ist sehr praktisch.

Allerdings komme ich nun nicht ganz mit dem Format der Variablen klar,
in der z.B. der Wert für die Temperatur abgespeichert ist.

Ich wollte diesen Wert ganz gerne über einen UART ausgeben. Ich bekomme
es es auch auf die Reihe einen 8 Bit in ASCII zu wandeln, nur mit dieser
Variablen (sht_value p_temperature) klappt das nicht. Muss ich die erst
noch auf unsigned char oder so casten, oder hat hier jemand einen
besseren Tip für mich?

MfG Severin
Autor: Timo Dittmar (tdittmar)
Datum: 02.06.2007 14:24

Hallo Severin,

schau mal in die libsht.h, dort kannst du sehen dass sht_value ein union
ist. Er (es?) enthält im gleichen Speicherbereich einen int (
ansprechbar als .i) und einen float Wert (als .f) Das ist ein (ziemlich
unsauberer) Trick um Speicher zu sparen. Die Idee dahinter: die
sht_measure Funktion liefert die Messwerte als Integer (16bit ,Auflösung
12 bit RH, 14 bit Temp) zurück. Dort kann man sie dann als variable.i
abgreifen. variable.f macht zu diesem Zeitpunkt natürlich noch keinen
Sinn. Bei dem Aufruf von sht_raw_to_physical wird aus den Rohdaten der
menschenkompatible Wert berechnet und sht_value variable wird
überschrieben. Jetzt kann man mit variable.f auf den float Wert
zugreifen. Durch die Verwendung des union wird nicht nur etwas Speicher
gespart, es ist auch effizienter, da bei dem Aufruf von
sht_raw_to_physical nicht so viel Speicher über den Stack bewegt wird.
(ob das in Anbetracht der Verwendung von float-Werten Sinn macht sei
dahingestellt)

Wenn du das alles richtig verstehen willst, schau ruhig mal in den
Quellcode und such dir ein (altmodisches?) C-Buch deines Vertrauens in
dem noch erklärt wird wie Computer auf Speicher zugreifen. Auch hier im
AVR-GCC Tutorial sind viele Anregungen enthalten :-)


Wie du siehst ist es mit einem einfachen cast nach char nicht getan :-)
Ich denke am einfachsten ist es einfach die zweimal zwei Byte der
Rohdaten über UART zu übertragen und die Umrechnung in Kalibrierte Werte
am Computer vorzunehmen. (siehe Lib oder die Sensirion Datenblätter) Der
Zugriff auf die einzelnen Bytes des Ints gehen z.B. auch wieder über ein
union (int i, b1,b2 char)

Grüße Timo
Autor: Roland (Gast)
Datum: 09.01.2008 09:03

kann mir jemand sagen mit welcher frequenz der atmega betrieben werden
muss? bekomme den code nicht zum laufen.

lg, roland
Autor: Dieter Bohlen (Gast)
Datum: 16.02.2008 12:53

Moin, habe auch ein Problem mit der Lib: Wo bitte kann ich die fertigen
Werte abgreifen? Finde keine Variablen wo das Ergebnis drinsteht? In der
Union auch nicht?
Autor: Dieter Bohlen (Gast)
Datum: 16.02.2008 15:05

So, hab jetzt mal den Code von oben + der sht11-lib genommen (erweitert
um den besagten reset-fehlerfix). geht aber immer noch nicht, mein LCD
zeigt zufällige 5stellige werte an, positiv und negativ.

messen() wird dabei jede sekunde in einer interrupt-routine aufgerufen.



void messen(void) {

unsigned char error =0;
unsigned char checksum;
  sht_value humidity;
  sht_value temperature;

  error=sht_softreset();
  if (error) {
  ks0108GotoXY(60,90);
  ks0108Puts("ERROR Softreset");
  }
        error=sht_measure(&humidity, &checksum, HUMI);
  if (error)
  { ks0108GotoXY(60,90);
  ks0108Puts("ERROR Hum");
  }
  error=sht_measure(&temperature, &checksum, TEMP);
  if (error)
  { ks0108GotoXY(60,90);
  ks0108Puts("ERROR Temp");
  }

  sht_raw_to_physical(&humidity, &temperature);

  unsigned char tstr[10];
  unsigned char hstr[10];
  
  itoa(temperature.i, tstr , 10);
  itoa(humidity.i, hstr , 10);
  ks0108ClearScreen();
  ks0108GotoXY(16,32-8);
  ks0108Puts(tstr);
  ks0108GotoXY(75,32-8);
  ks0108Puts(hstr);
  }
Autor: Dieter Bohlen (Gast)
Datum: 16.02.2008 15:15

Aber irgendwas scheint zu funktionieren, wenn ich die Sensordatenkabel
abziehe bekomme ich den Softreset und Feuchtigkeitsleseerror.
Autor: Timo Dittmar (Gast)
Datum: 16.02.2008 18:55

Hallo Dieter,

also das Ergebnis der Wandlung sollte schon in dem Union drinstehen. Das
ist leider alles ziemlich schlecht dokumentiert in der lib.

Direkt nach dem Messen kann man in temperature.i und humidity.i die
Rohwerte als integer abgreifen. Die Temperatur Rohdaten sind linear mit
der "menschenkompatiblen" Temperatur in °C verknüpft. Die
(unkompensierte) relative Luftfeuchte wird über ein polynom 2 Ordnung
aus den den Feuchtigkeitsrohwerten berechnet. Zusätzlich wird noch eine
Temperaturkompensation des Feuchtigkeitsmesswerts vorgenommen.

Das geschieht alles in der Funktion sht_raw_to_physical(&humidity,
&temperature).

Dabei werden die Rohdaten in humidity und temperature überschrieben.
Nach dem Aufruf von sht_raw_to_physical kann man über temperature.f und
humidity.f die  umgerechneten, kompensierten Messwerte als float
abrufen.

Die wilden positiven und negativen Zahlen kommen daher das er versucht
die float werte als int auszulesen.

Das Design dieser Funktion stammt nicht von mir sondern ist direkt aus
den Application Notes von Sensirion entnommen. Ich hatte es damals
verwendet da ich schnell einen funktionierenden Code haben wollte und
ich die Idee des Ram sparens nett fand.  Vermutlich würde ich es heute
anders machen, insbesondere die Verwendung von float ist richtig
Ressourcen Verschwendung.
Eigentlich wollte ich an dem Umweltdatenlogger Projekt mal weiter
machen, was vermutlich eine Version 3 der lib hervorgebracht hätte,
allerdings habe ich jetzt erstmal einen ct-bot zum spielen :-)

Grüße Timo
Autor: Lars (Gast)
Datum: 06.05.2008 17:36

Hallo,
Ich habe volrgendes problem ich möchte den SHT mit einem pic12F 8 bit
ansteuern, das funktionirt auch.
Leider habe ich probleme mit dem umrechen der Messwerte in Assembler.
Kann mir da jemand weiterhelfen. Ich weis das ist das Falsche Forum
dafür aber ich hoff es kennt sich vileicht doch jemand damit aus.
vielen dank
Lars
Autor: Pete K. (pete77)
Datum: 06.05.2008 18:01

Hallo Timo,

könntest Du eine bug-bereinigte Version bereitstellen ?

Danke,
Pete

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel





Hinweis: der Originalbeitrag ist mehr als 6 Monate alt.

webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net