Moin Forum.
Soweit ich das mitbekommen habe, ist ja der DS1820 sozusagen der
Klassiker unter den digitalen Temperatursensoren. Ich gehe davon aus,
dass sich entsprechend viele mit ihm beschäftigt haben und mir bei
meinem Problem vielleicht helfen können.
Der Code ist an meinem Beitrag angeheftet.
Ich versuche einen einzelnen DS1820 der mit einer externen Versorgung
arbeitet (also kein Parisite-Power) auszulesen, für den Anfang die
ganzen 8 Bytes.
Wenn nur einer der Temperatursensoren auf dem Bus vorhanden ist, kann
man das ReadRom[33h]-Kommando verwenden um die 8 Bytes auszulesen. Das
habe ich in meinem Code versucht, doch er gibt mir nur Nullen zurück.
Was mache ich falsch?
EDIT:
Hardware-Technisch habe ich alles laut Datenblatt erledigt, die Antwort
auf den Reset-Pulse habe ich mit meinem Oszi messen können, die
Schaltung ansich funktioniert also.
Vielen Dank im Voraus!
Copy & Paste dürfte der Code schon mal nicht sein, da die
void-Prototypen so wohl nicht akzeptiert werden dürften.
Wenn Du mit dem Oszi messen kannst: Passiert denn auf dem "Bus" was
außer dem Reset-Pulse?
Richtig vergurkt scheint die Funktion char* ReadTimeSlot() zu sein:
Wiese char *?
^
Und dann return "1"?
^ ^
Wenn wirklich ein char kommen soll, dann einfache Anführungszeichen
sowie kein *
Probier statt
if((PORTD & (1 << DQ) ) == 1)
mal PIND ...
Und bei SendCommand:
WriteTimeSlot(command & (1<<i)); ergibt wohl immer 1, sofern command
nicht 0 ist ...Du schiebst an der falschen Stelle.
Und das war wohl nur der erste grobe Überflug.
Ich muß jetzt ins kühle naß.
Ja, ich habe die WriteTimeSlot() Funktion mit 0 und 1 gestestet und sie
macht was sie soll.
Das mit dem char* hat einen einfachen Grund :
Die Funktion UART_Puts() benötigt einen String, ein einzelnes
char-Zeichen ist aber kein String =)
Wie gehört das mit dem command denn richtig?
Mfg
Den Pin immer als Open Drain Pin betreiben, also nie aktiv
hochziehen (ausser phasenweise wenn parasitär betrieben)!
Programmtechnisch heisst das: PORTx.y vorneweg ein für alle Mal auf 0
setzen und danach ausschliesslich die Richtung umschalten (raus für
low/0, rein für high/1). Sonst ergeben sich Phasen, in denen der Sensor
runter und der Controller rauf zieht. Genau dies geschieht bei dir nach
dem Reset durch den "presence pulse" des Sensors.
Ich will's nicht hoffen, aber möglicherweise kann man mit einem solchen
Treiberkonflikt sogar den Sensor himmeln.
Vielen Dank!
So, hier ist die neue Version meines Codes, ich hoffe das passt jetzt
einigermaßen. Leider hat dein Beitrag das Problem noch nicht beseitigt,
aber Schlimmeres verhindert =)
Ich habe gerade eine Denkblockade:
Wie kann ich überprüfen ob ein bestimmtes Bit in einer Byte Variable
gesetzt ist?
So ist es anscheinend falsch:
Hat hier nichts mit dem Problem zu tun, aber du solltest bei der
Initialisierung des Pins ihn nicht auf Ausgang und damit auf "low"
setzen. Das sollte erst im 1W-Reset erfolgen.
Christoph A. schrieb:> Wenn nur einer der Temperatursensoren auf dem Bus vorhanden ist, kann> man das ReadRom[33h]-Kommando verwenden um die 8 Bytes auszulesen. Das> habe ich in meinem Code versucht, doch er gibt mir nur Nullen zurück.> Was mache ich falsch?
33h liest wie schon der Name sagt den 64Bit ROMCODE aus!
dein Kommando der wahl ist SkipRom [CCh], was den Vergleich der Adresse
überspringt!
dann ConverT [44h], 1s warten und dann mit [BEh] die Daten lesen
Sascha
> mal überdenken solltest wurde bereits genannt.
Ohh, ich habe anscheinend den Unterschied von PIND und PORTD nicht
kapiert =)
Aber jz habe ich ein wenig recherchiert und glaube es verstanden zu
haben :
Sascha Weber schrieb:> Christoph A. schrieb:>> Wenn nur einer der Temperatursensoren auf dem Bus vorhanden ist, kann>> man das ReadRom[33h]-Kommando verwenden um die 8 Bytes auszulesen. Das>> habe ich in meinem Code versucht, doch er gibt mir nur Nullen zurück.>> Was mache ich falsch?> 33h liest wie schon der Name sagt den 64Bit ROMCODE aus!> dein Kommando der wahl ist SkipRom [CCh], was den Vergleich der Adresse> überspringt!> dann ConverT [44h], 1s warten und dann mit [BEh] die Daten lesen>> Sascha
Okay, aber der ROM-Code wird wohl kaum aus auschließlich Nullen bestehen
=)
>>> So richtig?>> Nö. Sowas nie mit 1 vergleichen, immer nur mit 0>> Hier gibt's irgendwo in der Artikelsammlung ein Tutorial über diesen> Bitkrams.
Vielen Dank, kleiner Schlampikeitsfehler.
Aber so gehts :
1
if((PIND&(1<<DQ)))
Und endlich habe ich den ROM-Code erfolgreich auslesen können, vielen
Dank euch allen!
Jetzt ist das Temerpaturauslesen auch nicht mehr schwierig =)
Mfg
@Christoph
> Okay, aber der ROM-Code wird wohl kaum aus auschließlich Nullen bestehen> =)
sicher nicht - aber die Temperatur ist's auch nicht, und nach der
Behebung deiner Probleme mit dem Protokoll währe das wohl das nächste
gewesen
Sascha
Hmm, anscheinend war ich wohl zu vorschnell.
Wenn ich das Datenblatt richtig verstanden habe, wird die Temperatur in
den ersten zwei Bytes gespeichert. Wenn ich diese auslese, bekomme ich
lauter Einsen, -0,5 Grad Celsius wären ein Traum in dieser heißen
Sommerzeit =)
Vll könntet ihr nochmal einen Blick darauf werfen.
Vielen Dank schonmal!
Mfg
Christoph A. schrieb:> Karl heinz Buchegger schrieb:>> Das hier kennst du?>> Beitrag "DS1820, DS18B20 in C">> Jap, mir ist bewusst dass es unzählige fertige Codes für diesen> Temperatursensor gibt =)
Schon klar.
Aber du könntest mal nachsehen, was da drinnen so passiert und worin
sich der Code von dort von deinem unterscheidet.
Christoph A. schrieb:> Vll könntet ihr nochmal einen Blick darauf werfen.
Erspare dir für den Anfang die (falsche) Abfrage nach dem Ende der
Messung und warte einfach die spezifizierte Maximalzeit ab.
Ausserdem kommt vor dem Lesekommando wieder ein 1W-Reset;
The transaction sequence for accessing the DS18S20 is as follows:
* Step 1. Initialization
* Step 2. ROM Command (followed by any required data exchange)
* Step 3. DS18S20 Function Command (followed by any required data
exchange)
It is very important to follow this sequence every time the DS18S20 is
accessed, as the DS18S20 will not respond if any steps in the sequence
are missing or out of order.
Falsche Abfrage?
Anstatt der Abfrage warte ich jetzt eine Sekunde.
Aber der Fehler besteht trotzdem noch.
Könnte es möglicherweise ein defekt des DS1820 sein? Der ist bei mir
nicht gerade ordnungsgemäß gelagert worden, also ohne ESD Folie usw.
Mfg
Christoph A. schrieb:> Falsche Abfrage?
Ein "read timeslot" ist bischen mehr als die Abfrage der Leitung.
> Anstatt der Abfrage warte ich jetzt eine Sekunde.> Aber der Fehler besteht trotzdem noch.
Lies auch des Rest meines Posts.
Christoph A. schrieb:> Das mit dem char* hat einen einfachen Grund :> Die Funktion UART_Puts() benötigt einen String, ein einzelnes> char-Zeichen ist aber kein String =)
Mein Fehler, ich habe mir nur die DS1820.c angesehen.
Wie A.K. schon geschrieben hat: Step 1, Step 2, Step 3. Immer.
Also nach READ_ROM kommt ResetPulse(). Vor READ_SCRPAD auch. Nach
READ_ROM brauchst Du hingegen keines mehr. Und ein while(1) nach getaner
Abeit bringt auch nichts mehr, könntest auch return 0 machen. Oder Deine
main mit der while(1) starten und am Ende des Loops eine Sekunde warten,
somit jede Sekunde einen neuen Meßwert.
Vielen Dank =)
Du hast mir wieder mal viel geholfen.
Mir war nicht klar, dass man diese Reihenfolge selbst beim Auslesen des
Scratchpads auch berücksichtigen muss!
Die Ausgabe ist jz :
1100 1110 0000 0000
Sicher dass es ein DS18(S)20 ist, kein DS18B20?
Damit wären es etwa 6°C - ok sicherlich auch nicht korrekt.
Hast Du das mal auf dem Oszi/LA verifiziert? Kommen wirklich diese Bits
an?
Das hatte ich bei meinen 1-Wire-Slave auch gemacht um das Timing zu
überprüfen.
Der Sensor ist mein DS1820 beschriftet, ohne S oder B dazwischen.
Ja, die Daten sind verifiziert, denn wenn ich ihn mit meinen Fingern
erwärme, ändert sich das Bitmuster ( die Zahl wird größer ) und geht
dann wieder in den Ausgangswert zurück. Komischerweise ist IMMER das 7te
Bit gesetzt, ich schätze ich habe den Sensor zerschossen^^
Ohne dem 7ten Bit gesetzt würde ich auf 21 Grad kommen.
Werde mich mal um einen Ersatz bemühen =)
Mfg
Christoph A. schrieb:> Werde mich mal um einen Ersatz bemühen =)
Ehe du das tust.
Hol dir aus der Codesammlung die PeDa Software, passe sie schnell an
deine Pinbelegung an, ändere noch die Ausgabe, so dass deine vorhandenen
Ausgabekanäle benutzt werden und wenn die dann dasselbe rauskriegt wie
du - dann besorg dir Ersatz :-)
PeDa ist das Synonym für
Peter Dannegger
Von ihm stammen unzähle Softwarebeiträge hier und in der Codesammlung
zb das hier
Beitrag "DS1820, DS18B20 in C"
Hinweis: In der Codesammlung kann man auch ganz wunderbar nach DS1820
suchen :-)