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
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.
Hallo, also die Delays habe ich auch alle aus dem PDF-Dokument so übernommen. Den Code von Peter Dannegger schaue ich mir mal an
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...
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.
Falscher Quarz; falsche Fuses (DIV8); interner statt externer Takt; Sensor nicht angeschlossen; am falschen Pin; Timing stimmt nicht (falscher Samplezeitpunkt); ...
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?
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
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.
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.
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?
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
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?
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.
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?
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.
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.
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!
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.
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
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.
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.
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.
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.
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.
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
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 :)
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?
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
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
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
>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.
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.