Forum: Mikrocontroller und Digitale Elektronik Hygrosens HYT221 an Atmega8 macht nichts


von Jens H. (deltaspace)


Lesenswert?

Hi Leute,

ich versuche hier verzweifelt von einem HYT221 von Hygrosens Daten zu 
bekommen. Wenn ich 4 Bytes auslese bekomme ich immer nur 4x 41 zurück, 
auch wenn ich die Temperatur verändere.

Hat von euch jemand Erfahrung mit diesem Sensor?

Ich Programmiere in C.

Hier der Code
1
  // Beginn der Messung
2
  twi_start();
3
  twi_sende_adresse(HYT221 + TWI_WRITE);
4
  loop_until_bit_is_set(TWCR, TWINT);
5
  twi_stop();
6
7
  // Auslesen der Messwerte
8
  twi_start();
9
  twi_sende_adresse(HYT221 + TWI_READ);
10
  loop_until_bit_is_set(TWCR, TWINT);
11
  byte[0] = TWDR;
12
  TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
13
  byte[1] = TWDR;
14
  TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
15
  byte[2] = TWDR;
16
  TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
17
  byte[3] = TWDR;
18
  twi_stop();

Danke schonmal für eure Hilfe

MfG

Jens

von Michael S. (Gast)


Lesenswert?

Hallo Jens,

leider habe auch ich Probleme mit dem Modul.
Als erstes musste ich feststellen, das das Modul nicht auf die Adresse 
0x28 sondern auf 0x50 (dez. 80) hört.

Unter der TWI-Adresse 0x51 kann man dann 4 Byte abholen - die verändern 
auch ihre Werte, wenn man den Sensor anhaucht.
Allerdings ergibt die Umrechnung keinerlei Messwerte, die mit den 
tatsächlich vorhandenen Temperatur- und Feuchtigkeitswerten
auch nur ansatzweise übereinstimmt.

Liest man mehrfach die Werte aus, dann wird immer dasselbe Ergebnis 
zurückgeliefert.
Erst wenn man ein TWI-Write ohne Parameter sendet, werden offensichtlich 
neu Werte in den Ausgangspuffer des Moduls geschrieben.

Hilfreich wäre eine ausführliche Dokumentation.
Aber die Angaben, die ich gefunden habe, sind sehr bescheiden.

Gestern (19.04.) habe ich eine mail an hygrosens geschickt.

Bislang keinerlei Reaktion. Nicht mal eine Eingangsbestätigung.


mfg

Michael S.

von Lutz (Gast)


Lesenswert?

Hallo,

meine beiden Module aus 
Beitrag "Erfahrungen Feuchtesensor HYT-371?" sind gestern 
gekommen und ich werde wohl erst am Wochenende etwas damit spielen 
können.
Die Dokumentation auf der Homepage ist in der Tat verbesserungswürdig, 
keine Frage. Aber eine Antwort auf eine mail nach einem Tag zu erwarten 
ist natürlich auch sehr optimistisch. Ich hatte nach wenigen Tagen eine 
bekommen (und da hat sich auch ein Mensch inhaltlich mit beschäftigt, 
also keine Bot-Antwort).

Michael S. schrieb:
> Liest man mehrfach die Werte aus, dann wird immer dasselbe Ergebnis
> zurückgeliefert.
> Erst wenn man ein TWI-Write ohne Parameter sendet, werden offensichtlich
> neu Werte in den Ausgangspuffer des Moduls geschrieben.

Nach meinen Infos 
(http://www.hygrosens.com/fileadmin/user_upload/Produkte/Sensorelemente/Digitale_Feuchtesensoren/HYT_I2C_Protokollbeschreibung_D.pdf) 
ist das wohl so richtig. Das Kommando DF liefert immer den zuletzt 
gemessenen Wert. Eine neue Messung wird mit dem Kommando MR ausgelöst.

Leider habe ich auf der Homepage auch noch keine gescheite Beschreibung 
der beiden Statusbits gefunden, wie man (wirklich) aus dem Meßwert die 
physikalische Größe errechnet, wie lange eine Messung eigentlich dauert, 
wie man dem Teil eine andere Adresse zuweist etc.

Michael S. schrieb:
> Als erstes musste ich feststellen, das das Modul nicht auf die Adresse
> 0x28 sondern auf 0x50 (dez. 80) hört.

Das ist natürlich schon ziemlich krass. Wie findet man denn sowas raus? 
Durch Experimentieren doch wohl sicher nicht.

Insgesamt sollte unbedingt was an der Doku auf der Homepage gemacht 
werden. Man kann sich aus diversen PDF's zwar vieles zusammenreimen, 
aber das ist ja eigentlich nicht die Aufgabe des Nutzers. Er soll das 
Datenblatt nehmen und mit den darin enthaltenen Informationen loslegen 
können.

von Michael S. (Gast)


Lesenswert?

Hallo Lutz,

das Datenblatt kannte ich noch nicht.

Hier ist die Berechnung der relativen Feuchtigkeit und der Temperatur 
völlig anders beschrieben als in den Unterlagen, die ich gefunden und 
genutzt habe.

Die positive Nachricht:
Mit diesen Formeln erhalte ich plausible Ergebnisse:

T[°C] = 165 / 2^14 * Messwert -40
liefert bei mir 194,62.. (bei ca. 19° Raumtemperatur)

rf[%] = 100 / 2^14 * Messwert
liefert bei mir 0,58.. (bei gemessener Feuchte von ca. 58%)

So weit so gut.

Wie man mit den Kommandos "Data Fetch" und "Measuring Request" umgeht, 
das muss ich mal testen.
Soll man da ein write mit den Parametern "DF" bzw. "MF" senden?
Oder reicht ein parameterloses write mit nachfolgendem read (so 
funktionierte es bei mir offensichtlich).

Die Dokumentation kann man so oder so interpretieren.

Ich vermute, dass sie mit extrem heißer Nadel gehäkelt wurde.
Man sehe sich nur auf der Seite 3 die Beispiele zur Temperatur- und zur 
Feuchtigkeitsberechnung an.

Sind beide identisch !

Naja - manchmal muss man eben zufrieden sein, wenn's einfach nur 
funktioniert.
Und man sich eine Retour sparen kann.

mfg

Michael S.

von Tip (Gast)


Lesenswert?


von Michael S. (Gast)


Lesenswert?

Hallo Tip,

Der erste Link liefert leider nur den "Beipackzettel".
Und die dort angegebene TWI-Adresse stimmt (zumindest bei meinen beiden 
Modulen) nicht mit der realen Adresse überein.

Der zweite Link ist hilfreicher (wurde auch von Lutz schon geliefert).
Diese Dokument habe ich aber auf der website unter dem Produkt HYT-221 
nicht gefunden.

Und auch hier ist die Rede von der TWI-Adress 0x28.

Die Beschreibung von "Data Fetch" und "Measurement Request" als 
Kommandos irritiert mich.

Ganz offensichtlich wird mit einem einfachen TWI-Write eine Messung 
ausgelöst, mit einem TWI-Read werden die Daten abgeholt.

An den beiden oberen Bits des ersten Bytes kann man erkennen,
- dass der "Baustein im Command Mode" ist
  (was bitteschön bedeutet das ??)
- dass der Messwert noch nicht aktualisiert wurde.


mfg

Michael S,

von Jens H. (deltaspace)


Lesenswert?

Hallo Leute,

danke schon mal für die Hilfe. Das mit der anderen Adresse werde ich mal 
versuchen. Wie hast du herausgefunden, welche Adresse das Modul wirklich 
hat?

Die Datenblätter kannte ich schon. Wenn die Adresse aber nicht stimmt, 
dann ist mir auch klar, warum ich keine Werte zurück gelesen bekam.

Ich komme leider erst morgen dazu, die Tests mit der anderen Adresse zu 
machen. Ich werd ich auf dem laufenden halten, was passiert.

Die Funktion des Moduls hab ich dem Datenblatt so entnommen, das man 
zuerst einen MR senden muss, dann macht das Teil seinen Messzyklus und 
schreibt die Werte in den Speicher. Sobald der Messzyklus abgeschlossen 
ist, kann man die neuen Werte mit DF abholen.
Irgendwo hab ich schon was gelesen, das ein kompletter Zyklus ca. 12-13s 
dauern soll. Leider finde ich die Stelle in irgendeinem PDF nicht mehr.

Danke nochmals.

MfG
Jens

von Matthias (Gast)


Lesenswert?

Michael S. schrieb:
> Und die dort angegebene TWI-Adresse stimmt (zumindest
> bei meinen beiden Modulen) nicht mit der realen Adresse überein.
> ...
> Und auch hier ist die Rede von der TWI-Adress 0x28.

In der Protokollbescheibung steht: "Die I2C 'Slave' Adresse ist default 
auf 0x28 programmiert und kann im gesamten Adressbereich
von (0x00 to 0x7F) eingestellt werden"

Wenn deine Adresse nicht stimmt, hast du die möglicherweise schon 
verdreht?

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

@ Jens und Matthias,

es kann durchaus sein, dass ich keine "jungfräulichen" Module erhalten 
habe, sondern (vergeigte) Retouren anderer.
Oder kundenspezifisch programmierte Restposten.

Ähnliches ist mir mit meinen ersten XBee-Modulen ergangen:
Da die Teile und ihre Funktion für mich noch völlig unbekannt waren, 
habe ich stundenlang nach (eigenen) Fehlern gesucht.
Am Ende stellte sich heraus, dass die default-Einstellungen 
(Schnittstellenparameter) verändert waren.

Bei den HYT-Modulen habe ich die Adresse wohl nicht zufällig selbst 
geändert, denn sie ist auf beiden Modulen identisch.

Abgesehen davon würde ich ja gerne wissen, wie ich Adressen ändern kann!
Und was es mit dem "Command Modus" auf sich hat.

Aber egal - die Dinger funktionieren erst einmal.

Ich hänge mal mein Testprogramm an, vielleicht hilft es euch weiter.
(Achtung: wenn im Programm von HYT-224 die Rede ist, dann meine ich 
eigentlich HYT-221, muss ich noch ändern).

Viel Spaß beim Messen.

Michael S.

von cappelone (Gast)


Lesenswert?

Nur mal so,
ja das Datenblatt ist gewöhnungsbedürftig.
Aber 0x28 * 2 +0 = 0x50 und 0x28*2+1 = 0x51 also alles richtig
bit 0 heisst schreiben/lesen.

Wie man die Adresse 0x28 aendert wüsst ich auch gern.

von Lutz (Gast)


Lesenswert?

Michael S. schrieb:
> Unter der TWI-Adresse 0x51 kann man dann 4 Byte abholen - die verändern
> auch ihre Werte, wenn man den Sensor anhaucht.
Ja klar, 0x51 bedeutet ja auch, daß das READ bit zusätzlich zur Adresse 
0x50 mit "1" gesetzt ist.

Michael S. schrieb:
> Abgesehen davon würde ich ja gerne wissen, wie ich Adressen ändern kann!
> Und was es mit dem "Command Modus" auf sich hat.
Versuch mal, innerhalb von max. 3 ms nach Herstellen der 
Spannungsversorgung (also am besten über einen Portpin versorgen, sonst 
ja gar nicht machbar) 0xA0 an den Sensor zu schicken. Der Sensor 
könnte dann im Programmiermode sein. Als nächstes 0x56 und 0x5F senden 
(soll wahrscheinlich Schreiben ins EEPROM bedeuten). Jetzt noch 0x00 und 
0x28 senden, um die 0x28 reinzuschreiben (scheint ein 16 bit EEPROM zu 
sein). Dann noch 0x80 zum Verlassen des Programmiermodes.
Das ist aber stochern im Nebel inkl. Vermutungen und Zusammensuchen aus 
diversen Internetquellen. Vielleicht solltest Du lieber die Adresse 
lassen, wie sie ist; jetzt geht es ja wenigstens.
Summe, was innerhalb 3 ms nach Power on gesendet werden muß:
0xA0 0x56 0x5F 0x00 0x28 0x80

von Michael S. (Gast)


Lesenswert?

@ capellone

die von dir beschriebenen Adressvergabe ist vermutlich C-Control-Logik.

Wenn ich "normale" I2C-Datenblätter mir ansehe, dann sind die 
geradzahligen Adressen (0 bis 254) jeweils die Write-Adressen.
Und bei gesetztem Bit.0 (Write-Adresse + 1) wird ein Read ausgeführt.

0x28 ist für mich dezimal 40 als Write-Adresse,
die zugehörige Read-Adresse dezimal 41.

Aber immerhin, deine These wäre eine Erklärung für das Durcheinander.

mfg

Michael S.

von Gerald *. (pyromane)


Lesenswert?

Ablauf soweit ich verstanden habe:

Senden des MR (Measurement Requests)
Byte in a Register schreiben

Lesen des DF (Data Fetch)
Byte in w Register lesen  (Feuchtigkeit H Byte)
Byte in x Register lesen  (Feuchtigkeit L Byte)
Byte in y Register lesen  (Temperatur H Byte)
Byte in z Register lesen  (Temperatur L Byte)

Jedoch in welches Register muss ich schreiben und in welchen Registern 
kann ich die Werte auslesen?

von Michael S. (Gast)


Lesenswert?

@ Gerald,

gar kein spezielles Register des Moduls !.

Ist alles nur heiße Luft mit "MR" und "DF".

Sprich das Modul mit seiner TWI-Write-Adresse (0x50 in der üblichen 
TWI-Terminologie) an, dann liest es die Feuchtigkeits/Temperaturwerte,

warte etwas bis die Konversion beendet ist (nach meiner Erfahrung 
reichen 100ms aus),

und lies dann mit einem TWI-Read (0x51) vier Byte aus.

Das sind dann die Daten, die weiter interpretiert werden müssen.

mfg

Michael S.

von Gerald *. (pyromane)


Lesenswert?

Vielen Dank für die Antwort.

Den HYT-271 kann ich ansprechen, jedoch immer folgende Antwort:

(Zimmertemperatur)
0x0   >Byte schreiben
0x15  <Byte lesen
0x55  <Byte lesen
0x55  <Byte lesen
0x55  <Byte lesen

(Kühlschrank)
0xE
0x4E
0x4E
0x4E


Hast du eigentlich schon eine Antwort auf die Email vom 19.04.11 
erhalten?

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

@ Gerald

ja, ich habe eine Antwort erhalten.
Die lautete:

"es tut mir leid wenn der Support nicht 100% funktioniert, aber wir sind
hier am "oberen Anschlag".

Das Datenblatt wird zur Zeit überarbeitet, siehe Anlage.

Anbei das Datenblatt des eingesetzten ASIC und einige Codebeispiele. Ich
hoffe das hilft weiter."

Die Codebeispiele hänge ich an. Geholfen hats mir nicht.

Leider habe ich kein Datenblatt für den HYT-221 erhalten.
Ich habe den Eindruck, dass jedes Modul eine andere Interpretation der 
Daten erwartet.

Dein konkretes Problem würde ich wie folgt angehen:

Zuerst sicherstellen, ob die TWI-Kommunikation erfolgreich war.
D.h. prüfen, ob die Gegenstelle nach dem Senden von 0x50 auch mit ACK 
bestätigt.
Wenn nicht, dann passt z.B. die gewählte Adresse nicht.
Wenn ja, dann die vier Byte lesen.

Aber wenn dann im erste zurückgelieferten Byte Bit 7 oder 6 gesetzt sind 
(z.B. bei 0xE0), dann liegt ein Fehler vor !
Möglicherweise wurde nach dem Senden der Write-Adresse nicht lange genug 
gewartet, und das Modul wandelt noch.

Nun kommt das nächste Problem, nämlich wie die gelesenen Daten in 
sinnvolle Messwerte umsetzen.

Und da bin ich selbst ratlos.
Dazu folgt ein neuer Beitrag.

Michael S.

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo allerseits,

hat irgendjemand von Euch inzwischen plausible Messergebnisse mit dem 
Module HYT-221 erhalten ?

Anlass der Frage ist:

Eigentlich hatte ich angenommen, die Kommunikation mit dem Modul und die 
Umrechnung der gelieferten Daten zu verstehen
(dank der Beschreibung in "HYT_I2C_Protokollbeschreibung_D.pdf")
Messungen bei Raumtepmeratur von ca. 20° lieferten die Werte im Rahmen 
der Erwartung bzw. der Anzeige anderer Messinstrumente.

Dann habe ich einen Log im Aussenbereich durchgeführt.
Im Minutenabstand wurden die Messwerte des HYT-221 und eines Dallas 
DS18B20 (zum Temperaturvergleich) aufgezeichnet.

Das Ergebnis war umwerfend:
Bei realer Luftfeuchte von 70% (nach Regenschauer) liefert der Sensor 
93% und die Temperaturwerte sind viel zu hoch.

Darauf habe ich die Versuchsanordnung geändert:
- zwei HYT-221 und drei Dallas DS18B20 sind dicht beeinander angeordnet 
und werden über Nacht im Minutentakt ausgelesen.
Zusätzlich werden einige Vergleichsmessungen von relativer Feuchte und 
Temperatur mit einem digitalen Handmessgerät ausgeführt.

Die Logdatei sowie die manuell gemessenen Werte (und meinen Programmcode 
zur Umrechnung der vom Sensor gelieferten Werte in relative 
Feuchte/Temperatur habe ich beigefügt).

Die Zusammenfassung:
Um die 20° herum liefert der Sensor nachvollziehbare Werte,
aber bei 10° Aussentemperatur werden ca. 16° gemessen !.
Und auch die Werte der relativen Feuchte liegen weit jenseits der 
Erwartung.

Stimmt die Formel der Umrechnung nicht ?
Ist der Sensor nicht kalibriert ?

Wer kann einen Tip geben ?

mfg

Michael S.

von Lutz (Gast)


Lesenswert?

Der Code sieht (für mich) etwas gewöhnungsbedürftig aus.
Faktor 1000 für eine Nachkommastelle? Ach so, hast die 100/... da mit 
reingerechnet, macht es aber wirklich nicht übersichtlicher. Am besten 
die rohen Werte komplett_ und an _einer Stelle verarbeiten, ist viel 
übersichtlicher. Und nach der Feuchte rechnest Du einfach so mit der 
Variablen "t" weiter, ohne sie vorher auf Null zu setzen und damit die 
vorherigen Werte zu löschen. Auch nicht schön.

Generell solltest Du auch das array für die Meßwerte in jedem 
Schleifendurchlauf neu mit einem aussagekräftigen Wert initialisieren, 
z.B. mit 0xAF. Besonders dann, wenn man noch am Fehler suchen ist. 
Weiterhin dann erstmal nur die HEX-Werte anschauen und auf Plausibilität 
prüfen (steht nicht mehr 0xAF drin.), umrechnen kannst Du dann später, 
wenn es bis hier alles in Ordnung ist. So dürfen sich das erste und 
dritte byte nicht ändern, da wohl kaum so starke Temperatur- oder 
Feuchteschwankungen zwischen 2 Messungen auftreten, daß das erste byte 
von zweien sich ändert. Aus dem gleichen Grund dürfen das zweite und das 
vierte byte auch nicht soooo stark variieren.

Also ich habe das Datenblatt 
(http://www.hygrosens.com/fileadmin/user_upload/Produkte/Sensorelemente/Digitale_Feuchtesensoren/HYT_I2C_Protokollbeschreibung_D.pdf) 
so verstanden, daß das "ready" bit (bit 14 oder 15 des ersten gelesenen 
bytes) gesetzt ist, wenn eine Wandlung fertig ist. Wenn eine Wandlung 
noch nicht fertig ist, ist das "stale" bit gesetzt (bit 14 oder 15). 
Bedeutet: Eines der beiden bits 14 und 15 ist immer gesetzt! Aus dem 
Grunde muß das erste byte auch mit 0x3F bzw. die beiden Feuchtebytes 
(wenn sie schon zusammengesetzt wurden) mit 0x3FFF verUNDet werden; also 
wirklich bit 14 und 15 wegmaskiert bzw. auf Null gesetzt werden. Das 
Kombinieren der beiden Feuchtebytes per Addition sieht ungewöhnlich aus, 
müßte aber auch funktionieren. Normalerweise verODERt man die Werte
(t = ((buffer[1]<<8) | (buffer[2])). Wahrscheinlich zu viele Klammern, 
aber ich gehe dabei lieber immer auf Nummer sicher.

Mit der Temperatur, wenn Du sie zusammengesetzt hast, mußt Du aber noch 
einen bitshift um 2 Stellen nach rechts machen!!! Die 14 bit kommen bei 
der Temperatur ja um 2 Stellen nach links geshiftet an (das bit 14 des 
Meßwertes wird auf bit 16 übertragen usw.).

Da mir das Timing auch noch unbekannt ist, schalte ich einfach die 
Spannung zum Sensor für ca. 600 ms aus und wieder ein. Denn nach dem POR 
macht der Sensor automatisch eine Messung und mann hat immer garantiert 
neue Meßwerte, wenn man das Kommando MR nicht senden kann oder will.

von Michael S. (Gast)


Lesenswert?

Hallo Lutz,

danke für die Rückmeldung. Hier kurz meine Gedanken dazu:

> Der Code sieht (für mich) etwas gewöhnungsbedürftig aus.
> Faktor 1000 für eine Nachkommastelle? Ach so, hast die 100/... da mit
> reingerechnet, macht es aber wirklich nicht übersichtlicher.

Dafür gibt es ja einen Kommentar.

> Am besten die rohen Werte komplett_ und an _einer Stelle verarbeiten,
> ist viel übersichtlicher.
> Und nach der Feuchte rechnest Du einfach so mit der
> Variablen "t" weiter, ohne sie vorher auf Null zu setzen und damit die
> vorherigen Werte zu löschen. Auch nicht schön.

Die Zuweisung t = x; sollte ausreichen.
Welchen Nutzen sollte es bringen, vorher ein t = 0; zu setzen ?

> Generell solltest Du auch das array für die Meßwerte in jedem
> Schleifendurchlauf neu mit einem aussagekräftigen Wert initialisieren,
> z.B. mit 0xAF. Besonders dann, wenn man noch am Fehler suchen ist.

Das TWI-Modul als solches ist erprobt und arbeitet anstandslos.
Ich prüfe lediglich, ob der TWI-Kommunikation erfolgreich war.

> Weiterhin dann erstmal nur die HEX-Werte anschauen und auf Plausibilität
> prüfen (steht nicht mehr 0xAF drin.), umrechnen kannst Du dann später,
> wenn es bis hier alles in Ordnung ist.

Genauso habe ich natürlich begonnen, alleine um die Formel zu 
überprüfen.

> So dürfen sich das erste und dritte byte nicht ändern, da wohl kaum so
> starke Temperatur- oder Feuchteschwankungen zwischen 2 Messungen
> auftreten, daß das erste byte von zweien sich ändert.

Und was ist bei einem Überlauf des Lower-Bytes ?

> Aus dem gleichen  Grund dürfen das zweite und das vierte byte auch nicht > soooo 
stark variieren.

So pauschal würde ich das nicht sagen.
Hier spielt das Messintervall eine Rolle (wenn ich 1x je Stunde messe, 
dann sind durchaus große Werteänderungen zu erwarten).

> Also ich habe das Datenblatt
> (http://www.hygrosens.com/fileadmin/user_upload/Pro...)
> so verstanden, daß das "ready" bit (bit 14 oder 15 des ersten gelesenen
> bytes) gesetzt ist, wenn eine Wandlung fertig ist. Wenn eine Wandlung
> noch nicht fertig ist, ist das "stale" bit gesetzt (bit 14 oder 15).
> Bedeutet: Eines der beiden bits 14 und 15 ist immer gesetzt!

Das habe ich nun anders verstanden.
Bit 15 zeigt einen allgemeinen Fehler.
Bit 14 sagt, das der Messwert seit dem letzten Lesen (noch) nicht 
geändert wurde.
Wenn ich die Wartezeit nach dem TWI-Write auf 50ms setze, dann ist bei 
einem TWI-Read das Bit 14 gesetzt (die Wandlung war noch nicht 
vollständig).

> Aus dem Grunde muß das erste byte auch mit 0x3F bzw. die beiden
> Feuchtebytes (wenn sie schon zusammengesetzt wurden) mit 0x3FFF verUNDet
> werden; also wirklich bit 14 und 15 wegmaskiert bzw. auf Null gesetzt
> werden.

Grundsätzlich ja.
Da ich aber vorher prüfe, ob eines der Bits gesetzt ist (in diesem Falle 
liegt ein Fehler vor), kann ich unterstellen, dass keines der Bits 
gesetzt ist - und auf das Maskieren verzichten.

> Das Kombinieren der beiden Feuchtebytes per Addition sieht ungewöhnlich
> aus, müßte aber auch funktionieren. Normalerweise verODERt man die Werte
> (t = ((buffer[1]<<8) | (buffer[2])).
> Wahrscheinlich zu viele Klammern, aber ich gehe dabei lieber immer auf
> Nummer sicher.

So sehe ich das auch.

> Mit der Temperatur, wenn Du sie zusammengesetzt hast, mußt Du aber noch
> einen bitshift um 2 Stellen nach rechts machen!!! Die 14 bit kommen bei
> der Temperatur ja um 2 Stellen nach links geshiftet an (das bit 14 des
> Meßwertes wird auf bit 16 übertragen usw.).

Ich habe nur verstanden, dass die beiden Bits maskiert werden sollen 
(obwohl sie bei meiner Multiplikation/Division sowieso eliminiert 
werden).

Wenn ich den Messwert anschließend noch 2x shifte (= durch 4 teile), 
dann erhalte ich aber keinen sinnvollen Temperaturwert mehr ?

> Da mir das Timing auch noch unbekannt ist, schalte ich einfach die
> Spannung zum Sensor für ca. 600 ms aus und wieder ein.
> Denn nach dem POR macht der Sensor automatisch eine Messung und mann
> hat immer garantiert neue Meßwerte, wenn man das Kommando MR nicht
> senden kann oder will.

In einem der Datenblätter habe ich (beim "Drüberfliegen") gelesen, dass 
die Wandlungszeit bei ca. 50ms liegt.
Das entspricht meiner Erfahrung mit dem Bit.14 im ersten Byte (sieh 
oben).

Ok - aber nun die entscheidende Frage.

Liefert das Modul bei deiner Interpretation der Datenblätter denn 
glaubwürdige Messwerte ?


mfg

Michael S.

von Lutz (Gast)


Lesenswert?

Michael S. schrieb:
>> So dürfen sich das erste und dritte byte nicht ändern, da wohl kaum so
>> starke Temperatur- oder Feuchteschwankungen zwischen 2 Messungen
>> auftreten, daß das erste byte von zweien sich ändert.
>
> Und was ist bei einem Überlauf des Lower-Bytes ?
Ich denke Du weißt, was ich meine.

Michael S. schrieb:
>> Aus dem gleichen  Grund dürfen das zweite und das vierte byte auch nicht > 
soooo
> stark variieren.
>
> So pauschal würde ich das nicht sagen.
> Hier spielt das Messintervall eine Rolle (wenn ich 1x je Stunde messe,
> dann sind durchaus große Werteänderungen zu erwarten).
Ist klar, nur wenn man etwas testet oder erforscht, ist das Meßintervall 
wohl eher im Sekundenbereich.

>> Also ich habe das Datenblatt
>> (http://www.hygrosens.com/fileadmin/user_upload/Pro...)
>> so verstanden, daß das "ready" bit (bit 14 oder 15 des ersten gelesenen
>> bytes) gesetzt ist, wenn eine Wandlung fertig ist. Wenn eine Wandlung
>> noch nicht fertig ist, ist das "stale" bit gesetzt (bit 14 oder 15).
>> Bedeutet: Eines der beiden bits 14 und 15 ist immer gesetzt!
>
> Das habe ich nun anders verstanden.
> Bit 15 zeigt einen allgemeinen Fehler.
> Bit 14 sagt, das der Messwert seit dem letzten Lesen (noch) nicht
> geändert wurde.
> Wenn ich die Wartezeit nach dem TWI-Write auf 50ms setze, dann ist bei
> einem TWI-Read das Bit 14 gesetzt (die Wandlung war noch nicht
> vollständig).
Zitat Datenblatt: "Erst nachdem der Messzyklus komplett abgearbeitet 
wurde ist das 'ready' Status Bit gesetzt und die aktuellen Messwerte 
stehen zur Verfügung. Ob der Messzyklus schon abgeschlossen wurde, kann 
somit durch zyklisches Auslesen des Ausgangsregistzers (polling) 
erfolgen. Erfolgt der Zugriff auf die Messwerte zu früh, so werden die 
Messwerte des vorherigen Messzyklus übertragen und das 'stale' status 
Bit ist gesetzt."
Also ich verstehe das so, daß während der Messung nur das stale bit 
gesetzt ist, wenn die Messung fertig ist nur noch das ready bit.
Ich werte diese bits allerdings nicht aus, da ich einfach, wie 
beschrieben, lange genug warte (zumindest derzeit).

Michael S. schrieb:
> Ich habe nur verstanden, dass die beiden Bits maskiert werden sollen
> (obwohl sie bei meiner Multiplikation/Division sowieso eliminiert
> werden).
>
> Wenn ich den Messwert anschließend noch 2x shifte (= durch 4 teile),
> dann erhalte ich aber keinen sinnvollen Temperaturwert mehr ?
Also meine Berechnung sieht so aus; da ist übrigens auch nix mit *10 für 
Nachkommastelle etc. erforderlich (gut, ist dafür mit Fließkomma, aber 
ich teste derzeit nur und der LPC1768 gibt's locker her)
1
  humidity_raw = 0;
2
  humidity_raw = ((Master_receive[0]<<8) | (Master_receive[1]));
3
  humidity_raw &= 0x3FFF;
4
  humidity = (100 * (double)humidity_raw) / 16384;
5
6
  temperature_raw = 0;
7
  temperature_raw = ((Master_receive[2]<<8) | (Master_receive[3]));
8
  temperature_raw = temperature_raw >> 2;          
9
  temperature = (((165 * (double)temperature_raw) / 16384) - 40);
Zitat: "Als drittes Byte werden die höchstwertigen 8 bits des 
Temperaturwerts übertragen. Danach kann als viertes Byte die 
niederwertigen 6 Bit des Temperaturwertes gelesen werden.Die letzten 
zwei Bits sind nicht benutzt und sollten wegmaskiert werden."
Wenn ich mir die Formel zur Temperaturberechnung anschaue (2^14), so 
wäre das auch plausibel mit dem shiften.

Michael S. schrieb:
> Ok - aber nun die entscheidende Frage.
>
> Liefert das Modul bei deiner Interpretation der Datenblätter denn
> glaubwürdige Messwerte ?
Ja, ich habe plausible Werte (wobei ich die Feuchte allerdings nicht 
vergleichen kann).
Wie ich erwähnte, habe ich allerdings den HYT-371. Da der allerdings von 
-40 bis +100 Grad geht (und nicht +125 Grad), hatte ich in der Formel 
oben zuerst statt 165 auch 140 genommen (weil es ja plausibel wäre ...), 
das war aber falsch und es gilt die Formel im Datenblatt. Wird wohl also 
intern im Chip schon irgendwas spezifisches gemacht. Daher kann es bei 
dem HYT-221 in der Tat anders sein. Ist eben schade, daß die 
Datenblätter nicht besser sind. Im Beispielcode von oben wird sogar eine 
ganz andere Formel benutzt. Habe darin aber gerade noch das gefunden:
1
//removing temperature status bits (ignored)
2
uMeasuredRawValue = uMeasuredRawValue >> 2;
Also shiften die auch und es scheint auch noch Statusbits für die 
Temperatur zu geben. Und weil es so logisch ist, sind die Statusbits der 
Temperatur hier die beiden LSB's ...

von Jens H. (deltaspace)


Lesenswert?

Hi Leute,

sorry das ich mich erst jetzt wieder Melde, aber ich kam nicht zum 
testen.
Jetzt habe ich es mit der Adresse 0x50 probiert, mit dieser Adresse kann 
ich werte auslesen, die auch in Ordnung sind.
Es lag also wirklich an den 0x28 im Datenblatt, weswegen ich nichts 
bekommen habe.

Danke für eure Hilfen.

MfG

Jens

von Michael S. (Gast)


Lesenswert?

@ Jens und Lutz,

hier noch einmal ausdrücklich die Frage nach der Plausiblität der 
Messwerte (auch bei unterschiedlichen Temperaturniveaus).

Anfangs hatte ich ja auch den Eindruck, die Werte würden stimmen (als 
ich nur bei Zimmertemperatur gemessen hatte).

Erst die Messungen über die zur Zeit kalten Nächte (morgens um 7:00h 
sind es teilweise unter 10°) haben dann gezeigt, dass die Abweichungen 
des HYT-221 um so größer werden, je weiter die Aussentemperatur von 20° 
abweicht.

Nur bei 20° stimmen die Werte für Temperatur und relative Feuchte mit 
anderen Messgeräten hinreichend überein.
Das kann man in der Log-Datei nachvollziehen, die ich gestern angehängt 
hatte.

mfg

Michael S.

von Michael S. (Gast)


Lesenswert?

@ Lutz

Shiften oder nicht shiften - das ist hier die Frage !

An folgender Stelle in "HUMICHIP DIGITALER FEUCHTESENSOR 
PROTOKOLLBESCHREIBUNG i2C"
(HYT_I2C_Protokollbeschreibung_D.pdf) habe ich mich orientiert:

Seite 2 unter DF(Data Fetch):

"Als drittes Byte werden die höchstwertigen 8 bits des Temperaturwertes 
übertragen.
Danach kann als viertes Byte die niederwertigen 6 Bit des 
Temperaturwertes gelesen werden.
Die letzten zweit Bits sind nicht benutzt und sollten wegmaskiert 
werden."

Man beachte die Formulierung "sollten". Müssen also nicht.
Und von shiften ist HIER keine Rede.
In dem Arduino-Beispiel von Hygrosens wird aber doch geshiftet.


Und auf Seite 3 oben steht zu der Bedeutung der Bits:

"Die obersten bei Bits sind Status Bits mit folgender Bedeutung:
Bit.15: CMode Bit, falls 1 ist der Baustein im Command Mode
Bit.14: Stale bit, falls 1 ist seit dem letzten Auslesen kein neuer 
Messwert gebildet worden."

Folgerung: Ist keines der beiden Bits gesetzt, dann ist alles in Butter.
Sofern die Dokumentation stimmt.

mfg

Michael.

von Lutz (Gast)


Lesenswert?

Michael S. schrieb:
> hier noch einmal ausdrücklich die Frage nach der Plausiblität der
> Messwerte (auch bei unterschiedlichen Temperaturniveaus).
>
> Anfangs hatte ich ja auch den Eindruck, die Werte würden stimmen (als
> ich nur bei Zimmertemperatur gemessen hatte).

Auf Grund meines Testaufbaus mit Steckbrett konnte ich bisher leider nur 
den Raum zwischen 15,9 und 20,8 Grad messen. Und das stimmte sehr gut 
mit einem normalen Thermometer überein. Feuchte kann ich leider nicht 
wirklich verifizieren, lag aber immer so zwischen 54 und 59 %. Wenn ich 
meinen Außensensor der Wetterstation reinhole, stimmt das nach 20 
Minuten auch ziemlich mit den Werten überein (Temperatur 0,4 Grad, 
Feuchte 4 %rF Abweichung, wobei ich nicht die Genauigkeit des 
Feuchtemoduls kenne).

Michael S. schrieb:
> Und auf Seite 3 oben steht zu der Bedeutung der Bits:
>
> "Die obersten bei Bits sind Status Bits mit folgender Bedeutung:
> Bit.15: CMode Bit, falls 1 ist der Baustein im Command Mode
> Bit.14: Stale bit, falls 1 ist seit dem letzten Auslesen kein neuer
> Messwert gebildet worden."
>
> Folgerung: Ist keines der beiden Bits gesetzt, dann ist alles in Butter.
> Sofern die Dokumentation stimmt.

Die Seite 3 hatte ich wegen der anderen Fehler bisher gar nicht so 
wirklich wahrgenommen. Das paßt dann aber wieder nicht mit der Seite 1 
zusammen (was ich schon zitiert hatte, mit dem "ready" bit).

Michael S. schrieb:
> In dem Arduino-Beispiel von Hygrosens wird aber doch geshiftet.

Das macht das ganze wirklich nicht einfacher. Ich vermute mittlerweile, 
daß diese Beschreibung doch nicht für alle Sensoren gültig ist, zumal 
neben Dir auch Jens seinen Sensor (HYT-221) mit 0x50 anspricht, während 
mein HYT-371 auf die 0x28 reagiert (0x50 ist meinem übrigens egal, 
passiert nix). Wenn Du shiftest, kommt bei Dir Quatsch raus, wenn ich 
nicht shifte, kommt bei mir Quatsch bei der Temperatur raus.

von Michael S. (Gast)


Lesenswert?

@ Lutz

um eine Erklärung für die Differenzen/Missverständisse bei der 
Adressierung zu erhalten, habe ich mir die Datenblätter diverser 
Standard-I2C-Buskomponenten (PCF8574 etc.) angesehen.
Hier werden die Adressen ausschließlich binär dargestellt.

Für den HYT-221 würde sie lauten:

0101 0000.

Als Slave-Adresse sind die höchstwertigen 7 Bit definiert, also

0101 000

Angehängt wird ein weiteres Bit, das über Lesen oder Schreiben 
entscheidet (R/W-Bit).
Zusammen ergeben das 8 Bit:

Slave-Adr: 0101 000 plus R/W-Bit: 0/1.

Wenn man das Byte in seine Komponenten (Slave-Adresse und  R/W-Bit) 
zerlegt, dann kann man die Adresse gedanklich nach rechts shiften und 
als 7-Bit lesen:

010 1000 = 0x28.

Oder ungeshiftet als 8-Bit:

0101 0000 = 0x50.

Letztlich meint aber beides dasselbe.

Unglücklich ist lediglich die Beschreibung des Datenblattes.
Hätte man hier anstelle der Angabe 0x28 die binäre Darstellung der 
Adresse gewählt, dann wäre die Interpretation eindeutig gewesen und 
Missverständisse ausgeschlossen worden.


mfg

Michael S.

von Lutz (Gast)


Lesenswert?

Michael S. schrieb:
> Wenn man das Byte in seine Komponenten (Slave-Adresse und  R/W-Bit)
> zerlegt, dann kann man die Adresse gedanklich nach rechts shiften und
> als 7-Bit lesen:
>
> 010 1000 = 0x28.
>
> Oder ungeshiftet als 8-Bit:
>
> 0101 0000 = 0x50.
>
> Letztlich meint aber beides dasselbe.

Hallo Michael,

das klingt auf jeden Fall plausibel. Das hätte ich jetzt aber gar nicht 
rausgefunden, da ja I2C per Definition eine 7 bit-Adresse hat. Und das 
Read/Write bit hätte ich da deshalb nun wirklich nicht reingerechnet und 
gesagt "reagiert auf 0x50".

Auf jeden Fall sind wir jetzt schon mal einen Schritt weiter (sogar in 
eine positive Richtung).

Unverständlich bzw. unterschiedlich ist auf jeden Fall das shiften/nicht 
shiften beim Temperaturwert. Vielleicht solltest zum Testen mal "meine" 
Temperaturformel nehmen. Oder mal statt
temperatur = (int16_t) (t - 40);
lieber
temperatur = ((int16_t) t) - 40;
nehmen, da t ja uint32_t ist ...

von Michael S. (Gast)


Lesenswert?

@ Lutz,

> Unverständlich bzw. unterschiedlich ist auf jeden Fall das shiften/nicht
> shiften beim Temperaturwert.

Du hattest ja schon darauf hingewiesen, dass ich - wenn ich meine 
Messwerte shifte - alle Wert durch 4 dividiere.
Mit dem Ergebnis, dass alle Temperaturwerte entsprechend kleiner werden. 
Also noch falscher.

> Oder mal statt
> temperatur = (int16_t) (t - 40);
> lieber
> temperatur = ((int16_t) t) - 40;
> nehmen, da t ja uint32_t ist ...

Ja, ja, das Vermischen von int und uint bringt mich immer wieder ins 
Rotieren.

uint32_t t;
temperatur = (int16_t) (t - 40);

Angenommen t = 39, dann wird (t - 40) zu 0xFF FF FF FF.
Wenn dieser Wert zu int16 gecastet wird, was wird dann daraus ?

Insofern ist Dein Hinweis richtig. Besser ist, erst t zu int16_t zu 
casten und danach zu subtrahieren:

temperatur = ((int16_t) t) - 40;

Nur zu dumm, dass sich die Werte von RH und T dadurch immer noch nicht 
verbessern.

Wenn man einmal annehmen würde, dass
- der Fehler nicht am Modul und
- nicht an seinen Kalibrierwerten liegt und
- dass der Fehler ein linearer Fehler ist,
dann könnte man mit den Parametern in der Berechnungsformel spielen.

y = a * x + b

Bislang ist a = (100 / 2^14) und b = -40.
Wenn a größer wird, dann nimmt die Steigung der Geraden zu.
b könnte verkleinert werden, so dass bei 20° die Messergebnisse 
unverändert bleiben.

Ich habe mich mal drangemacht
- die geloggten Temperaturdaten rückzukonvertieren in die vom Sensor 
gelieferten Werte,
- dann die Parameter der Formel so variieren, dass die erwarteten 
Temperturwerte geliefert werden.

Wenn ich die Parameter a = (255 / 2^14) und b = -133,5 eingeben, dann 
nähern sich die Temperaturwerte, die der HYT-221 liefert, den erwarteten 
Wert an.
Natürlich kann ich nur einige wenige Daten im Bereich von 9° über 15° 
nach 22° prüfen.
Und das reicht nicht für ein belastbares Resultat.

Vielleicht sollte ich die Module mal im Backofen testen.

mfg

Michael S.

von Lutz (Gast)


Lesenswert?

Bitte poste mal Deine puren HEX-Werte; also wirklich die 4 bytes, die Du 
aus dem Sensor liest, sowie die von Dir daraus errechneten Meßwerte.
Und Dein vollständiges Programm.

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

@ Lutz,

hier die von mir geloggten Daten:

- einmal als unbearbeitetes Logfile,
- in die Tabellenkalkulation eingelesenes Logfile mit umgerechneten
  Messwerten,
- ein älteres Logfile ohne Zeiteinträge (Messintervall 30 Sekunden),
- der relevante Programmteil mit der Datenaquise und der Konversion.

mfg

Michael S.

von Lutz (Gast)


Lesenswert?

Hallo Michael,

ich war eigentlich schwerpunktmäßig an den Definitionen dieser beiden 
Funktionen interessiert, da nicht ersichtlich ist, was dort passiert:
1
TWI_MA_Start_Transceiver_With_Data(buffer, 5); // Daten via TWI einlesen
2
TWI_MA_Get_Data_From_Transceiver(buffer, 5);// Daten abholen

Und in den Logfiles sind ja schon bearbeitete Werte drin; Du hast ja 
z.B. in der Datei logfile_hyt221.log in der ersten Zeile zwei Sensoren 
aufgezeichnet. Dort steht
...;4014;22548;4096;22100;...
...;erste Feuchte;erste Temperatur;zweite Feuchte;zweite Temperatur;...
Das bedeutet, daß die 4 rohen, aus dem Sensor gelesenen bytes (high-byte 
Feuchte, low-byte Feuchte, high-byte Temperatur, low-byte temperatur) 
schon irgendwie bearbeitet (z.B. zusammengesetzt) wurden. Und ich war an 
den unbearbeiteten bytes interessiert.

Also bitte einfach eine Messung machen, die 4 ausgelesenen bytes sowie 
die dazu errechneten Werte posten (und die vollständige Definition der 
beiden o.g. Funktionen, damit ich wirklich jeden einzelnen Schritt in 
der Kette vom Auslesen bis zum errechneten Wert nachvollziehen kann).

von Michael S. (Gast)


Lesenswert?

@ Lutz,

am 22.04.11 hatte ich als Anlage in der Datei "hyt-221-110422.zip" den 
damaligen Programmcode beigefügt.

Dort sind im Modul "twi_master.c" die beiden Funktionen definiert.

- TWI_MA_Start_Transceiver_With_Data();

Lädt interruptgesteuert die Daten in einen lokalen Buffer des Moduls.

- TWI_MA_Get_Data_From_Transceiver();

Holt die Daten aus dem Modul ab.

Das Programm ist eine Anpassung einer Atmel-AP-Note und funktioniert in 
zahlreichen meiner Anwendungen ohne Probleme
(Man kann Fehler nie ausschließen - aber hier würde ich zuletzt suchen).

Im der Datei "hyt_221_log.c" kann man sehen, wie im Unterprogramm 
HYT_221_read() die vom HYT_221 eingelesenen Daten verarbeitet werden:
Während des Logvorgangs werden sie unverändert Byte für Byte in ein 
Eeprom geschrieben.

Beim Auslesen des Logfiles im Unterprogramm HYT_221_konvert() werden 
dann jeweils 2 Bytes in einer 16Bit Variablen zusammengefügt, via utoa() 
in einen String umgewandelt und über die serielle Schnittstelle 
ausgegeben.

mfg

Michael S.

von Lutz (Gast)


Lesenswert?

Entschuldige, aber ich hatte mir nur den späteren Anhang vom 30.04. 
angeschaut. Heute geht es mir leider nicht so prickelnd, weshalb ich den 
Funktionen TWI_MA_Start_Transceiver_With_Data(buffer, 1);
und
TWI_MA_Get_Data_From_Transceiver(buffer, 5);
heute nicht mehr Folgen kann.
Auch den Aufruf
TWI_MA_Start_Transceiver_With_Data(buffer, 5); // Daten via TWI einlesen
TWI_MA_Get_Data_From_Transceiver(buffer, 5);// Daten abholen
hintereinander kann ich deshalb nicht nachvollziehen, oder daß beim 
ersten write die for-Schleife nicht ausgeführt wird.

Morgen Abend ist es aber bestimmt besser.

von Michael S. (Gast)


Lesenswert?

@Lutz,

wenn Du den Einstieg in das TWI-Modul machen willst .. naja, da muss man 
sich schon etwas reindenken.
Hier ein paar Worte zur Erläuterung:

Um die RH und T zu lesen und bereitzustellen, muss der HYT_221 mit 
seiner TWI-Adresse ohne weitere Parameter schreibend (R/W = 0) 
angesprochen werden.

Daher wird zuerst die TWI_Adresse (0x50, R/W-Bit = 0) an den Slave 
gesendet.
Die Adresse steht in Buffer[0].
> buffer[0] = HYT221_ADR;

Es wird genau ein Byte gesendet, nämlich die Adresse. Daher:
> TWI_MA_Start_Transceiver_With_Data(buffer, 1);

(Anmerkung: TWI_MA_Start_Transceiver_With_Data() kann Senden und 
Empfangen, entscheidend ist das R/W-Bit im ersten Byte, der 
TWI-Adresse.)

Zur Sicherheit wird geprüft, ob die Transaktion einen Fehler verursacht 
hat (z.B. Slave nicht präsent)
> if (!(TWI_LastTransOK()))

Wenn die Transaktion ok war, dann wird 100ms gewartet, in dieser Zeit 
sollte der HYT-221 seine Arbeit abgeschlossen haben.
> delay_ms(10);

Dann wird die TWI_Adresse incrementiert (= das R/W-Bit gesetzt, die 
Adresse ist nun = 0x51).
> buffer[0]++;

Da vier Byte abgeholt werden sollen, wird als Parameter (1 für die 
Adresse + 4 für die Daten) übergeben.
> TWI_MA_Start_Transceiver_With_Data(buffer, 5);

Das Modul liest nun im Hintergrund interruptgesteuert die 4 Byte ein.

Das Unterprogramm
> TWI_MA_Get_Data_From_Transceiver(buffer, 5);

holt die 4 Byte (genaugenommen 5, weil die Adresse in Byte[0] steht) ab.
Dabei wird aber ein Flag gepollt, dass anzeigt, ob die TWI-Übertragung 
abgeschlossen ist.
> while ( TWCR & (1<<TWIE) );

Sobald die Übertragung beendet, werden die Daten zurückgeliefert und 
können ausgewertet werden.

(Hinweis: In diesem konkreten Fall bringt der Einsatz des TWI-Interrupts 
keinen Vorteil gegenüber dem reinen, pollenden Betrieb.)

mfg

Michael S.

von Michael S. (Gast)


Lesenswert?

@ Lutz,

habe freundlicherweise von Hygrosens noch eine Mail bekommen.
In einem BASCOM-Beispiel löst sich das Problem "Shiften oder nicht 
Shiften" der Raw-Temperaturwerte:

Beim HYT 271 ist der Divisor für die Temperatur nicht 2^14 sondern 2^16, 
dass heißt, der Bereich von 0 - 100% Luftfeuchte skaliert auf den 
Zahlenbereich von 0 .. 2^16.

Indem Du den Raw-Wert erst zweimal nach rechts shiftest und dann durch 
2^14 teilst, dividierts Du genau durch 2^16.
Also hast Du durch einen doppelten Irrtum den richtigen Wert erhalten.

Offensichtlich liefern die unterschiedlichen Sensortypen die Daten in 
unterschiedlichen Formaten aus.

' 1. humidity

    Hbyte1 = Hbyte1 And &H3F  '  clear status bits

    Answer1 = Hbyte1
    Shift Answer1 , Left , 8
    Answer1 = Answer1 Or Lbyte1

' hymidity is  bin - value in Answer1 ( 14 Bit )
' recalculation in float
' Scale 0 .. 16383 = 0 .. 100 %

    Humidity = Answer1 / 163.84

' formating with 2 digits

    Ha = Fusing(humidity , "#.##")

' 2. temperature

    Answer2 = Hbyte2
    Shift Answer2 , Left , 8
    Lbyte2 = Lbyte2 And &HFC
    Answer2 = Answer2 Or Lbyte2

' temperatur is bin - value in Answer2 ( 14 Bit )
' set the 2 right bit to 0
' recalculation in float
' Scale 0 ... 65535 = -40 C to +125 C

   Temperature = Answer2
   Temperature = Temperature / 65536
   Temperature = Temperature * 165
   Temperature = Temperature - 40

Zu dumm dass ich immer noch keine Lösung für meinen HYT-221 habe.
Ein stimmiges Datenblatt für den HYT-221 zu erhalten, das wäre jetzt der 
krönende Abschluss.

mfg

Michael S.

von Michael S. (Gast)


Lesenswert?

@ Lutz,

zwischenzeitlich hat mir hygrosens per email bestätigt, dass die 
verwendete Berechnungsformel

> RH = Raw * 100 / 2^14
> T = (Raw * 165 / 2^14) - 40

korrekt sei (für den HYT-221 !).

Gleichzeitig hat man mir angeboten, die Sensoren einzusenden.
Das Angebot werde ich annehmen und dann hoffentlich bald über einen 
Erfolg berichten können.

mfg

Michael S.

von MaWi (Gast)


Lesenswert?

Jetzt, wo ich das alles hier lese, wird mir klar, warum ich dem Sensor 
(HYT371) seit Tagen nichts entlocken kann. Sobald ich eigene 
Erkenntnisse habe, werde ich eine Rückmeldung geben!

von Lutz (Gast)


Lesenswert?

Hallo Michael,
das war ja ein ereignisreicher Tag! Vielen Dank für die Erklärungen, da 
kann ich mir das ganze gehüpfe durchs Datenblatt und die beiden 
relevanten c-Dateien sparen; das ging gestern gar nicht bei mir.

Eines habe ich aber noch nicht ganz verstanden, bitte noch erklären:

Michael S. schrieb:
> Da vier Byte abgeholt werden sollen, wird als Parameter (1 für die
> Adresse + 4 für die Daten) übergeben.
>> TWI_MA_Start_Transceiver_With_Data(buffer, 5);
>
> Das Modul liest nun im Hintergrund interruptgesteuert die 4 Byte ein.
>
> Das Unterprogramm
>> TWI_MA_Get_Data_From_Transceiver(buffer, 5);
>
> holt die 4 Byte (genaugenommen 5, weil die Adresse in Byte[0] steht) ab.

Wenn ich die MA_Start-Funktion mit den Parametern (buffer, 5) durchgehe:
TWI_MA_buf[0] wird der Wert 0x51 zugewiesen.
Die if-Bedingung ist nicht erfüllt.
=> Was passiert nun? Du schreibst, das Modul liest in ISR 4 byte 
ein.Wäre dann nicht die nächste Get_Data-Funktion überflüssig?

Dann kommt die Get_Data-Funktion, um die Daten aus dem Sensor 
auszulesen.
=> Nochmal Daten lesen? Wäre dann nicht die vorherige Funktion 
überflüssig?

von Lutz (Gast)


Lesenswert?

Michael S. schrieb:
> Beim HYT 271 ist der Divisor für die Temperatur nicht 2^14 sondern 2^16,
> dass heißt, der Bereich von 0 - 100% Luftfeuchte skaliert auf den
> Zahlenbereich von 0 .. 2^16.
>
> Indem Du den Raw-Wert erst zweimal nach rechts shiftest und dann durch
> 2^14 teilst, dividierts Du genau durch 2^16.
> Also hast Du durch einen doppelten Irrtum den richtigen Wert erhalten.
>
> Offensichtlich liefern die unterschiedlichen Sensortypen die Daten in
> unterschiedlichen Formaten aus.

Michael S. schrieb:
> Zu dumm dass ich immer noch keine Lösung für meinen HYT-221 habe.

Das scheint das Problem zu sein: Du hast den 221, das Beispiel ist für 
den 271 und ich habe den 371.
Leider scheinen die wirklich unterschiedlich zu sein!!!

Michael S. schrieb:
> Ein stimmiges Datenblatt für den HYT-221 zu erhalten, das wäre jetzt der
> krönende Abschluss.

Das wäre wirklich die Lösung (und das von Anfang an).

von Lutz (Gast)


Lesenswert?

@MaWi:
Ich habe den 371 erfolgreich am Laufen, allerdings mit einem LPC1768 und 
der Firmware-Lb von NXP. ZUmindest glaube ich, daß es erfolgreich ist. 
Wo genau klemmt es denn bei Dir?

von Matthias W. (mawi_pic)


Lesenswert?

Hallo Lutz!
Ich verwende PIC16Fxx-Controller (später evtl. auch 18er PIC's) zum 
ansteuern. Habe gestern abend für den HYT371 mal die Adressen 50h und 
51h verwendet. Und schon habe ich auf dem Display einen Wert, der sich 
je nach Feuchte verändert. Am Wochenende werde ich daran gehen zu 
schauen, ob die Werte auch irgendwie sinnvoll sind.

an alle:
Wäre es vielleicht dienlich, mal ein neues Thema anzufangen? Der 
Ursprung war ja mal "HYT221 an ATmega8 macht nichts". Eine Aufteilung in 
die einzelnen Sensor-Typen ist vl. nicht schlecht. Denn manche scheinen 
ja so zu funktionieren, wie in den Unterlagen.

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

@ Lutz,

wenn TWI_LastTransOK() ein False meldet, dann liegt ein fataler Fehler 
vor.
Es kam keine erfolgreiche TWI-Kommunikation zustande.
Meist liegt die Ursache an einer falsche Adresse, an Problemen mit der 
Verkabelung, fehlenden Pullups oder einem blockierten Bus.
In diesem Falle kann man nur noch abbrechen.

Wenn dagegen im ersten gelesenen Byte das Bit.6 gesetzt ist, dann ist 
der Sensor vermutlich noch am Konvertieren.
In diesem Fall macht es Sinn, noch weitere Leseversuche zu starten.

Wenn weitere 9 Versuche auch die keinen Erfolg bringen, dann wird 
ebenfalls beendet.

In der Testphase werden über die serielle Schnittstelle Meldungen 
ausgegeben.

Den zuständigen Programmausschnitt füge ich noch einmal bei.

Übrigens noch schönen Dank für Deine Hilfsbereitschaft.

mfg

Michael S.

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo allerseits,

meine Erkenntnisse aus dem Versuch der Inbetriebnahme der Module 
(genaugenommen nur den HYT-221) habe ich mal zusammengefasst.

In der Hoffnung, dass andere weniger viel Zeit dabei verschwenden 
müssen.

Hinweise auf Fehler und Ergänzungen sind willkommen.

mfg

Michael S.

von Lutz (Gast)


Lesenswert?

Hallo Michael,

> Wenn ich die MA_Start-Funktion mit den Parametern (buffer, 5) durchgehe:
> TWI_MA_buf[0] wird der Wert 0x51 zugewiesen.
> Die if-Bedingung ist nicht erfüllt.
> => Was passiert nun? Du schreibst, das Modul liest in ISR 4 byte
> ein.Wäre dann nicht die nächste Get_Data-Funktion überflüssig?
>
> Dann kommt die Get_Data-Funktion, um die Daten aus dem Sensor
> auszulesen.
> => Nochmal Daten lesen? Wäre dann nicht die vorherige Funktion
> überflüssig?
kleines Mißverständnis oder ich habe es immer noch nicht verstanden: Ich 
meinte die If-Bedingung in der Funktion
1
void TWI_MA_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize )
2
{
3
   unsigned char temp;
4
   while ( TWCR & (1<<TWIE) );           // Wait until TWI is ready for next transmission.
5
6
   TWI_msgSize = msgSize;                // Number of data to transmit.
7
   TWI_MA_buf[0]  = msg[0];              // Store slave address with R/W setting.
8
   if (!( msg[0] & (0x01) ))             //If it is a write operation, then also copy data.
9
   {
10
   for ( temp = 1; temp < msgSize; temp++ )
11
      TWI_MA_buf[ temp ] = msg[ temp ];
12
   }
13
    
14
   TWI_success = FALSE;
15
   TWI_state   = TWI_NO_STATE ;
16
   TWCR = (1<<TWEN)|                            // TWI Interface enabled.
17
          (1<<TWIE)|(1<<TWINT)|                 // Enable TWI Interupt and clear the flag.
18
          (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)|      // Initiate a START condition.
19
          (0<<TWWC);     
20
}
Danach wird die folgende Funktion mit (buffer, 5) aufgerufen:
1
unsigned char TWI_MA_Get_Data_From_Transceiver( unsigned char *msg, unsigned char msgSize )
2
{
3
   unsigned char i;
4
5
  while ( TWCR & (1<<TWIE) );                // Wait until TWI is ready for next transmission.
6
  if (TWI_success)                        // Last transmission competed successfully.
7
   {                                             
8
   for ( i=0; i<msgSize; i++ )                  // Copy data from Transceiver buffer.
9
      {
10
         msg[ i ] = TWI_MA_buf[ i ];
11
      }
12
   }
13
14
   return( TWI_success );
15
}

Das hatte ich nicht verstanden:
- die If-Bedingung in der ersten Funktion ist beim Aufruf mit (buffer, 
5) nicht erfüllt, weshalb dann auch die zugehörige for-Schleife nicht 
ausgeführt wird. Was macht die Funktion jetzt noch?

- Warum die beiden Funktionen überhaupt hintereinander ausgerufen 
werden, da Du ja geschrieben hattest, daß auch die erste Funktion lesen 
kann.

Ich hoffe, daß ich es diesmal halbwegs verständlich rübergebracht habe.

von Michael S. (Gast)


Lesenswert?

@ Lutz,

zwar hat Deine Frage nichts mit eigentlichen Inhalt dieses Threads zu 
tun, ich will sie dennoch kurz beantworten:

> if (!( msg[0] & (0x01) )) //If it is a write operation, then also copy data.

Wenn das Read-Bit gesetzt ist, dann wird nur das erste Byte des 
übergebenen Arrays als Adresse übernommen, alle anderen werden 
ignoriert, da ja gelesen werden soll.
Lediglich der 2. Parameter der Funktion, die Anzahl der zu lesenden 
Bytes, ist von Bedeutung.

Ist das Read-Bit nicht gesetzt (R/W-Bit = 0), dann sollen die Daten 
innerhalb des Arrays an den Slave gesendet werden.
Daher werden sie zunächst in ein lokales Array umkopiert.

Anschließend werden die "richtigen" Bits in TWCR gesetzt und von nun an 
läuft die weitere Arbeit interruptgesteuert.
D.h., sobald ein Byte versendet wurde, wird via Interrupt wieder in das 
Modul gesprungen und das nächste Byte versendet.
Der Controller kann zwischendrin andere Aufgaben erledigen und muss 
nicht warten, bis die Übertragung abgeschlossen ist.

Wenn nun Daten empfangen (vom Master aus dem Slave ausgelesen werden), 
dann werden diese zuerst wieder im Hintergrund in den lokalen Buffer 
geschrieben.

Das Ende der Übertragung kann das Programm am Bit TWIE im Register TWCR 
erkannt.
Die Bedingung in der Schleife

> while(TWCR & (1<<TWIE);

ist solange erfüllt, wie TWIE gesetzt ist.
TWIE wird nach Übertragung/Empfang des letzten Bytes gelöscht.

Nun stehen die empfangenen Daten aber immer noch im lokalen Buffer des 
Moduls.
Also müssen sie vom aufrufenden Programmteil abgeholt werden.
Genau dazu dient die Funktion TWI_MA_Get_Data_From_Transceiver().

Die Steuerung der Kommunikation erfolgt über die Bits in TWCR.
Deren Bedeutung musst Du Dir genau ansehen, dann verstehst Du, wie das 
Modul arbeitet.

Die Funktionen und ihre Bezeichnung habe ich weitgehend aus der Vorlage 
von Atmel übernommen.
Die Namen sind etwas lang, aber ich wollte die Herkunft erkennbar 
lassen.

Etwas irritierend ist, das das 1. Byte des Buffers immer die Adresse 
ist.
Die Daten beginnen immer erst bei Buffer[1].
Da kann man sich aber dran gewöhnen.

Für das Verständnis übersichtlicher wäre möglicherweise, wenn man die 
Funktion TWI_Start_Transceiver_With_Data() in ein TWI_write() und ein 
TWI_read aufdröseln würde.
Das TWI_read könnte auch gleich das Abholen der Daten aus dem TWI-Modul 
mit übernehmen ...
Aber das kann ja jeder so halten, wie es seinem Verständnis am besten 
entspricht.

mfg

Michael S.

von Michael S. (Gast)


Lesenswert?

Hallo allerseits.

Was machen denn Eure Messungen mit den Hygrosens-Sensoren ?
Man hört ja nichts mehr - ist das als gutes Zeichen zu werten ?

Bei mir gibt es zunächst tatsächlich gute Nachricht:
Hygrosens hat meine beiden Sensoren getauscht.

Die schlechte Nachricht:
Die mit den neuen Sensoren erzielten (Temperatur-) Messwerte sind 
genauso falsch wie vorher.

Aber denken wir positiv:
ich darf nun davon ausgehen, dass nicht die Hardware fehlerhaft ist.

Auf der Suche nach Fehlerquellen habe ich einige Zeit mit den Raw-Werten 
in der Tabellenkalkulation experimentiert.

Bis mir auffiel, dass Kommisar Zufall mich an der Nase herumgeführt hat:

Rein zufällig stimmten die Temperaturwerte (nur) bei Raumtemperatur.
Allerdings wurden sie in der Einheit 0.1 Grad zurückgegeben.
Die Subtraktion von 40 in der Umrechnungsformel konnte demnach als 
niedrigsten Wert nur -4.0° liefern.
Da konnte etwas nicht stimmen.
Weiterhin lagen die Raw-Werte (der Temperatur) - die eigentlich im 
Bereich 0 bis 2^14 erwartet werden sollten - weit höher als 2^14.

Und dann wurde mir klar, dass mir die Lösung des Problems längst bekannt 
war:

Die Raw-Wert (14 Bit) stehen linksbündig im 3./4.Byte der vom Sensor 
zurückgelieferten Werte.
Um sie auf den Wertebereich 0..2^14 zur reduzieren, müssen sie um 2 Bit 
nach rechts geschiftet werden.

Dann kann die von Hygrosens angegebenen Formel benutzt werden:

T = (165 * T_raw / 2^14) - 40

Sie liefert die Temperatur nun in der Einheit Grad.

Alternativ kann man direkt den ungeshifteten Wert nehmen und rechnen:

T = (165 * T_raw / 2^16) - 40

Dann sollte man (möglicherweise vorher) die beiden niedrigstwertigen 
Bits der Raw-Temperatur maskieren.

Eine klar und eindeutig formulierte Dokumentation hätte hier Vielen 
wirklich viel Zeit erspart !
Wenn man die Lösung kennt, dann kann man sie in 2 Sätzen formulieren.
Kennt man sie nicht, dann kann man stundenlang raten !

Jetzt bleibt für mich noch die Frage zu klären, wie verlässlich die 
RH-Werte sind.
Der nächtliche Log im überdachten Aussenbereich (bei Regen) lieferte 
eine relative Luftfeuchte von bis zu 99.9%.
Mein Handmessgerät zeigte am frühen Morgen 83% (der HYT-221 lieferte da 
95%).



mfg


Michael S.

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo allerseits,

nachdem nun auch bei mir die Temperaturmessung mit dem HYT-221 
funktioniert, hier meine überarbeiteten Erkenntnisse zur Inbetriebnahme 
der Module.

mfg

Michael S.

von Andreas S. (Gast)


Lesenswert?

Hallo,

nur mal so zur Info:
* TWI ist nur ein Begriff, um die (früher) angeblich fälligen 
Lizenz-Gebühren zu umgehen, denn der ehem. patentierte Standard heißt 
I²C.

* jeder I²C-Slave hat eine 7-Bit-Adresse - die 10-Bit-Adressen mal außen 
vor gelassen. Dass die Adresse auf den Bits 1-7 eines Bytes eingetragen 
werden, ändert nichts an der Adresse. Das erste Byte nach der 
Start-Prozedur beinhaltet nunmal 2 Felder.

* jeder der "8-Bit"-Adressen verwendet und den Geräten dann eine Lese- 
und Schreib-Adresse verpasst, ist nur zu faul zum Shiften. Viel Spaß bei 
10-Bit-Adressen!

* Wenn der Sensor laut Protokoll so arbeitet, dass er zuerst eine 
Messaufforderung haben möchte, dann ist es gemeinhin nicht komisch, wenn 
er ohne die immer den letzten Wert liefert. Sondern es hat was mit 
Strom-sparen zu tun, wenn er nur auf Aufforderung misst und berechnet.

> Dann habe ich einen Log im Aussenbereich durchgeführt.
...
> Das Ergebnis war umwerfend:
> Bei realer Luftfeuchte von 70% (nach Regenschauer) liefert der Sensor
> 93% und die Temperaturwerte sind viel zu hoch.

Also während des Regens liegt die Luftfeuchte meiner Meinung nach bei 
ca. 100%, sonst würde es nicht regnen. Wie lange nach dem Regen wurde 
die Messung durchgeführt? Waren die Sensoren direkt dem Regen ausgesetzt 
oder überdacht? War das Handmessgerät auch ständig neben den Sensoren? 
Ist der Feuchtesensor des Hanmessgeräts geschützt oder außen liegend? 
War die Witterung nach dem Regen eher kühl oder kam gleich die Sonne 
raus und hat die Sonne Sensor und Handmessgerät gleichermaßen 
beschienen?

Also ich mein ja nur, es gibt halt viele Faktoren, die sich auf komische 
Messergebnisse auswirken

Gruß, Andreas

Also ich meine

von Frank B. (frank13)


Lesenswert?

Hallo allerseits!

Ich beschäftige mich gerade mit dem HYT 271 und habe ein etwas kurioses 
Problem:
Wenn ich per TWI an die Adresse 0x28 (oder 50 je nach Sichtweise) 
schreibe, bleibt der gesamte TWI-Bus hängen. Der HYT scheint den SDA 
dauerhaft auf Masse zu ziehen. Wenn ich den Pin abnehme, läuft der Bus 
weiter. Wenn ich eine andere Adresse beschreibe, läuft auch Alles. Hat 
da jemand eine Idee woran das liegen könnte?
Ich nutze den MSP430F2112.

Edit: Die Übertragung geht bis zum ACK (also Adresse erkannt) und dann 
bleibt SDA auf Masse.

Viele Grüße

Frank

von Michael S. (Gast)


Lesenswert?

@ Frank Bußmann,

wenn der Slave mit ACK antwortet, dann ist nicht er das Problem.

Der Master muss ein Stop senden (SDA wieder auf VCC ziehen).
Das tut er offensichtlich nicht.
Warum ?

Vielleicht fehlen die Pullups ?

mfg

Michael S.

von Frank B. (frank13)


Lesenswert?

Hi!

Die Pullups sind drin (je 10 kOhm). SDA bleibt "sauber" auf Masse 
kleben...

Viele Grüße

Frank

von Michel (Gast)


Lesenswert?

Frank Bußmann schrieb:
> SDA bleibt "sauber" auf Masse
> kleben...
Und was macht der Master mit SCL?

von Michael S. (Gast)


Lesenswert?

@ Frank Bußmann,

versuche es mal mit 3.3k Pullups.

Zur Fehlereingrenzung würde ich einen PCF8574 anschließen.

Sollte auch der Fehler auch hier auftreten, dann ist klar, dass der 
Master der Verursacher ist.

Michael S.

von Frank B. (frank13)


Lesenswert?

Hi,

der bleibt auch auf Masse, der Bus "steht" also. Wenn ich dann den SDA 
abklemme, läuft der Bus weiter. Steckt da evtl. noch ein Fehler im 
Master?

Edit: den PCF werde ich mal testen - ist eine gute Idee.

Frank

von Michael S. (Gast)


Lesenswert?

@ Frank Bußmann,

> Der HYT scheint den SDA
> dauerhaft auf Masse zu ziehen. Wenn ich den Pin abnehme, läuft der Bus
> weiter. Wenn ich eine andere Adresse beschreibe, läuft auch Alles. Hat
> da jemand eine Idee woran das liegen könnte?

> Wenn ich dann den SDA abklemme, läuft der Bus weiter.

Ich hätte da den Verdacht, dass SDA immer auf Masse liegt (Kurzschluss 
?).

Das vermutete ACK ist möglicherweise gar keine Antwort des Slaves ?

mfg

Michael S.

von Frank B. (frank13)


Lesenswert?

Hi!

Ein Kurzschluß auf SDA kann es nicht sein - ich sehe die korrekte 
Start-Kondition und auch die korrekten Adressbits auf dem Oszi.
Der Fehler (also das "unendliche" ACK) kommt auch nur, wenn ich die 
Sensoradresse schreibe, sonst nicht.

Viele Grüße

Frank

von Michael S. (Gast)


Lesenswert?

@ Frank Bussmann,

ok, du hast Recht.
Es ist ja eigentlich der Slave, der SDA runterzieht und dann wieder 
losläßt.
Tut er das nicht, dann könnte die Ursache an SCK liegen.

Kannst du den auch parallel das SCK-Signal darstellen ?

Grundsätzlich würde ich zuerst die Funktion des Masters an einem 
Standard-Slave prüfen.

Michael S.

von Frank B. (frank13)


Lesenswert?

Hi!

Der SCK bleibt auch auf Masse - so langsam vermute ich irgendeinen 
Fehler im Codebeispiel von TI...
Ich schnappe mir heute Abend erstmal einen PCF8574.

Viele Grüße

Frank

von stiller Beobachter (Gast)


Lesenswert?

Frank Bußmann schrieb:
> Ich schnappe mir heute Abend erstmal einen PCF8574.

Gibt es da schon neue Erkenntnisse?

von Frank B. (frank13)


Lesenswert?

Hi!

Es gibt neue Erkentnisse: Es waren weder das Programm noch der Sensor 
schuld, meine CPU hatte offensichtlich eine Hardwaremacke. Ich habe eine 
identische Austausch-CPU verwendet und jetzt geht es.
Beim MSP430 gibt es ein Bit, welches den I2C-SCK bei einem anliegenden 
ACK anhält. Und genau dieses Bit ließ sich nicht löschen.

Viele Grüße

Frank

von Tom B. (botas)


Lesenswert?

Wenn man einen kleinen Widerstand in die Leitung einbaut kann man auf 
dem Oszilloskop sehen wer sie herunter zieht. Der eine zieht dann direkt 
auf Masse, den anderen sieht man über den Spannungsteiler vom Widerstand 
und Pullup, also nur fast Masse. Manchmal hilft das bei solchen 
Problemen.

von Frank B. (frank13)


Lesenswert?

Hi!

Den Trick hatte ich auch benutzt - allerdings mit einer Diode in der 
Leitung. Hat zum Debuggen völlig ausgereicht.

Viele Grüße

Frank

von Rico (Gast)


Lesenswert?

Hallo,
ich habe mir fataler Weise auch so ein HYt221 zu gelegt ohne an die 
Folgen zu denke. Hier ist es recht ruhig geworden und daher denke ich es 
ist möglich dem Modul die richtigen Daten zu entlocken. Leider hab ich 
das auch noch nicht so wirklich hinbekommen. Die gesammte Routine von 
Messung starten und daten auslesen funktioniert zwar aber die Daten die 
ausgelesen werden sind merkwürdig. Bei einer Feuchte von 67% und einer 
Temperatur von 23°C  bekomme ich diese Hexwerte:
byte1 51h
byte2 2Ah
byte3 CFh
byte4 61h
Das würde ja follgendes bedeuten:
Feuchte:
byte1      byte2
01010001   00101010
zusammen und maskiert mit 0x3FFF
0001000100101010 = 112Ah = 4394d
Feuchte = 100*4394/16384 = 26,8...
Temperatur:
byte1      byte2
11001111   01100001
maskiert mit 0xFFFC und verschoben >>2
11001111011000 = 33D8h = 13272
Temp = 165*13272/16384-40 = 93,5...
Wie kann ich den Bytes der Reihe nach falsch einlesen?

viele Grüße rico

von Michael S. (Gast)


Lesenswert?

Hallo Rico,


> byte1      byte2
> 01010001   00101010
> zusammen und maskiert mit 0x3FFF

wenn ich die Probleme und ihre Lösung noch recht in Erinnerung habe, 
dann haben die beiden höchstwertigen Bits eine Bedeutung ....

(nämlich die, dass die Daten nicht gültig sind, weil - entweder der 
Sensor im Programmiermodus ist oder aber die Konversion noch nicht 
abgeschlossen ist - genaueres steht im Datenblatt).

Möglicherweise hast Du das Ergebnis zu früh abgeholt - oder gar kein 
Kommando zur Konversion abgeschickt ??

mfg

Michael S.

von Jürgen S. (starblue) Benutzerseite


Lesenswert?

Schaut euch mal die Datenblätter zum Honewell HumidIcon 6130 an.

von Rico (Gast)


Lesenswert?

Hallo Michael,
danke für die Antwort. Ich hatte in den letzten Wochen wenig Zeit, daher 
hat das Projekt etwas gestockt. Ich bin mir nicht sicher wo der Fehler 
liegt oder lag. Ich habe alles nochmals umprogrammiert. Jetzt 
funktioniert es herforragend. Ich kann aber nicht sagen ob ich es 
besonders kompliziert, gut oder schlecht programmiert habe.
viele Grüße Rico

von Chrstian T. (christian_trohn)


Lesenswert?

Hi, ich häng auch grad an meinem HYT 241, leider bekomme ich nicht mal 
die Kommunikation mit dem Sensor hin. Dh. ich schicke zu beginn den Hex 
Wert 0x51 an meinen Sensor, der allerdings überhaupt nicht darauf 
reagiert und ich in meiner   while(!(TWCR & (1<<TWINT)));  Schleife 
hängen bleibe. Kommentiere ich diese aus läuft zumindest der Bus weiter 
und die anderen Teilnehmer liefern mir Werte, also liegt es zu fast 100% 
an dieser Zeile. Die Frage ist jetzt, hat mein Sensor nen macken oder 
warum bekomm ich keine Rückmeldung???
Ich nutze die I2C bib von Fleury.
Grüße Christian

Edit: Ups Anhänge haben gefehlt, aber hier als Ausschnitte besser zu 
betrachten:
Der verursacher der Endlosschleife:
unsigned char i2c_start(unsigned char address)
{
    uint8_t   twst;

  // send START condition
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

  // wait until transmission completed
  while(!(TWCR & (1<<TWINT)));

  // check value of TWI Status Register. Mask prescaler bits.
  twst = TW_STATUS & 0xF8;
  if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;

  // send device address
  TWDR = address;
  TWCR = (1<<TWINT) | (1<<TWEN);

  // wail until transmission completed and ACK/NACK has been received
  while(!(TWCR & (1<<TWINT)));

  // check value of TWI Status Register. Mask prescaler bits.
  twst = TW_STATUS & 0xF8;
  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

  return 0;

}/* i2c_start */
Meine kleine Wertabfrage:
void HYT_getdata(unsigned char *FX_STR, unsigned char i)
{
  unsigned char ret;
   if(i==3)
   {
      ret = i2c_start (0x51);
    i2c_stop  ();
    for(unsigned char j=0; j<10;j++)
    _delay_ms(10);
       ret = i2c_start (0x50);
      ret = i2c_read  (ACK);
  *&FX_STR[3] = (unsigned char)ret;
       ret = i2c_read  (ACK);
  *&FX_STR[4] = (unsigned char)ret;
       ret = i2c_read  (ACK);
  *&FX_STR[5] = (unsigned char)ret;
       ret = i2c_read  (NAK);
  *&FX_STR[6] = (unsigned char)ret;
    i2c_stop  ();

  }
}

von Erik .. (erik_mit_k)


Lesenswert?

> Chrstian Trohn
> Hi, ich häng auch grad an meinem HYT 241, leider bekomme ich nicht mal
> die Kommunikation mit dem Sensor hin.

Ich habe ein ähnliches Problem mit einem Drucksensor von Hygrosens, hat 
du mittlerweile eine Verbindung zu deinem Sensor aufbauen können?

von Erik .. (erik_mit_k)


Lesenswert?

Also ich hab mein Problem gefunden. Man sollte SDA und SCL nicht 
vertauschen;-) tztztz immer das gleiche mit dem Drahtverhau. Mit der I2C 
bib von Fleury sieht das in meinem Beispiel wie folgt aus:

Datenblatt zum Drucksensor DRMOD-I2C-RV0:
http://www.produktinfo.conrad.com/datenblaetter/500000-524999/502399-da-01-de-DRUCKMODUL_I2C_DRMOD_12C_RVO.pdf
1
/*########################################################################################################################################################
2
  Title:    Test LED Driver Max6956
3
  Author:   Martin Junghans <martin.junghans@freenet.de>
4
  File:     $Id: autoversion1.c,  2008/07/04
5
  Software: AVR-GCC / Programmers Notpad 2 / Version  2.0.7
6
#########################################################################################################################################################*/
7
8
//########################################################################################################################################################
9
#include <stdlib.h>
10
#include <avr/io.h>
11
#include <avr/interrupt.h>
12
#include <avr/pgmspace.h>
13
#include "i2cmaster.h"
14
#include "util/delay.h"
15
16
17
#define DRMOD_I2C_ADD  (0x78 << 1)//Adresse linksbündig machen siehe Datenblatt DRMOD
18
19
//######################################################################################################################################################## I2C-BUS
20
//Auslesen des Druckwertes vom DRMOD
21
short I2CRead_DRMOD(uint8_t ADDR)
22
  {
23
  short return_value;
24
  
25
    i2c_start_wait(ADDR + I2C_READ);   // set device address and read mode
26
  return_value = (i2c_readAck() <<8);
27
    return_value |= i2c_readNak();                 // write command
28
    i2c_stop();                       // set stop conditon = release bus
29
  
30
  return return_value;
31
  }
32
//######################################################################################################################################################## Hauptprogramm
33
int main(void)
34
{  
35
  DDRA  = 0xff;                              // use all pins on port B for output 
36
    PORTA = 0xff;                              // (active low LED's )
37
  
38
  cli();
39
    i2c_init();
40
    sei();                               // now enable interrupt
41
  
42
  char ret;
43
  
44
//----------------------- Schleife ----------------------------------------------------------------
45
while(1)                            
46
  {  
47
//################################################################################# 
48
  ret = (char)(I2CRead_DRMOD(DRMOD_I2C_ADD));
49
  PORTA = (ret);                            // output byte on the LED's  
50
  _delay_ms(100);
51
  }
52
}

Im Nachhinein ist das mit der Adresse usw. eigentlich alles völlig klar. 
Vielleicht hilft das hier ja noch jemanden der Probleme mit den 
HYGROSENS I²C Sensoren hat...

von Dennis (Gast)


Lesenswert?

Hallo,
habe den Chip heute entdeckt. Will vielleicht endlich mal eine 
Brutmaschine damit bauen. Wie genau kann der HYT 221 denn die 
Temperatur. Brauche eine Nachkommastelle.

Grüße und schon mal Danke
Dennis

von Sven G. (sven_g)


Lesenswert?


von Robert (Gast)


Lesenswert?

Noch ein kleiner Hinweis am Rande: Durch Zufall habe ich entdeckt daß 
bereits geringe Mengen Chlor (z.B. aus Reinigungsmitteln) den Sensor 
komplett blockieren können! Zum Glück ist die Sache nach ausreichender 
Lüftung reversibel. Also mit dem Einsatz in einer Schwimmhalle wirds so 
nix :-)

Robert

von John B. (Gast)


Lesenswert?

Hallo,

kann jemand mal einen funktionieren Code hochladen?

von Sven G. (sven_g)


Lesenswert?

Das Protokoll für HYT-221 und HYT-371 sollte gleich sein. Bitte 
korrigieren, wenn ich hier falsch liege.

Dann ist hier der Teil, der Ausschliesslich den Sensor anspricht. Für 
den Atmega, muss man einfach nur einen anderen I2C Treiber nehmen (davon 
gibt es reichlich).
Die ganze Konfiguration der Adresse kann man problemlos weglassen, wenn 
nur ein Sensor verwendet wird, das macht den Code dann deutlich 
übersichtlicher.


HYT-371.c
https://bitbucket.org/tswaehn/pic-minilib/src/e098e1eedd87ea8bb71158521e989e7adf32574c/drivers/HYT_371.c?at=default


ggf. gibts natürlich auch den Rest (I2C Treiber und Co) allerdings für 
PIC (aber mit etwas Aufwand auf Atmega übertragbar):

https://bitbucket.org/tswaehn/pic-minilib/src/e098e1eedd87/drivers?at=default

Grüße

von Ben (Gast)


Lesenswert?

Hallo,

habe auch so einen schönen HYT321 und mich versucht am Beispiel von 
Erick B. zu orientieren. Bisher leider ohne erfolgt auch nur eine 
Kommunikation aufzubauen!

Leider tut er ab der while Schleife nichts mehr...

Vorab:

- Mega 32
- SCL & SDA via 4,7kOhm auf VCC
- In i2cmaster. S

#define SDA       1    // SDA Port C, Pin 1
#define SCL      0    // SCL Port C, Pin 0
#define SDA_PORT        PORTC           // SDA Port C
#define SCL_PORT        PORTC           // SCL Port C

- Programm
1
#define   F_CPU 1000000UL          // MP-Takt
2
#include   "PF/i2cmaster.h"
3
#include  <avr/io.h>
4
#include  <stdio.h>
5
#include  <stdlib.h>
6
#include   <inttypes.h>
7
#include   <avr/interrupt.h>
8
#include   <avr/wdt.h>
9
#include    <util/delay.h>
10
11
12
#define BAUD     1200UL            
13
#define UBRR_BAUD  ((F_CPU)/(16*(BAUD))-1)
14
#define HYT321  0x28 
15
16
int uart_putc(unsigned char c)
17
{
18
  while (!(UCSRA & (1<<UDRE)));
19
20
  UDR = c;
21
  return 0;
22
}
23
int uart_puti(unsigned int c)
24
{
25
  while (!(UCSRA & (1<<UDRE)));
26
27
  UDR = c;
28
  return 0;
29
}
30
int uart_puts( char* str )
31
{
32
  while( *str )
33
    uart_putc( *str++ );
34
  while (!(UCSRA & (1<<UDRE)));
35
36
  UDR = 0x0A;
37
  return 0;
38
}
39
    
40
int main(void)
41
{
42
43
  UCSRB   |= (1 << TXEN) | ( 1 << RXEN ) | ( 1 << RXCIE ) ;     
44
   UCSRC   |= ( 1 << URSEL ) | ( 1<<UCSZ1 ) | ( 1<<UCSZ0);        
45
    UBRRL  = (uint8_t) UBRR_BAUD;
46
47
  sei();   
48
  uart_puts(" Starting ");
49
  cli();
50
  i2c_init();
51
  sei();
52
  uart_puts(" Init OK ");  
53
  unsigned char ret;
54
55
  while (1)
56
  {
57
  short return_value;
58
  i2c_start_wait(HYT321+I2C_READ);     
59
  return_value = (i2c_readAck() <<8);
60
  return_value |= i2c_readAck();
61
  i2c_stop();  
62
63
  uart_puts(" Data received ");                      
64
  ret = (char) return_value;
65
  uart_putc(ret);
66
  }
67
}

von Sven G. (sven_g)


Lesenswert?

Die default Adresse ist 0x28. Diese muss im I2C Treiber dann noch ein 
bit links geshiftet werden. Bin mir nicht sicher, ob im
1
i2c_start_wait()
 der shift automatisch gemacht wird. Aber eigentlich so wie das hier 
aussieht, kann es nicht mehr automatisch geshiftet werden, da das 
read-bit ver-oder-t ist. Also muss man die Adresse vorher shiften.

Sprich man sollte statt 0x28 die Adresse 0x50 verwenden.

Oder sehe ich das falsch?

von Peter S. (peter-schubert)


Lesenswert?

Hallo Leute,

ich habe ein Atmega32 und würde gerne den HYT221 über den I2C-BUS 
betreiben. Ich habe schon selbst herumprobiert und lege mir dabei die 
Karten. Kann mir da jemand von Euch weiterhelfen oder hat sogar schon 
ein fertiges Programm  ( in C geschrieben ) ?
Ihr würdet mir damit echt weiter helfen, weil es für mich sehr wichtig 
und dringend ist.
Vielen Dank im Voraus

M.f.G Peter Schubert

von Erik .. (erik_mit_k)


Lesenswert?

Hallo,
schon mal das Beispiel von Ben weiter oben getestet?

Jedoch mit der folgenden Adresse:
1
#define HYT321  (0x28 << 1)//Adresse linksbündig machen

von Voggi (Gast)


Lesenswert?

hab mir die HYT_I2C_Beispiele.zip geladen Beispiel funktioniert gut mit 
Arduino (hab das Teil jetzt 36 Std :-)), nur leider verändern sich die 
Werte nicht. Dann vorm auslesen der Werte 0xA0 an den HYT227 gesendet 
und siehe da nun tut es was es soll.

  Wire.beginTransmission(adress);
  Wire.write(160);
  Wire.endTransmission();

von Ferdinand K. (foerdi)


Angehängte Dateien:

Lesenswert?

Die Sensoren HYT-131, HYT-221 und HYT-271 sowie das Modell HYT-221 von 
IST scheinen alle auf dem gleichen Die zu basieren. Der kommt aus 
Dresden von ZMDI: http://www.zmdi.com/zssc3122 (Datenblatt im Anhang). 
Bisher ist das aber nur eine Vermutung.
Bei Gelegenheit werde ich mal testen ob ich mit Hilfe der Angaben im 
Datenblatt die Slave-Adresse von einem HYT-131 ändern kann.

Quelle: 
http://www.raspberrypi.org/phpBB3/viewtopic.php?t=31183&p=306104#p306104

von Fuggi (Gast)


Lesenswert?

Voggi schrieb:
> funktioniert gut mit Arduino (hab das Teil jetzt 36 Std :-)),
> nur leider verändern sich die Werte nicht.

Das würde die Arduinos samt ihren Besitzern in den Overflow bringen.

von tswaehn (Gast)


Lesenswert?

Ja sicher kann man die Adresse ändern. Man muss dazu nach Power-On des 
Sensors innerhalb von 10msek Zeitfenster in den Kommando Modus wechseln 
und schreibt dann einfach die gewünschte Config, unter anderem die neue 
Adresse. Dies ist ziemlich tricky und funktioniert bei mir nur mit 
Hotplug und auch nicht bei jedem Anlauf. Man bräuchte hier eine 
schaltbare Betriebsspannung für den Sensor.

Funktionierenden Code, um die Adresse des HYT371 zu ändern gibt es hier:

https://bitbucket.org/tswaehn/pic-minilib/src/1471d001ac214a583129d50c183adf2411ccc076/drivers/HYT_371.c?at=default

(funktioniert auch mit HYT221)

von Ferdinand K. (foerdi)


Angehängte Dateien:

Lesenswert?

Wie erwartet ist das Ändern der I2C Adresse möglich. Mit der angehängten 
Arduino Sketch funktioniert das auch sehr zuverlässig. Die bisherige 
(default 0x28) und neue Adresse werden über defines eingestellt. Dann 
nur noch auf den Arduino laden, den Seriellen Monitor starten und ein 
beliebiges Zeichen senden.

Aber Vorsicht: wenn das Ändern der Adresse schief läuft, kann der Sensor 
evtl. nicht mehr gefunden werden. Ein Durchlauf aller I2C Adressen hilft 
den Sensor wieder zu finden.

Der Code aktiviert auch das Comm_locked Flag im Konfigurations-Register 
ZMDI_Config. Dadurch reagiert der Sensor nur noch auf seine I2C-Adresse. 
Bei dem Sensor mit dem ich den Code getestet hatte war dieses Flag 
(herstellerseitig) deaktiviert. Das macht natürlich keinen Sinn wenn man 
mehrere Sensoren betreiben will.

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.