DS18S20 bringt immer 127

Gast #1936751
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/ds18b20_pre1.pdf

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


Gruß Robin
Angehängte Dateien:
Gast #1937209
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...
#1937334
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.
1
int16_t nDS18S20ReadTemperature(uint8_t vucPinNumber)
2
   {
3
   int16_t nTemperature;
4

5
   //Reset, skip ROM and start temperature conversion
6
   therm_reset(vucPinNumber);
7
   therm_write_byte(THERM_CMD_SKIPROM, vucPinNumber);
8
   therm_write_byte(THERM_CMD_CONVERTTEMP, vucPinNumber);
9

10
   //Wait until conversion is complete
11
   while (!therm_read_bit(vucPinNumber))
12
      ;
13

14
   //Reset, skip ROM and send command to read Scratchpad
15
   therm_reset(vucPinNumber);
16
   therm_write_byte(THERM_CMD_SKIPROM, vucPinNumber);
17
   therm_write_byte(THERM_CMD_RSCRATCHPAD, vucPinNumber);
18

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

25
   therm_reset(vucPinNumber);
26

27
   return nTemperature;
28
   }
29

30
char * pcDS18S20TempToString(int16_t vnTemp, char *rpcBuffer)
31
   {
32
   char *pcBuffer;
33

34
   pcBuffer = rpcBuffer;
35

36
   if (vnTemp > 0)
37
      {
38
      *pcBuffer = '+';
39
      pcBuffer++;
40
      }
41

42
   if ((vnTemp >> 1) <= 9 && (vnTemp >> 1) >= -9)
43
      {
44
      // Leerzeichen bei einstelligen Zahlen
45
      *pcBuffer = ' ';
46
      pcBuffer++;
47
      }
48

49
   itoa(vnTemp >> 1, pcBuffer, 10);
50
   while (*pcBuffer != '\0')
51
      pcBuffer++;
52
   *pcBuffer = '.';
53
   pcBuffer++;
54
   if (vnTemp & 0x0001)
55
      {
56
      *pcBuffer = '5';
57
      }
58
   else
59
      {
60
      *pcBuffer = '0';
61
      }
62
   pcBuffer++;
63
   *pcBuffer = 0xDF;
64

65
   pcBuffer++;
66
   *pcBuffer = '\0';
67

68
   return rpcBuffer;
69
   }

Gruß

Dirk
Gast #1937858
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.
Gast #1939658
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
Gast #1939699
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?
#1939718
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.
Gast #1940911
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.
Angehängte Dateien:
#1940932
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
1
#define F_CPU 3000000UL //Your clock speed in Hz (3Mhz here)
2
#define LOOP_CYCLES 8 //Number of cycles that the loop takes
3
#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!
#1940999
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.
Gast #1941005
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
#1941012
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.
#1941103
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.
Gast #1941184
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.
#1941198
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-Tutorial#Warteschleifen_.28delay.h.29


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_Checkliste#.C3.9Cbertragungsprobleme_durch_falschen_oder_ungenauen_Takt


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.
Gast #1945606
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
Angehängte Dateien:
Gast #1945728
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 :)
Gast #1945937
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?
Gast #1946261
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
Gast #1957497
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
Gast #1957520
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
Gast #1957544
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.
Gast #1959080
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren