PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : IIC-Temp.-sensor DS1631 Ausleseproblem



Imrahil
25.09.2008, 01:00
Vor einem halben Jahr habe ich eine C-Control I Station M2.0 erworben und dazu 3 Temperatursensoren für den IIC Bus um eine Heizungssteuerung zu realisieren.
Sensor 1 ist unverändert, Addresse 158(+1)
Sensor 2 ist auf ad0 auf ground gebrückt, Addresse 156(+1)
Sensor 3 ist auf ad1 auf ground gebrückt, Addresse 154(+1)
Sensor 1 und 2 waren seitdem ohne Pause in Betrieb und verrichten ihren Dienst tadellos.
Vor kurzem wollte ich jetzt neben der Vorlauftemperatur (Sensor 1) und der Boilertemperatur (Sensor 2) noch die Heizkesseltemperatur mit Sensor 3 ermitteln.
Als ich diesen angeschlossen habe und ein entsprechendes Programm geladen habe das mir einfach nur alle drei Werte immer wieder ausliest und ausgibt kam es zu Fehlern.
Der Wert der Sensoren 1 und 3 wurde 0 oder nahm andere fixe Werte an.
Sensor 2 tickerte ohne Probleme weiter.
Verwendeter Code:
DS1631_Generic.bas

'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIII
'III BASIC++ DEMO ZUM BASIC-COMPUTER UNIT M 1.2/2.0 IIIII
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIII
'--------------------------------------------------------------------
' Beispiel zum BASIC-COMPUTER mit dem Programmer/Application-Board
'--------------------------------------------------------------------
' LIBRARY: COMMON DS1631 CONTROL ROUTINES
'
'---------------------------------------------------------------------
'DS1631RESET(ADDR as byte) RESET
'DS1631CONVERT(ADDR as byte) START CONVERSION
'DS1631GET_STATUS(ADDR as byte) READ STATUS REGISTER,RETURN BYTE
'DS1631SET_STATUS(ADDR as byte,DATA as byte) WRITE STATUS REGISTER
'DS1631GET_TEMP(ADDR as byte) RETURN WORD WITH TEMP
'-------------------------------------------------------------------

'--------------------------
'--- DS1631 COMMANDS ------
'--------------------------
const CONVERT=51h
const STOP_CONVERT=22h
const READ_TEMP=AAh
const CONF=ACh
const RESET=54h

'-----------------------------------------------------
'------------------ DS1631 RESET ------------------
'-----------------------------------------------------
FUNCTION DS1631RESET(ADDR as byte)
IIC.INIT
IIC.START
IIC.SEND ADDR
IIC.SEND RESET
IIC.STOP
IIC.OFF
END FUNCTION
'-----------------------------------------------------
'------------------ DS1631 CONVERT ----------------
'-----------------------------------------------------
FUNCTION DS1631CONVERT(ADDR as byte)
IIC.INIT
IIC.START
IIC.SEND ADDR
IIC.SEND CONVERT
IIC.STOP
IIC.OFF
END FUNCTION
'-----------------------------------------------------
'----------------- GET DS1631 STATUS -----------------
'-----------------------------------------------------
FUNCTION DS1631GET_STATUS(ADDR as byte)
define DATA as byte
IIC.INIT
IIC.START
IIC.SEND ADDR
IIC.SEND CONF
IIC.STOP

IIC.START
IIC.SEND (ADDR+1)
IIC.GET DATA
IIC.STOP
IIC.OFF
RETURN DATA
END FUNCTION
'-------------------------------------------------------
'----------------- SET DS1631 STATUS -----------------
'-------------------------------------------------------
FUNCTION DS1631SET_STATUS(ADDR as byte,DATA as byte)
IIC.INIT
IIC.START
IIC.SEND ADDR
IIC.SEND CONF
IIC.SEND DATA
IIC.STOP
END FUNCTION
'-------------------------------------------------------
'----------------- WAIT DS1631 READY -----------------
'-------------------------------------------------------
FUNCTION DS1631WAIT_READY(ADDR as byte)
#WT
if (DS1631GET_STATUS(ADDR)) and 80h = 0 then goto WT
END FUNCTION
'-----------------------------------------------------
'----------------- GET DS1631 TEMP -----------------
'-----------------------------------------------------
FUNCTION DS1631GET_TEMP(ADDR as byte)
define TEMP as word
define DATA as byte

IIC.INIT
IIC.START
IIC.SEND ADDR
IIC.SEND READ_TEMP
IIC.STOP

IIC.START
IIC.SEND (ADDR+1)
IIC.GET DATA
TEMP=DATA*256
IIC.GET DATA
TEMP=TEMP+DATA
IIC.STOP
IIC.OFF
RETURN TEMP
END FUNCTION

Auslesen der Sensoren:

Function sensorenlesen()
LCD.Off
DS1631CONVERT(ADR1) 'DA-Umsetzung starten
DS1631WAIT_READY(ADR1) 'auf Bereitmeldung warten
vorlaufist=DS1631GET_TEMP(ADR1)/256 'Messwert an Variable
DS1631CONVERT(ADR2) 'DA-Umsetzung starten
DS1631WAIT_READY(ADR2) 'auf Bereitmeldung warten
brauchwasserist=DS1631GET_TEMP(ADR2)/256 'Messwert an Variable
DS1631CONVERT(ADR3) 'DA-Umsetzung starten
DS1631WAIT_READY(ADR3) 'auf Bereitmeldung warten
kesselist=DS1631GET_TEMP(ADR3)/256 'Messwert an Variable
Print ";b:" & brauchwasserist & ";v:" & vorlaufist & ";r1:" & r1 & ";r2:" & r2 & ";r3:" & r3 & ";r4:" & r4
LCD.Init switchonly
End Function
Print schickt mir über die RS232 Schnittstelle Informationen zum Zustand der C-Control Station und ihrer Relais/Sensoren. (r1-4 <=> Relais 1-4)
Mache ich eventuel einen Fehler beim Auslesen der Sensoren?
Ein Addresskonflikt fällt aus, da einzeln betrieben (also nur 1+2 oder 2+3) die Daten fehlerfrei gelesen werden (Temperaturüberprüfung mit aufgelegtem Daumen, der Wert stieg sofort an, bzw. sank nach wegnahme des Daumens umgehend wieder).
Oder ist der Bus mit 3 Sensoren überbelastet? (eine übermässige Länge der Kabel liegt nicht vor die Länge ist <3m für alle Kabel. Das Kabel zum Sensor 1 hat ca 2,5m die zu den beiden anderen jeweils ca 1m)

Als Problem kommt noch hinzu: eigentlich müssten noch mindestens 2 weitere Sensoren (Innenraum- und Aussentemperatur) dazu kommen, könnte das auch zu Problemen führen?

Gruss Imrahil

Dierk
25.09.2008, 07:29
Sollte eigentlich funktionieren, so weit ich das sehe.
Hast Du Pullup-Widerstände (4k7) an den I2C-Busleitungen (SDA/SCL) angebracht?
Ohne die kommen nämlich solche 'komischen' Ergebnisse heraus.

Imrahil
25.09.2008, 10:01
Ich weiss nicht ob das das ist was du meinst aber so weit ich herausfinden konnte sind SDA und SCL intern über 10k an +5V angeschlossen.
Jedenfalls entnehme ich das diesen Schaltplänen (http://www.spiketronics.com/downloads/G_MANUAL_BA006_STATION_A5.pdf) der Station 2.0.
(Übersicht auf Seite 4 rechts)
Wenn das nicht der Fall ist, gegen was muss ich dann einen Pullupwiderstand anbringen, und wo kann ich das anbringen?
Alle Sensoren hängen derzeit auf einer Lochplatine mit Stecksystem, so dass sie einfach dazu- und abgeschaltet werden können, kann ich einfach auf dem Hinweg zu dieser Platine (15cm) einen entsprechenden Widerstand einbauen?
Gruss Imrahil

Dierk
25.09.2008, 10:21
Ja, stimmt die Station 2 hat ja intern schon jeweils einen 10K Pullup.
Natürlich kann es sein, dass bei Deiner Kabellänge die 10K Widerstände nicht mehr reichen.
Versuch einfach mal pro Leitung (SDA/SCL) einem 4K7 Pullup Widerstand.
Einfach zwischen 5V und IIC-Busleitung am Ende des Busses einbauen. Der Widerstandswert darf aber auf keinen Fall kleiner als 1K sein, sonst gehen die Ports hops.

Imrahil
25.09.2008, 21:38
*edit*
Ich habe den Fehler zwar nicht gefunden aber nachdem ich meinen kompletten Code neu aufgebaut habe ging es wundersamerweise...
*schulterzuck*
Nevermind ;)
Bin leider noch nicht dazugekommen die Pullup-Widerstände dran zu bauen, wenn ich das gemacht hab melde ich mich wieder.
Danke aber schonmal für die Hilfe bisher!
Imrahil