PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 2 Stück LM75 an einem Controller (I2C-Bus) (GELÖST)



HPM
05.04.2010, 17:43
Hallo Forumler,

ich hab hier ein kleines Verständnisproblem!

Ich will eine Pumpe nach 2 verschiedenen Temp- Kriterien steuern. Dazu will ich 2 Temp.-fühler (LM75) an einer I2C auslesen. Ich hab nun schon mehrmals im Forum gelesen und auch RN-Wissen gequält, bin aber immer noch nicht so richtig hinter die Funktion der Ansteuerung gestiegen, wenn mann mehrere Geräte an einem Bus betreibt.

Hier mal mein vorbereiteter Code, der allerdings genau in dem Tempfühler SUP (ganz unten) nicht ausprogrammiert ist.

Kann mir da jemand mit größerer Erfahrung in den Dingen weiter helfen?



'-------------------------------------------------------------------------------
' Controller Grundeinstellung
'-------------------------------------------------------------------------------
$regfile = "m8def.dat" 'Prozessor MEGA8
$crystal = 1000000 'int. 1MHz-Takt



'-------------------------------------------------------------------------------
' Display Grundeinstellung
'-------------------------------------------------------------------------------
Config Lcd = 16 * 2 '16Zeichen 2Zeilen
Config Lcdbus = 4 '4 bit mode
Config Lcdmode = Port
Config Lcdpin = Pin , Rs = Portd.0 , E = Portd.1 , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7
'Mega8 Anschlüsse Bein 2 Bein 3 Bein 6 Bein 11 Bein 12 Bein 13
'Displayanschluss Bein 6 Bein 4 Bein 11 Bein 12 Bein 13 Bein 14
'Displayanschluss (Rest) Bein 1 = GND Bein 2 = +5V Bein 3 = Kontrast



'-------------------------------------------------------------------------------
' Temperaturerfassung LM75 Grundeinstellung
'-------------------------------------------------------------------------------
Declare Sub Tempfuehler()

Const Lm75slavewrite = &H90
Const Lm75slaveread = &H91
Dim Lm75high As Byte
Dim Lm75low As Byte

Dim Wasser As Byte
Dim Luft As Byte
Dim Tempvar As Byte

Config Sda = Portc.4
Config Scl = Portc.5



'-------------------------------------------------------------------------------
' Eingänge, Ausgänge, Allgemeine Variablen
'-------------------------------------------------------------------------------

Config Pinb.1 = Input ' Pumpe Hand EIN
Config Pinb.2 = Output ' Pumpe Ausgang

Portb = &B11111111 ' alle PullUP ein

Portb.2 = 1 ' 1= Pumpe Aus

'************************************************* ******************************
'************************************************* ******************************
'* *
'* Hauptprogramm *
'* *
'************************************************* ******************************
'************************************************* ******************************

Do

Hand:
If Pinb.1 = 0 Then ' 0 = Schalter Ein
Portb.2 = 0 ' 0= Pumpe Ein
Locate 1 , 1
Lcd "! Hand ! "
Locate 2 , 1
Lcd "! Hand ! "
Goto Hand
End If

'-------------------------------------------------------------------------------


Call Tempfuehler()


'-------------------------------------------------------------------------------
' Display
'-------------------------------------------------------------------------------

Cls

Deflcdchar Print , 12 , 18 , 18 , 12 , 32 , 32 , 32 , 32 ' °=Grad-Zeichen

Locate 1 , 1
Lcd "Wasser="
Locate 1 , 9
Lcd Wasser
Locate 1 , 15
Lcd Chr(0) ; "C"

Locate 2 , 1
Lcd " Luft="
Locate 2 , 9
Lcd Luft
Locate 2 , 15
Lcd Chr(0) ; "C"

'-------------------------------------------------------------------------------
' Steuerung
'-------------------------------------------------------------------------------

'Steuerung, wenn Wasser zu kalt
Tempvar = Luft - 2
If Wasser < 22 And Wasser < Tempvar Then
Goto Pumpe_ein
End If

'Steuerung, wenn Wasser zu warm
Tempvar = Luft + 2
If Wasser >= 25 And Wasser > Tempvar Then
Goto Pumpe_ein
End If

Portb.2 = 1 ' 1= Pumpe AUS
Goto Endesteuerung

Pumpe_ein:
Portb.2 = 0 ' 0= Pumpe EIN

Endesteuerung:

Loop

End

'*************** ENDE HauptProgramm ********************************************




'************************************************* ******************************
'* *
'* Unterprogramme und Interrupt Routinen *
'* *
'************************************************* ******************************



'-------------------------------------------------------------------------------
' Sub LM75-Temperaturfühler
'-------------------------------------------------------------------------------
Sub Tempfuehler()
'***** Temperaturfühler 1 *****
I2cinit
I2cstart
I2cwbyte Lm75slaveread
I2crbyte Lm75high , Ack
I2crbyte Lm75low , Nack
I2cstop
If Lm75high > 127 Then
Wasser = Lm75high And 127
Wasser = Not Wasser
Incr Wasser
Else
Wasser = Lm75high '+/- Wert 'Korr. falsche Anzeige
End If

'***** Temperaturfühler 2 *****

I2cinit
I2cstart
I2cwbyte Lm75slaveread
I2crbyte Lm75high , Ack
I2crbyte Lm75low , Nack
I2cstop
If Lm75high > 127 Then
Luft = Lm75high And 127
Luft = Not Luft
Incr Luft
Else
Luft = Lm75high '+/- Wert 'Korr. falsche Anzeige
End If

'*******************************

Wait 5

End Sub
'-------------------------------------------------------------------------------

Vitis
05.04.2010, 23:24
aaaalso ...

ein Bus hat die Funktion mehrere Peripheriebausteine über die gleichen Leitungen
zu betrieben, sprich zu lesen und zu schreiben i.d.R..
Busse gibt es viele, serielle sind oft entweder der I2C, der auch als TWI bezeichnet wird
oder SPI.
TWI / I2C hat den Vorteil, dass nur zwei Leitungen benötigt werden,
bei SPI brauchts minimum 3, mit Chip Select 4 Verbindungen.
Dafür braucht am TWI im Gegensatz zu SPI jeder Busteilnehmer eine
bestimmte Adresse,
da ja alle Busteilnehmer die selben Kommandos erhalten.
Oft haben die Bausteine noch eine Möglichkeit verschiedene Adressen zugewiesen
zu bekommen, meist indem man Pins auf GND oder VSS legt.
Zusätzlich wird in der Adresse noch kodiert, ob ein Schreib- oder Lesezugriff erfolgt,
meist über das letzte Bit der Adresse.

Und im Übrigen ... Bei Codes mit GOTO lese ich mich gar nicht erst ein ... Spaghetti gibts
nur auf dem Teller :)

HPM
06.04.2010, 20:07
Hallo Vitis,

vielen Dank, für die ausführliche Abhandlung über Bus- Systeme.

StevieL
08.04.2010, 18:18
Hallo Peter,

ich mag GOTO im Code auch nicht, das ist aber ein anderes Thema.

Du musst auf jeden Fall die Sensoren mit unterschiedlichen Adressen ausstatten.

Const Lm75slavewrite = &H90
Const Lm75slaveread = &H91

reicht nicht. Du musst auch noch Lm75slave2write oder so ähnlich für den zweiten Chip deklarieren und diese Adresse(n) dann im Codeteil für den zweiten Sensor verwenden. Am Chip musst du die Adresse dann natürlich auch noch hardwaremäßig einstellen.

Beim Abfragen mehrerer Sensoren würde ich übrigens eine Funktion verwenden, die die Basisadresse des Sensors als Parameter übergibt und die Temperatur als Ergebnis zurückliefert (Declare Function LM75_gettemp(byval Device As Byte) As Single)

HPM
10.04.2010, 18:39
Hallo StevieL,

vielen Dank, für die Infos!
Genau das war der Anstoß, hab das Problem gelöst.
Seltsamerweise hatte ich die beiden LM75 für den Test ohne Schutzkondensatoren (100nF) betrieben. Da hat sich ein seltsamer Drift ergeben und die Anzeige war ständig unruhig.

Jetzt funktioniert aber meine Schaltung tadellos!

Bei den Recherchen ist mir jetzt aber aufgefallen, dass die LM75 an max. 1m Kabellänge betrieben werden sollen. Ich habe aber den Einen bei ca. 1m und den Anderen bei ca. 2m.

Wenn es nicht funbktioniert muss ich dann wohl auf 1wire umsteigen und dann fängt die Sache von vorn an ;-)

Das mit der Funktion hört sich interessant an. Allerdings bin ich diesbezüglich noch nicht so sattelfest, deswegen auch GOTO :-)

Danke vielmals und noch gutes Gelingen bei Deinen Projekten.