Hallo!
Ich bin noch ein Anfänger auf dem Gebiet der
Mikrocontrollerprogrammierung und bin momentan dabei, ein
Datenloggersystem zu programmieren, das Temperaturdaten über den Sensor
DS1621 über eine TWI/I²C-Leitung empfängt und dann via I²C diese Daten
auf einem Slave EEPROM (Atmel 24C64) abspeichert. Koordiniert werden
diese Aktionen vom Master IC Atmel ATmega8.
Die I²C-Schnittstellen zum EEPROM ließen sich bisher einwandfrei
programmieren, nun aber habe ich Probleme mit der Ansteuerung des
Temperatursensors, in dessen Datenblatt ich mich sehr schlecht
zurechtfinde.
Ich programmiere in Assembler (Entwicklungsumgebung AVR Studio) und
möchte von dem DS1621 Temperaturwerte empfangen. Dies sollte über eine
Master Receiver-Benutzung des TWI seitens meines ATmega8 funktionieren.
Dazu sende ich eine Startbedingung, und übermittle auf die TWI-Leitung
den Wunsch, schreiben zu wollen mitsamt der Adresse des
Temperatursensors auf die TWI-Leitung und warte, bis der
Temperatursensor sein ACK sendet.
Und wie geht es nun weiter? Im Datenblatt ist in der schmematischen
Grafik dazu die Übertragung eines sogenannten "Command Byte" vorgesehen,
aber ich weiß nicht, was ich denn mit diesem machen soll, bzw., was es
überhaupt bezwecken soll.
Normalerweise müsste ich doch nun lediglich eine repeated Startbedingung
senden, und dann einzeln die Temperaturwerte empfangen können, um
schließlich mit einer NACK-Übertragung und einer Stop-Bedingung zu
enden.
Kann mir jemand eventuell freundlicherweise erklären, wie ich die für
Ansteuerung des Sensors nun schrittweise vorgehen muss, um den vom IC
aktuell gemessenen Temperaturwert zu erhalten?
Besten Dank im Vorraus!
R.M. schrieb:> Besten Dank im Vorraus!Beitrag melden
Zum Glück gibt es hier im Forum schon 191 Threads zum DS1621. Ohne die
jetzt im einzelnen alle durchgelesen zu haben, werden da wohl
ausreichend viele funktionsfähige Code-Beispiele dabei sein.
Ich habe allerdings noch nirgendwo etwas über dieses mysteriöse "Command
Byte" gelesen. Es geht mir auch weniger um den Code, sondern mehr um
eine allgemeine Anleitung, wie ich nun weiter vorzugehen habe.
Im Datenblatt stehen die Kommando-Bytes. Also wo ist das Problem?
Das ist hier im Forum sogar verlinkt. Scrollst du runter, findest du den
Abschnitt "Command Set". Auch der Ablauf der I2C Kommunikation im Bezug
auf diese Kommandos ist da haarklein beschrieben.
Man muss schon senil sein um das nicht zu finden und dafür einen Thread
aufzumachen.
gruß cyblord
R.M. schrieb:> Ist damit vielleicht eventuell das Configuration/Status Register gemeint> (vgl. Data Sheet, p. 5) ?
Schau doch mal auf Seite 10.
Was hat das Config bzw. Statsu register damit zu tun? Dir gehts doch um
die Befehle. Lies doch einfach mal das Datenblatt der Reihe nach durch?
Was meinst du für wen das Ding geschrieben wurde? Für alle außer dich,
damit die das lesen und dir das dann erzählen können was drinnsteht?
Seite 10: Dort heißt es "Command Set - Table 3". Und eine Seite darüber
werden die Kommandos beschrieben. Kannst du lesen?
Da steht:
COMMAND SET
Data and control information is read from and written to
the DS1621 in the format shown in Figure 5. To write to
the DS1621, the master will issue the slave address of
the DS1621, and the R/W bit will be set to 0. After receiving
an acknowledge, the bus master provides a command
protocol. After receiving this protocol, the DS1621
will issue an acknowledge, and then the master may
send data to the DS1621. If the DS1621 is to be read,
the master must send the command protocol as before,
and then issue a repeated START condition and the
control byte again, this time with the R/W bit set to 1 to
allow reading of the data from the DS1621. The command
set for the DS1621 as shown in Table 3 is as follows:
Da habe ich tatsächlich etwas übersehen.
Da sich dieser Sensor aber deutlich von meinen bisherigen I²C-Arbeiten
unterscheidet, habe ich noch eine Frage: Durch Setzen von Bytes
(beispielsweise 10000000 --> Read Temperature) kann ich also Aktionen
auslösen? Hat dieser Sensor dann quasi schon vordefinierte Methoden, mit
denen er arbeiten kann?
Könnte die Ansteuerung prinzipiell folgendermaßen funktionieren:
1. Startbedingung
2. Adressübermittlung --> DS1621-Adresse + Schreiben
3. Commando Register --> Start Convert T
4. Startbedingung
5. Adressübermittlung --> DS1621-Adresse + Lesen
6. Commando Register --> Temperatur lesen
7. Commando Register --> Stop Convert T
8. Stopbedingung
Noch eine Frage: Muss ich zwangsweise diese Werte "High Temp Trigger"
und "Low Temp Trigger" festlegen, und damit mit dem Ausgang T(OUT)
arbeiten?
R.M. schrieb:> Durch Setzen von Bytes> (beispielsweise 10000000 --> Read Temperature) kann ich also Aktionen> auslösen? Hat dieser Sensor dann quasi schon vordefinierte Methoden, mit> denen er arbeiten kann?
Für ein "setzen"? Du sendest ein Bytes. Wenn du ein Kommando sendest
dann führt er es aus. Das haben "Kommandos" so an sich. Das ist halt
keiner reiner Speicher wie ein EEPROm, von dem man nur Daten holt und
dahin speichert, sondern man kommuniziert halt etwas komplexer.
> Noch eine Frage: Muss ich zwangsweise diese Werte "High Temp Trigger"> und "Low Temp Trigger" festlegen, und damit mit dem Ausgang T(OUT)> arbeiten?
k.a. müsste ich das Datenblatt zu lesen. Aber ich denke nein.
> Könnte die Ansteuerung prinzipiell folgendermaßen funktionieren:
Jetzt nimm dir halt das Datenblatt und probiers aus. Jetzt hab ich schon
die Kommandos für dich gefunden, jetzt muss ich sie dir auch noch
erklären? Schick mir doch einfach dein Projekt zu dann mach ich es dir
fertig.
Aber bevor ich Temperaturen lesen kann, muss ich dem IC erst einmal
sagen, dass er beginnen soll, jene zu messen, oder?
Außerdem heißt es im Datenblatt:
// [...] the bus master provides a command
// protocol. After receiving this protocol, the DS1621
// will issue an acknowledge, and then the master may
// send data to the DS1621. [...]
Muss ich dieses Protokoll auslesen?
Ich habe den Code nun implementiert. Der Temperatur IC liefert aber
Temperturwerte zwischen 74 und 111 Grad Celsius (?) (bei Fahrenheit
würde es ja noch Sinn machen). Ist das normal? Woher weiß ich, ob das
nun °C oder °F sind?
Es ist nämlich relativ heiß gewesen, von dem her würden
111°C = 43.9°C
schon Sinn machen, genau wie im Schatten
74°F = 23.3°C.
R.M. schrieb:> Ich habe den Code nun implementiert. Der Temperatur IC liefert aber> Temperturwerte zwischen 74 und 111 Grad Celsius (?) (bei Fahrenheit> würde es ja noch Sinn machen). Ist das normal? Woher weiß ich, ob das> nun °C oder °F sind?
Dazu guckst du am besten in das Datenblatt und in deine Ausgaberoutine.
Anhand der Tabelle 2 (Temperature/Data relationship) sollte es doch
möglich sein, den (uns unbekannten) Digital Output deines Sensors auf
der Celsiusskala einzuordnen. Dann kommt es auf deine Software drauf an,
ob der Hex-Wert richtig umgerechnet wird und auf welche Temperaturskala
die Ausgabe skaliert wird.
Wenn ich die Tabelle im Datenblatt hernehme (was ich natürlich getan
habe), ist da aber ein relativ einfaches Schema zu erkennen: Das erste
Bit des High-Ordered-Byte dient dem Vorzeichen, und der Binärwert danach
ist umgerechnet in das Dezimalsystem dann einfach der Temperaturwert.
Deswegen weiß ich jetzt auch einfach nicht, warum das theoretisch Grad
Fahrenheit sein könnten - es würde nur Sinn machen.
R.M. schrieb:> Das erste Bit des High-Ordered-Byte dient dem Vorzeichen, und der> Binärwert danach ist umgerechnet in das Dezimalsystem dann einfach der> Temperaturwert.
Nicht ganz. Das MSB ist die Temperatur in Grad Celsius als
Zweierkomplement. Vom LSB wird nur das oberste Bit benutzt und hat ein
Gewicht von 1/2 Grad-C
Noch eine Frage, da ich vielleicht einen anderen Fehler gemacht habe:
Wenn ich z.B. die Operation "Read Temperature" durchführen will, welchen
Wert muss ich dann der Datenleitung für das Command Byte übergeben? Und
was bedeutet das "AAh" dahinter in Klammern?
R.M. schrieb:> Wenn ich z.B. die Operation "Read Temperature" durchführen will, welchen> Wert muss ich dann der Datenleitung für das Command Byte übergeben? Und> was bedeutet das "AAh" dahinter in Klammern?
"AAh" ist das Command Byte für das Lesen des Temperaturregisters
Und was heißt das? Ich kann mit dem Begriff "AAh" gerade nichts
anfangen. Was muss ich denn machen, um das dem Ic mitzuteilen? Ich muss
ihm ja in einem Byte mitteilen: Read temperature!
Ich hatte es aktuell so gelöst, dass ich via Datenleitung das so
übergeben habe:
0b10000000 --> Read Temperature
0b01000000 --> Read Counter
0b00100000 --> Read Slope
u.s.w.
Aber ich glaube, das geht nicht so ...
Wie geht es dann?
Ich habe nun den Algorithmus implementiert, aber es scheint, als ob die
Temperatur, egal ob ich jetzt einen Föhn über den Sensor halte oder er
im kühlen Schatten steht, konstant 15 Grad Celsius ist.
Mein Algorithmus sieht wie folgt aus:
1. Startbedingung
2. Übermitteln der Adresse des DS1621 + Write Operation
3. Datenübertragung: Kommando "Start Convert T"
4. Repeated Startbedingung
5. Übermitteln der Adresse des DS1621 + Write Operation
6. Datenübertragung: Kommando "Access TH"
7. Repeated Startbedingung
8. Übermitteln der Adresse des DS1621 + Read Operation
9. Auslesen des TWI-Datenregisters
10. Senden eines NACK
11. Repeated Startbedingung
12. Übermitteln der Adresse des DS1621 + Write Operation
13. Datenübertragung: Kommando "Stop Convert T"
14. Stopbedingung
Damit dürfte ich doch die ganzzahligen Temperaturwerte empfangen. Die
I2C-Library dürfte eigentlich keine Fehler enthalten, denn die
Kommunikation mit dem externen EEPROM funktioniert einwandfrei.
Was könnte da schief gelaufen sein?
Wieso sendet der DS1621 stets einen konstanten Wert von 15 beiu o.g.
Programmtext? Der Wert steht dann immer im Register "temp_input", auch
wenn ich es unmittelbar davor "cleare".
Warum läßt du die Messung nicht erstmal durchlaufen (1SHOT = "0").
Evtl. liest du im Moment das Temperaturregister, bevor die Messung
beendet ist (DONE="1")
Meinst du also, ich sollte ein Commando Byte losschicken, dass mir
solange den Wert "DONE" aus dem Configuration-Register zurückgibt, bis
dieser 1 ist, und dann erst auslesen?
R.M. schrieb:> Meinst du also, ich sollte ein Commando Byte losschicken, dass mir> solange den Wert "DONE" aus dem Configuration-Register zurückgibt, bis> dieser 1 ist, und dann erst auslesen?
Oder warte einfach einige Sekunden. Zum testen reicht das. Später dann
auf "DONE" pollen. Steht im Datenblatt nichts zur Dauer des
Messvorgangs?
Was meinst du mit "durchlaufen"? Wenn ich das Bit in 1SHOT auf 0 setze,
dann würde das ja eine ständige Messung bedeuten und DONE würde nie 1
werden, oder?
R.M. schrieb:> Was meinst du mit "durchlaufen"? Wenn ich das Bit in 1SHOT auf 0 setze,> dann würde das ja eine ständige Messung bedeuten und DONE würde nie 1> werden, oder?
Eine Messung "durchlaufen" lassen ist doch ein deutscher Satz. Was gibts
denn da nicht zu verstehen? Du startest die Messung, lässt sie in Ruhe
bis sie fertig ist. Und dann erst liest du das Ergebniss aus. Ist doch
auch irgendwie von Logik getragen dieser Vorschlag oder? Darf man fragen
wie alt du bist? Dann könnte man die Antworten eventuell besser
anpassen.
Im Datenblatt heißt es dazu:
One Shot Mode. If 1SHOT is “1”, the DS1621
will perform one temperature conversion
upon reception of the Start Convert T protocol.
If 1SHOT is “0”, the DS1621 will continuously
perform temperature conversions. This
bit is nonvolatile.
Das heißt, 1SHOT auf 0 zu setzen würde bedeuten, dass die Messung
STÄNDIG vonstatten geht, falls ich das richtig verstande habe.
R.M. schrieb:> Was meinst du mit "durchlaufen"? Wenn ich das Bit in 1SHOT auf 0 setze,> dann würde das ja eine ständige Messung bedeuten und DONE würde nie 1> werden, oder?Beitrag melden Bearbeiten Löschen
Schon, aber du müßtest nur einmal starten und der Sensor würde
selbständig immer einen aktuellen Wert im Temperaturregister ablegen. Du
kannst das letzte Wandlungsergebnis dann jederzeit mit "Read
Temperature" abholen.
Der Wandler braucht 750ms für die Wandlung und du gibt ihm im Moment
keine Zeit dafür, sondern versuchst schon nach ein paar µs zu lesen.
Also der obige Programmtext funktioniert gar nicht. Und auch, wenn ich
simple Warteschleifen der Länge ~1 Sekunde in den Programmtext einbaue,
ändert das leider nichts an der Ausgabe "15".
Was kann ich da falsch gemacht haben?