Forum: Mikrocontroller und Digitale Elektronik Sensor über I²C-Bus auslesen - Bascom-Code


von R. W. (riwen)


Lesenswert?

Hi, ich versuche gerade den Sensor HYT-221 über den I²C-Bus an meinem Rn
Control V1.4 auszulesen. Der Sensor ermöglicht Temperatur- und 
Luftfeuchtigkeitsmessung. Ich habe mir ohne Erfahrung aus bisherigen 
Threads folgenden Bascom-Code zusammengebastelt. Allerdings gibt er mir 
immer nur die Zahl 255 raus. Kann  mir jemand bitte weiterhelfen? 
Danke!!!
1
$regfile = "m32def.dat"
2
$framesize = 32
3
$swstack = 32
4
$hwstack = 64
5
                                                             'Quarzfrequenz
6
$crystal = 16000000                                         'Baud-Rate
7
$baud = 9600                                                'Ports für IIC-Bus
8
Config Scl = Portc.0
9
Config Sda = Portc.1
10
                                                             'Deklaration der Variablen
11
12
Config Adc = Single , Prescaler = Auto                      'Für Tastenabfrage und Spannungsmessung
13
14
Start Adc
15
Sound Portd.7 , 400 , 450                                   'BEEP
16
Sound Portd.7 , 200 , 700                                   'BEEP
17
Sound Portd.7 , 400 , 450                                   'BEEP
18
19
Config Portc = Output
20
21
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0       'Konfiguration COM-Port 1
22
23
Open "com1:" For Binary As #1                               'COM1 aktivieren.
24
25
Declare Sub Showtemperatur()
26
27
Const Hyt221write = &H90
28
Const Hyt221read = &H91
29
Dim Hyt221high As Byte
30
Dim Hyt221low As Byte
31
Dim Temperatur As Integer
32
Dim Nachkommastelle As String * 2
33
34
35
I2cinit
36
37
Start:
38
     Showtemperatur
39
     Wait 2
40
     Goto Start
41
42
Do
43
44
Sub Showtemperatur()
45
   I2cstart
46
   I2cwbyte Hyt221read
47
   I2crbyte Hyt221high , Ack
48
   I2crbyte Hyt221low , Nack
49
   I2cstop
50
51
52
   Temperatur = Hyt221high
53
54
   Print Temperatur
55
End Sub
56
57
Loop

von spess53 (Gast)


Lesenswert?

Hi

>Const Hyt221write = &H90
>Const Hyt221read = &H91

Wo hast du die Adressen her? Lt. Datenblatt hat der die Adresse 0x28. 
Mit dem R/W-Bit ergibt das die Adressen 0x50 für Schreiben und 0x51 für 
Lesen.

Diese Adresse findet sich auch in der Protokollbeschreibung:

http://www.produktinfo.conrad.com/datenblaetter/500000-524999/505671-da-01-en-I2C_Schnittstellenprotokoll.pdf

MfG Spess

von R. W. (riwen)


Lesenswert?

Hi Spess,

danke erstmal für deine Antwort! Du hast recht, die habe ich vergessen 
zu ändern. Habe gerade schon gedacht, das Problem wäre gelöst, ist es 
aber nicht. LabView gibt mir immernoch "255" raus. An LabView sollte es 
nicht liegen-ich habe schon andere Sachen damit ausgelesen.

von spess53 (Gast)


Lesenswert?

Hi

>Sub Showtemperatur()
>   I2cstart
>   I2cwbyte Hyt221read
>   I2crbyte Hyt221high , Ack
>   I2crbyte Hyt221low , Nack
>   I2cstop

>   Temperatur = Hyt221high

Das passt auch nicht. Beim Lesen repräsentieren die ersten beiden Bytes 
die Feuchtigkeit. Das von dir nicht gelesene dritte Byte ist der 
Temperaturwert.

MfG Spess

von R. W. (riwen)


Lesenswert?

Du meinst das Temperatur = Hyt221high?
Ich habe das erstmal so eingefügt, weil ich überhaupt einen Wert 
rausbekommen möchte. Ich habe mittlerweile durch die Änderung der 
Adressen doch einen anderen Wert: 81 - der bleibt allerdings auch 
konstant. Kannst Du mir einen kurzen Lösungsvorschlag unterbreiten?

von spess53 (Gast)


Lesenswert?

Hi

>Du meinst das Temperatur = Hyt221high?

Nein. Hyt221high ist Cap.Data[13:8].

>Ich habe das erstmal so eingefügt, weil ich überhaupt einen Wert
>rausbekommen möchte.

Also hast du nicht wirklich die Temperatur gemeint?

>Ich habe mittlerweile durch die Änderung der
>Adressen doch einen anderen Wert: 81 - der bleibt allerdings auch
>konstant.

Wenn du einen jungfräulichen Sensor hast liegen die Adressen fest auf 
0x50/0x51.

>Kannst Du mir einen kurzen Lösungsvorschlag unterbreiten?

Auf jeden Fall würde ich mir erst mal das Low-Byte ansehen. Dort ändert 
sich mit Sicherheit eher etwas als auf dem High-Byte.

MfG Spess

von R. W. (riwen)


Lesenswert?

Ja die Variable hieß hier gerade nur Temperatur, damit ich keine neue 
deklarieren muss. Ich bekomme für das LowByte den konstanten Wert 233. 
Es ändert sich nichts.
Mir fehlt auch etwas die Ahnung, wie die Werte aussehen sollen die er 
mir zurück gibt - wie man Temperatur von der Feuchtigkeit trennt.
Mein erstes Ziel ist es momentan, einen Wert zu bekommen, der sich 
ändert.

von spess53 (Gast)


Lesenswert?

Hi

>Mir fehlt auch etwas die Ahnung, wie die Werte aussehen sollen die er
>mir zurück gibt

Dann rechne doch mal einen Feuchtigkeitswert in den Rohwert (rHraw) um:

rH [%] = (100 / 2^14) * rHraw

>...wie man Temperatur von der Feuchtigkeit trennt.

Dazu must du auch noch das dritte Byte lesen.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

>Mein erstes Ziel ist es momentan, einen Wert zu bekommen, der sich
>ändert.

Gerade noch mal in der obigen Protokollbeschreibung gelesen: Du must 
erst eine Messung mit einem Schreibbefehl starten bevor du gültige Werte 
auslesen kannst.

Nimm dir also die Beschreibung noch mal gründlich zur Brust.

MfG Spess

von R. W. (riwen)


Lesenswert?

Hi Spess,

in dieser Form? Das dritte Byte hab ich jetzt so deklariert:

Dim Hyt221_3byte As Byte

I2cstart
   I2cwbyte Hyt221write
   I2cwbyte Hyt221read
   I2crbyte Hyt221high , Ack
   I2crbyte Hyt221low , Ack
   I2crbyte Hyt221_3byte , Nack
I2cstop

Mir fehlt leider die Erfahrung, um mit den im Datasheet beschriebenen 
Vorgängen richtig umzugehen. Ich bin es mehrfach durchgegangen. Die 
ersten beiden Bytes geben die Feuchtigkeit wieder und das dritte die 
Temperatur, richtig? Für das dritte Byte bekomme ich wieder 255. Alle 
Werte sonst sind unverändert und bleiben konstant. Kannst Du mir sagen, 
wie ich den anfänglichen Schreibbefehl, den Du meintest ausführe und das 
dritte Byte richtig auslese?

von R. W. (riwen)


Lesenswert?

...ich muss dazu sagen. Ich bin eigentlich in der Biologie tätig- 
deshalb fehlt mir etwas das Knowhow zu so etwas. Für jede Hilfe bin ich 
sehr dankbar.

von Karl H. (kbuchegg)


Lesenswert?

Du musst aber schon den Write irgendwann mal beenden.
Der Sensor verwechselt sonst dein nächstes Byte, welches eigentlich als 
Reda Kommando gedacht war mit Daten, die er (wo auch immer hin) 
schreiben soll.

I2cstart
   I2cwbyte Hyt221write
I2cstop
I2cstart
   I2cwbyte Hyt221read
   I2crbyte Hyt221high , Ack
   I2crbyte Hyt221low , Ack
   I2crbyte Hyt221_3byte , Nack
I2cstop


Und zwischen den Write und dem Read wäre eine kleine Wartezeit 
angebracht, denn immerhin beginnt der Sensor erst mit dem Write mit 
seiner Arbeit. Und die braucht ja schliesslich auch ein bischen Zeit.

von Karl H. (kbuchegg)


Lesenswert?

R. W. schrieb:
> ...ich muss dazu sagen. Ich bin eigentlich in der Biologie tätig-
> deshalb fehlt mir etwas das Knowhow zu so etwas. Für jede Hilfe bin ich
> sehr dankbar.

Na ja. Der Hersteller hat extra eine Doku über das I2C Protokoll 
zusammengestellt

http://www.ist-ag.com/eh/ist-ag/resource.nsf/imgref/Download_AHHYT-I2C_E1.1.pdf/$FILE/AHHYT-I2C_E1.1.pdf

Da sind sogar Bilder drinn, die den Ablauf veranschaulichen. Ein bischen 
was muss man dir schon zumuten können. Denn ansonsten muss man sagen: 
lass es - es gibt genug Leute die das eben schon gelernt haben und nur 
auf Arbeit warten.

von spess53 (Gast)


Lesenswert?

Hi

>...ich muss dazu sagen. Ich bin eigentlich in der Biologie tätig-
>deshalb fehlt mir etwas das Knowhow zu so etwas. Für jede Hilfe bin ich
>sehr dankbar.

Und ich kenne weder den Sensor noch BASCOM. Falls du C wenigstens lesen 
kannst findest du hier

http://www.ist-ag.com/eh/ist-ag/en/home.nsf/contentview/~humidity-modules/

Beispiele (TWI_master) für AVRs. Habe ich aber nur mal überflogen.

Kannst du mit BASCOM eigentlich feststellen, ob das Modul bei dem 
Schreibzugriff oder nach den Lesebefehl wenigstens mit ACK antwortet?

Die obersten 2 Bit des ersten Bytes sind übrigens Statusbits:

Bit 15: CMode Bit, if 1 – element is in command mode
Bit 14: Stale bit, if 1 – no new value has been created
since the last reading.

Also sollte Bit15 auf jeden Fall 0 sein.

MfG Spess

von R. W. (riwen)


Lesenswert?

Okay Leute, danke schon einmal bis hierhin! Ihr habt mir schon viel 
weitergeholfen! Ich habe nun folgenden Code. Laut Datenblatt 
repräsentieren die ersten beiden Bytes die Feuchtigkeit und das 3. die 
Temperatur. Ich bekomme für jedes Byte Werte, die sich auch ändern. Im 
Anhang ist ein Screenshot der Ausgabewerte. Die Frage ist, wie ich die 
jetzt verarbeite. Die im Datasheet verzeichneten Formeln zur Umrechnung 
funktionieren kann ich da ja nicht einfach so anwenden - da bekomme ich 
unrealistische Werte. Ich brauche noch einen letzten Tipp für dieses 
Problem. Danke!

Do

Sub Showtemperatur()

I2cstart
   I2cwbyte Hyt221write
I2cstop

Wait 2

I2cstart
   I2cwbyte Hyt221read
   I2crbyte Hyt221high , Ack
   I2crbyte Hyt221low , Ack
   I2crbyte Hyt221_3byte , Nack
I2cstop

   Print "Byte1:   " ; Hyt221high ; "   Byte2:   " ; Hyt221low ; " 
Byte3:   " ; Hyt221_3byte


End Sub

Loop

von Karl H. (kbuchegg)


Lesenswert?

R. W. schrieb:
> Die im Datasheet verzeichneten Formeln zur Umrechnung
> funktionieren kann ich da ja nicht einfach so anwenden

doch eigentlich schon. Du musst nur wissen was du tust.

> - da bekomme ich
> unrealistische Werte.

Dann könnten zb deine Ausgangswerte falsch sein, die du vom Sensor 
bekommst.

Welche Werte kriegst du denn so?

Und PS: lies 4 Bytes aus, denn der Sonsor stellt auch 4 Bytes bereit. 2 
für die Feuchte und 2 für die Temperatur - wenn man mal im Datenblatt 
genau lesen würde. Mit 3 Bytes würde es auch gehen, dann nimmt man halt 
die unteren 6 Bit der Temperatur als 0 an.

von R. W. (riwen)


Lesenswert?

Hier die Werte:

Byte1: 31
Byte2: 109
Byte3: 96
Byte4: 72

Die Nachkommastellen - Byte 2 und 4 verändern sich natürlich stark.

von spess53 (Gast)


Lesenswert?

Hi

>Hier die Werte:

>Byte1: 31
>Byte2: 109
>Byte3: 96
>Byte4: 72

Macht 22°C und 49% rH. Sieht doch gut aus. Hast du ein anderes Gerät, 
mit dem du das überprüfen kannst?

Und entschuldige, das ich die ganze Zeit von einem Byte für die 
Temperatur geredet habe. Ich hatte mich nur an der Darstellung 
orientiert.

MfG Spess

von R. W. (riwen)


Lesenswert?

Hi Spess,
wegen letzterem - kein Ding^^ Hätte mir ja auffallen müssen. Danke!
Wie bist Du jetzt auf die Werte gekommen?? Die sehen wirklich gut aus, 
aber ich komm da nicht drauf. Du hast mit den Gleichungen aus dem 
Datenblatt gerechnet?

von Karl H. (kbuchegg)


Lesenswert?

R. W. schrieb:
> Hi Spess,
> wegen letzterem - kein Ding^^ Hätte mir ja auffallen müssen. Danke!
> Wie bist Du jetzt auf die Werte gekommen?? Die sehen wirklich gut aus,
> aber ich komm da nicht drauf. Du hast mit den Gleichungen aus dem
> Datenblatt gerechnet?

Na klar. Womit denn sonst.

Nehmen wir die Feuchtigkeit.
Die beiden Bytes sind

31 und 109.

In den 31 stecken in den ersten beiden Bits 2 Statusinformationen 
drinnen. Also schreib ich mir das mal binär auf.
Dezimal 31 ist binär 0001 1111

Was sagt das Datenblatt: die beiden linksten Bits haben die Bedeutung
höchtes Bit:  wenn 1, dann ist das Gerät im Command Mode
              (was immer das auch ist)
das Bit links davon:  wenn 1, dann ist der Wert alt.

In unserem Fall:

  0001 1111
  ||
  |+---> Wert ist aktuell
  |
  +----> kein Command Mode

soweit so gut. Wenn da 1 Bits drinn wären, dann müsste man sie vor der 
Verarbeitung der Bytes löschen und gezielt auf 0 bringen. Das Datenblatt 
sagt sogar, wie man das macht. (ok, das Datenblatt geht davon aus, dass 
zuerst die beiden Bytes zu einer 16 Bit Zahl zusammengefasst werden und 
dann die Bits gelöscht werden. Ist aber nur eine kleinere Modifikation. 
Ob zuerst löschen und dann zusammenfassen oder zuerst zusammenfassen und 
dann löschen läuft aufs gleiche raus. Lediglich die Zahlenwerte bei der 
verundung sind andere)

Dann werden die beiden Bytes zu einer 16 Bit Zahl zusammengefasst

Zahl = 31 * 256 + 109 = 8045

und in rH umgerechnet.
Die Formel im Datenblatt lautet  (100/2^14) * Zahl

2 hoch 14, das ist eine andere Schreibweise für 16384 und um nicht in 
Rechenprobleme zu laufen, stell ich die Formel mal ein bischen um (denn 
100/16384 ist als Ganzzahldivision gerechnet eine glatte 0)

Ich rechne lieber   ( 100 * Zahl ) / 16384

100 * 8045 = 804500    (ausfpassen, dass überschreitet den 16 Bit 
Wertebereich!)

und 804500 / 16384 = 49.10

Die Kommastellen interessieren uns nicht weiter (die sind physikalisch 
wahrscheinlich sowieso falsch). Aber das Ergebnis lautet 49%

Soll ich dir die Temperatur auch vorrechnen, oder schaffst du das jetzt 
ausnahmsweise mal alleine? Aber aufpassen: die Bit-Aufteilung in den 
beiden Bytes ist eine andere - wie im Datenblatt ein paar mal erwähnt 
und auch in der Zeichnung eingetragen ist!

von spess53 (Gast)


Lesenswert?

Hi

>Du hast mit den Gleichungen aus dem Datenblatt gerechnet?

Ja. Du must erstmal aus Byte1 und 2 bzw. Byte3 und 4 jeweils einen 
14-Bit-Wert machen:

für Feuchte: (Byte1*256+Byte2) and &H3FFF

das 'and &H3FFF' ist notwendig um die beiden Statusbits (Bit15:14) 
auszublenden.

für Temperatur: (Byte3*256+Byte4)/4

Der Wert für die Temperatur wird linksbündig übertragen und muss deshalb 
um 2 Bit nach rechts geschoben werden (/4).

Und die Werte brauchst du dann nur noch in Formeln auf S.3 der 
Protokollbeschreibung einsetzen. Fertig.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

Ups, Karl-Heinz war schneller.

MfG Spess

von R. W. (riwen)


Lesenswert?

Kay. Danke! Hilft mir weiter.

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.