www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DS18S20 bringt immer 127


Autor: Robin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Bastlergemeinde,

ich bin immer noch dabei, ein kleines Thermostat zu bauen. Beim Auslesen 
des DS18S20 habe ich allerdings ein Problem: Der bringt mir immer +127°C 
zurück obwohl im Raum nur 21°C sind. Ich komme da einfach nicht weiter. 
Den großteil des Quellcodes habe ich von hier:

http://www.teslabs.com/openplayer/docs/docs/other/...

Habt ihr noch eine Idee, was falsch sein könnte?


Gruß Robin

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und die Delays stimmen so alle? In der avr-libc finden sich präzise 
Delay-Funktionen - und hier im Forum fertiger und funktionierender 
DS18x20-Code von Peter Dannegger.

NB: Interrupts sind der Gegenspieler ungeschützter Delay-Schleifen.

Autor: Robin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also die Delays habe ich auch alle aus dem PDF-Dokument so übernommen.

Den Code von Peter Dannegger schaue ich mir mal an

Autor: Robin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also mit dem Code komme ich auch nicht weiter. Eigentlich sollte es doch 
mit dem Code, den ich aus der PDF-Datei verwendet habe funktionieren.

Wenn immer 127 raus kommt sollte das ja bedeuten, dass in den beiden 
ausgelesenen Bytes nur 1111 1111 1111 1111 drin steht. Vom Vorzeichen 
jetzt mal abgesehen.

Habe auch schon überlegt, ob ich schlecht gelötet habe und den Pull-Up 
Wiederstand mit VCC überbrückt habe, dort ist aber alles okay.

Ich komme einfach nicht weiter...

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin schrieb:

> Habt ihr noch eine Idee, was falsch sein könnte?

Schaltplan und Fotos vom Aufbau fehlen ja, deshalb auch an das 
Unmögliche denken: Der Sensor ist nicht oder falsch an PB2 
angeschlossen.

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falscher Quarz; falsche Fuses (DIV8); interner statt externer Takt; 
Sensor nicht angeschlossen; am falschen Pin; Timing stimmt nicht 
(falscher Samplezeitpunkt); ...

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin schrieb:
> Eigentlich sollte es doch
> mit dem Code, den ich aus der PDF-Datei verwendet habe funktionieren.

Hast Du den abgetippt? So richtig wie vor 20 Jahren?
Hast Du den auch auf Tippfehler überprüft?
Vielleicht auch daran gedacht, dass dieser Code vielleicht auch Fehler 
enthalten kann?

Autor: Dirk Schmidt (disc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Robin,
das PDF, aus dem Du Deinen Code hast, ist für die B-Variante des 18X20 
geschrieben. Diese hat eine Auflösung von bis zu 12 bit.
Du hast ja die S-Variante, die nur 9 bit Auflösung hat. Darum wird das 
wohl nicht funktionieren, da das Ausgabeformat etwas anders ist (siehe 
Datenblatt).

Hier mal meine funktionierende Variante für den 18S20. Ich habe die 
Funktionen so umgeschrieben, dass ich unterschiedliche Pins verwenden 
kann.
int16_t nDS18S20ReadTemperature(uint8_t vucPinNumber)
   {
   int16_t nTemperature;

   //Reset, skip ROM and start temperature conversion
   therm_reset(vucPinNumber);
   therm_write_byte(THERM_CMD_SKIPROM, vucPinNumber);
   therm_write_byte(THERM_CMD_CONVERTTEMP, vucPinNumber);

   //Wait until conversion is complete
   while (!therm_read_bit(vucPinNumber))
      ;

   //Reset, skip ROM and send command to read Scratchpad
   therm_reset(vucPinNumber);
   therm_write_byte(THERM_CMD_SKIPROM, vucPinNumber);
   therm_write_byte(THERM_CMD_RSCRATCHPAD, vucPinNumber);

   //Read Scratchpad (only 2 first bytes)
   nTemperature = therm_read_byte(vucPinNumber);
   nTemperature |= therm_read_byte(vucPinNumber) << 8;
   // Test -25Grad
   //temperature = 0xFFCE;

   therm_reset(vucPinNumber);

   return nTemperature;
   }

char * pcDS18S20TempToString(int16_t vnTemp, char *rpcBuffer)
   {
   char *pcBuffer;

   pcBuffer = rpcBuffer;

   if (vnTemp > 0)
      {
      *pcBuffer = '+';
      pcBuffer++;
      }

   if ((vnTemp >> 1) <= 9 && (vnTemp >> 1) >= -9)
      {
      // Leerzeichen bei einstelligen Zahlen
      *pcBuffer = ' ';
      pcBuffer++;
      }

   itoa(vnTemp >> 1, pcBuffer, 10);
   while (*pcBuffer != '\0')
      pcBuffer++;
   *pcBuffer = '.';
   pcBuffer++;
   if (vnTemp & 0x0001)
      {
      *pcBuffer = '5';
      }
   else
      {
      *pcBuffer = '0';
      }
   pcBuffer++;
   *pcBuffer = 0xDF;

   pcBuffer++;
   *pcBuffer = '\0';

   return rpcBuffer;
   }

Gruß

Dirk

Autor: Robin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also ich habe diesen perinlichen Anfängerfehler korrigiert. Nun zeigt er 
zwar ne andere Zahl an aber diese ist -1°C welche ja eigentlich -0,5°C 
darstellt aber ich arbeite ja mit int, also ohne Kommastellen. Auf 
jedenfall bedeutet das, das wieder die ganzen beiden Bytes aus 1 
bestehen.

:(

Das löst leider mein Problem noch nicht.

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin schrieb:
> eiden Bytes aus 1 bestehen.
Das bedeutet
a. Der Sensor zieht die Datenleitung nicht nach Low.
b. Der Prozessor misst den Zustand der Datenleitung im falschen Moment.
c. Du verwendest den falschen Pin.

Autor: ROBIN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

also der PIN ist 100%ig richtig angeschlossen an PB2. Der Port ist auch 
auf Ausgang geschaltet.

Wie teste ich denn ohne Oszi ob zur richtigen Zeit gelesen wird?

Autor: mexman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ROBIN schrieb:
> Wie teste ich denn ohne Oszi ob zur richtigen Zeit gelesen wird?

Garnicht.
Genau wie man einen Motor nicht reparieren kann, wenn keine 
Schraubenschluessel hat, zum Kuchenbacken das entsprechende Werkzeug 
ebenso braucht wie die Zutaten, kann man eben bestimmte Fehler in 
gewissen Schaltungen nur finden, wenn man eines hat!


Gruss

Michael

Autor: ROBIN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann denn aufgrund meiner gebauten Schaltung durch den Widerstand der 
Leitungen etc. die Zeit verzögert werden? Also das die Zeiten, die ich 
im Code angegeben habe dann real nicht eingehalten werden?

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

Bewertung
0 lesenswert
nicht lesenswert
Ziemlich unwahrscheinlich.

Ich kann nur soviel sagen:
Ich hab mir aus der Codesammlung den Code vom PeDa geholt, die Pins 
angepasst, Taktfrequenz an die tatsächliche angepasst und das ist auf 
Anhieb gelaufen. Ob ich 4k7 oder 10k als Pullup benutzt habe, war 
unerheblich.


Ich tippe mal darauf, dass deine µC Taktfrequenz nicht mit der im 
Programm eingestellten übereinstimmt.

Autor: nicht_eingeloggt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das, was Christian H. sagt.

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wird der Chip mit Energie versorgt? Parasitär oder über extra 
Anschluss? Wahrscheinlich parasitär und dann muss ja GND mit VDD 
überbrückt werden. Ist das gemacht?

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hans schrieb:
> Wahrscheinlich parasitär

Zumindest macht das Programm keinen Strong-Pullup (müsste normalerweise 
über einen extra-Transistor gemacht werden), damit der Sensor beim 
Wandeln genug Strom bekommt. Ich tippe daher eher auf eigene 
Stromversorgung.

Autor: Robin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also der Sensor ist mit an der 5V-Leitung des µC angeschlossen. Die 5V 
kommen von einem 9V Netzteil. Also die 9V werden mit einem 7805er auf 5V 
heruntergeregelt, wie man das halt so macht.

Der Schaltplan liegt bei.


Gruß Robin

Und nochmal vielen vielen Dank für eure Hilfe.

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

Bewertung
0 lesenswert
nicht lesenswert
Hmm.
Laut deinem Schaltplan hast du keinen Quarz am µC hängen. Die XTAL Pins 
sind alle frei.

Da frage ich mich dann, was das hier
#define F_CPU 3000000UL //Your clock speed in Hz (3Mhz here)
#define LOOP_CYCLES 8 //Number of cycles that the loop takes
#define us(num) (num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))

in deinem Code soll. Einen Mega8 kann man mit internen Mitteln ganz 
sicher nicht auf 3Mhz einstellen.

WENN also dein Schaltplan korrekt und vollständig ist, DANN kann das so 
gar nicht funktionieren, WEIL deine delays allesamt falsch sind!

Siehe zb gleich die erste Antwort auf deine Frage!

Auch wenn du Code klaust, was grundsätzlich ok ist, ein bischen 
mitdenken musst du schon!

Autor: Robin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ist die Lösungen einen 3MHz Quarz anzuhängen?

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

Bewertung
0 lesenswert
nicht lesenswert
Robin schrieb:
> Also ist die Lösungen einen 3MHz Quarz anzuhängen?

Die Lösung kann sein, deinen COmpiler nicht anzulügen.
Wenn dein Mega mit 1Mhz (weil Grundzustand) getaktet wird, dann trag 
beim F_CPU auch 1 Mhz ein.

Das ist doch nicht so schwer. Wer soweit ist, dass er Multiplexen kann, 
sollte doch in seiner Lehrzeit schon mal über F_CPU gestolpert sein. Wie 
hast du denn deinen Timer und die Multiplexfrequenz berechnet, wenn das 
für dicvh anscheinend völliges Neuland ist, dass ein Mega8 frisch aus 
der Tüte mit 1Mhz läuft.

Autor: Robin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja zum Multiplexen habe ich das Tutorial hier von der Seite gelesen. 
Hat auch gleich funktioniert.

Habe leider nur Ahnung vom programmieren ansich und weniger von der 
Hardware-Kommunikation mit dem Atmega. Deshalb bin ich ja noch Anfänger 
^^ war vll. etwas zu schwer das Projekt. Ich versuche mal obs mit dem 
Ändern der 3 MHz funktioniert. Danke für die Hilfe.

Gruß und Schönen Abend
Robin

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

Bewertung
0 lesenswert
nicht lesenswert
Robin schrieb:

> Habe leider nur Ahnung vom programmieren ansich


Im Code stehst dabei, dass du anpassen musst. Im von dir verlinkten PDF 
gibt es ein Kapitel (3.1) das mit 'Critical Timing' überschrieben ist 
und welches ausführlichst auf die damit zusammenhängende Problematik 
eingeht. Alles nicht gelesen?
Hast du denn nicht ein einziges mal den Code den du klaust 
durchgeschaut, wenigstens oberflächlich, und dich gefragt, wie 
eigentlich die delays realisiert sind, die da überall quer durch die 
Bank auftauchen?



> ^^ war vll. etwas zu schwer das Projekt. Ich versuche mal obs mit dem
> Ändern der 3 MHz funktioniert.

Das ist zumindst mal ein Fehler.
Ob es der einzige ist, wird sich zeigen.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Hast du denn nicht ein einziges mal den Code den du *klaust*

Nana, (zu) starker Tobak!

Robin hat bereits im ersten Beitrag geschrieben, woher der Code stammt 
und der Autor hat das Projekt als Open-HW/SW ("Openplayer") 
aufgezogen. Robin ist da 100x ehrlicher als manch anderer.

Nix für ungut, SCNR.

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

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> Karl heinz Buchegger schrieb:
>
>> Hast du denn nicht ein einziges mal den Code den du *klaust*
>
> Nana, (zu) starker Tobak!
>
> Robin hat bereits im ersten Beitrag geschrieben, woher der Code stammt
> und der Autor hat das Projekt als Open-HW/SW ("Openplayer")
> aufgezogen. Robin ist da 100x ehrlicher als manch anderer.
>
> Nix für ungut, SCNR.

Gut, 'klauen' streichen und durch 'übernehmen' ersetzen.
Das Grundübel bleibt aber weiterhin.

Autor: Robin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay also habe den Code jetzt so geändert:

#define F_CPU 1000000UL //Your clock speed in Hz (1Mhz here)
#define LOOP_CYCLES 8 //Number of cycles that the loop takes
#define us(num) (num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))

Geht leider trotzdem nicht. Ich prüfe morgen nochmal alle Anschlüsse und 
ob mein Atmega8 für einen loop auch wie in dem Beispiel aus dem 
PDF-Dokument wirklich 8 cycles benötigt.

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

Bewertung
0 lesenswert
nicht lesenswert
Robin schrieb:
> Okay also habe den Code jetzt so geändert:
>
> #define F_CPU 1000000UL //Your clock speed in Hz (1Mhz here)
> #define LOOP_CYCLES 8 //Number of cycles that the loop takes
> #define us(num) (num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))
>
> Geht leider trotzdem nicht.

OK.
Dann gibts noch mindestens 1 weiteres Problem.

> Ich prüfe morgen nochmal alle Anschlüsse und
> ob mein Atmega8 für einen loop auch wie in dem Beispiel aus dem
> PDF-Dokument wirklich 8 cycles benötigt.

Schmeiss diese delays Funktion überhaupt raus und ersetzte sie durch 
_delay_us aus <util/delay.h>. Die stimmt 100% (wenn F_CPU korrekt 
gesetzt ist und natürlich im Rahmen der überhaupt möglichen Auflösung).

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...


Nochmal zum F_CPU. Hast du an den Fuses des Mega gespielt?
Wie gesagt: Aulieferungszustand ist 1Mhz. Aber per Fuse kann man auch 
andere Frequenzen einstellen. Eventuell sollte man das mal mit ein paar 
_delay_ms und einer blinkenden LED überprüfen, wenn du dir nicht sicher 
bist. So wie hier beschrieben:
http://www.mikrocontroller.net/articles/AVR_Checkl...


Ach und noch was: Solange der DS-Code ständig von Interrupts 
unterbrochen werden kann, wird es mit einem delay auf 
Warteschleifenbasis sowieso eher nichts. Die Zeiten werden nicht 
stimmen. Du solltest daher auf jeden Fall während des Auslesens die 
Interrupts abschalten, auch wenn das zunächst bedeutet, dass deine 
Anzeigen flackern.

Autor: Robin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also ich habe jetzt folgendes gemacht:
1) alle alten delay-Funktionen durch _delay_us ersetzt
2) Geprüft, ob die Hz umgestellt wurden. Dazu habe ich einfach mal die 
Segment-Anzeigen im 1-Sekunden-Takt blinken lassen. Das war auch 
wirklich (soweit man das mit dem menschlichen Auge messen kann) 1 
Sekunde je Takt - hab das so gemacht wie im AVR Tut beschrieben.
3) Ich deaktiviere vor dem kompletten Auslesevorgang die Interrupts mir 
der Methode cli() und aktiviere sie danach wieder mit sei()

Leider ändert das nichts an dem Ergebnis, welches angezeigt wird :(


Kann man irgendwie testen, ob vll der Sensor im ***** ist?


Gruß Robin

Autor: Chris2k (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Robin,

überprüfe mal, ob die den Sensor richtig angeschlossen hast. Damit meine 
ich nicht den Pin am µC, sondern die Verdrahtung des Sensors. Schau dazu 
mal im Datenblatt und achte dabei auf die Nummering der Pins samt des 
Zusatzes "Bottom View" (!). Ich hatte das damals dummerweise verwechselt 
- zum Glück hatte ich ein Netzteil, was den Strom begrenzen kann und der 
Sensor hat die peinliche Geschichte überlebt :)

Autor: Dummy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne blöde Zwischenfrage, auf welchem µC läuft den das Programm ?
Ich vermisse irgendwie im geposteten Quellcode die Include Datei zum µC.
Die muss doch auch angeben sein oder irre ich mich da?

Autor: Robin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich benutze einen Atmega8. Funktioniert aber alles soweit, nur eben 
nicht das Einlesen der Temperatur. Der Sensor bringt immer 1111111 
usw...

Den Anschluss vom Sensor prüfe ich heute Abend mal wenn ich zu Hause 
bin.


Gruß Robin

Autor: Robin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also nachdem ich jetzt noch ein wenig mit den Zeiten und so weiter 
rumprobiert hatte ab ich mir jetzt bei Conrad einen neuen Sensor 
gekauft.

Und siehe da er zeigt schonmal etwas anders an als sonst. Bei 19°C im 
Raum zeigen die Anzeigen 44 an. Manchmal aber auch nur 38. Wenn das 
Gerät 1 Minute angeschaltet ist zeigt die Anzeige dann 1° mehr an als 45 
bzw. 39.

Des Weiteren spinnt die 7-Segment-Anzeige seitdem ich die Interrupts mit 
cli() und sei() vor dem Messen ab bzw. nach dem Messen wieder anstelle. 
Ohne dieses Vorgehen funktioniert aber die Messung nicht. Hat jemand 
einen Tipp für mich wie ich das Zeitmanagement besser realisieren kann? 
Die Anzeigen flackern nicht sondern sie "springen" sozusagen wil hin und 
her (nicht wörtlich nehmen ;) bin nicht besoffen)

Gruß Robin

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der DS18S20 braucht nach der Initialisierung ein klein
wenig Zeit (paar ms) bis zur ersten Messung, danach läuft
alles korrekt. Habe Projekte mit Attiny 2313 und Atmega8,
dabei verhält sich alles identisch. Ansonsten keine Probleme
mit dem DS18S20, allerdings funktioniert 1wire nicht mit
100m (eigenes Protokoll entwickelt. Man sollte alle 9 Bytes
nutzen um den Checksummentest zu machen. Das Zusammenrechnen
der Bytes zur Temperatur ist im Datenblatt beschrieben.
Auslesen, Decodieren (bei langen Strecken spez. Übertragungs-
protokoll) läuft bei mir alles unter BASCOM. Keine Probleme!
VG Micha

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hat jemand
>einen Tipp für mich wie ich das Zeitmanagement besser realisieren kann?

Schalte deinen Prozessor mal auf Vollgas. 1MHz ist ja nun
nicht der Bringer. 1 Wire und Interrupts für Multiplexanzeigen
beisst sich ganz schön. Versuch es erstmal mit einem LCD.
Dem tut es nicht weh wenn mal ein paar ms keine Daten kommen.

Autor: Robin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also habe den µC jetzt mal 1 Stunde laufen lassen und die Temp ist dann 
nicht nur um 1° sondern bis auf 47°C angestiegen obwohl im Raum trotzdem 
nur 19 bis 20 waren. Beeinflusst die Eigenerwärmung des Sensors das 
Messergebnis so stark?

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.