Forum: Mikrocontroller und Digitale Elektronik DS1820, Ansteuerungsprobleme


von Christoph A. (shadowrunner93)


Angehängte Dateien:

Lesenswert?

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!

von Lutz (Gast)


Lesenswert?

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ß.

von Christoph A. (shadowrunner93)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Christoph A. (shadowrunner93)


Angehängte Dateien:

Lesenswert?

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:
1
var & (1<<i)


Mfg

von (prx) A. K. (prx)


Lesenswert?

Dass du
1
//  Datenleitung überprüfen
2
if((PORTD & (1 << DQ) ) == 1)
mal überdenken solltest wurde bereits genannt.

von (prx) A. K. (prx)


Lesenswert?

Christoph A. schrieb:

> So ist es anscheinend falsch:

So ist es durchaus richtig, wenn man das richtige "var" hinschreibt.

von (prx) A. K. (prx)


Lesenswert?

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.

von Sascha W. (sascha-w)


Lesenswert?

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

von Christoph A. (shadowrunner93)


Lesenswert?

A. K. schrieb:
> Dass du
>
1
> //  Datenleitung überprüfen
2
> if((PORTD & (1 << DQ) ) == 1)
3
>
> 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 :
1
if((PIND & (1 << DQ) ) == 1)

So richtig?

Mfg

von Christoph A. (shadowrunner93)


Lesenswert?

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 
=)

von (prx) A. K. (prx)


Lesenswert?

Christoph A. schrieb:
1
> if((PIND & (1 << DQ) ) == 1

> So richtig?

Nö. Sowas nie mit 1 vergleichen, immer nur mit 0

Hier gibt's irgendwo in der Artikelsammlung ein Tutorial über diesen 
Bitkrams.

von Christoph A. (shadowrunner93)


Lesenswert?

A. K. schrieb:
> Christoph A. schrieb:
>
>
1
>> if((PIND & (1 << DQ) ) == 1
2
>
>
>> 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

von Sascha W. (sascha-w)


Lesenswert?

@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

von Christoph A. (shadowrunner93)


Angehängte Dateien:

Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

Das hier kennst du?
Beitrag "DS1820, DS18B20 in C"

von Christoph A. (shadowrunner93)


Lesenswert?

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 =)

von Karl H. (kbuchegg)


Lesenswert?

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.

von Christoph A. (shadowrunner93)


Lesenswert?

Tut mir Leid, mit dieser Formatierung kann ich nichts anfangen..
Es würde Ewigkeiten dauern bis ich mich in diesen Code eingarbeitet 
habe..

von (prx) A. K. (prx)


Lesenswert?

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.

von Christoph A. (shadowrunner93)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Lutz (Gast)


Lesenswert?

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.

von Christoph A. (shadowrunner93)


Lesenswert?

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

von Christoph A. (shadowrunner93)


Lesenswert?

Tut mir Leid, die Ausgabe ist richtig gedreht :

0000 0000 0110 1010

2+8+32+64 = 106

106/2 = 53 Grad

Ein bisschen warm?^^

MFg

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

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.

von Christoph A. (shadowrunner93)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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 :-)

von Christoph A. (shadowrunner93)


Lesenswert?

PeDa Software?

Tut mir Leid, unter diesem Begriff habe ich nichts gefunden.

Mfg

von Karl H. (kbuchegg)


Lesenswert?

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 :-)

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.