www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DS1820, Ansteuerungsprobleme


Autor: Christoph A. (shadowrunner93)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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!

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß.

Autor: Christoph A. (shadowrunner93)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christoph A. (shadowrunner93)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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:
var & (1<<i)


Mfg

Autor: A. K. (prx)
Datum:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph A. schrieb:

> So ist es anscheinend falsch:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christoph A. (shadowrunner93)
Datum:

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

So richtig?

Mfg

Autor: Christoph A. (shadowrunner93)
Datum:

Bewertung
0 lesenswert
nicht 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 
=)

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph A. schrieb:
> 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.

Autor: Christoph A. (shadowrunner93)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Christoph A. schrieb:
>
>
>> 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.

Vielen Dank, kleiner Schlampikeitsfehler.

Aber so gehts :
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

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christoph A. (shadowrunner93)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hier kennst du?
Beitrag "DS1820, DS18B20 in C"

Autor: Christoph A. (shadowrunner93)
Datum:

Bewertung
0 lesenswert
nicht 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 =)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christoph A. (shadowrunner93)
Datum:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christoph A. (shadowrunner93)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christoph A. (shadowrunner93)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christoph A. (shadowrunner93)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christoph A. (shadowrunner93)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Christoph A. (shadowrunner93)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PeDa Software?

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

Mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.