Hallo Ich habe ein Arduino Nano und ein paar DS18B20 daran angeschlossen bei positiven Temperaturen stimmen die werte auch so weit. Aber sobald es Richtung minus grade geht wirds schlimm. Ein Beispiel ein Fühler hat -7 Grad und der nano gibt aufen Display -1,3 Grad aus und der Abstand wird größer je kälter der Sensor wird welche auch mit +5 Volt verbunden ist also mit allen drei pins. Habe schon ein paar andre beispiele versucht ist aber IMMER das selbe bei + grad ist alles ok bei - stimmt ab -1 grad nix mehr. Zuerst dachte ich ein Sensor ist defekt ok getauscht aber nö keine Änderung. } DeviceAddress sensor1 = { 0x28, 0xFF, 0x86, 0x2E, 0x74, 0x16, 0x3, 0xAF }; DeviceAddress sensor2 = { 0x28, 0xFF, 0x5, 0x72, 0x74, 0x16, 0x3, 0xE0 }; DeviceAddress sensor3 = { 0x28, 0xFF, 0x2B, 0x3F, 0x73, 0x16, 0x5, 0x60 }; void writeTimeToScratchpad(byte* address) { //reset the bus ds.reset(); //select our sensor ds.select(address); //CONVERT T function call (44h) which puts the temperature into the scratchpad ds.write(0x44,1); //sleep a second for the write to take place delay(1000); } void readTimeFromScratchpad(byte* address, byte* data) { //reset the bus ds.reset(); //select our sensor ds.select(address); //read the scratchpad (BEh) ds.write(0xBE); for (byte i=0;i<9;i++){ data[i] = ds.read(); } } float getTemperature(byte* address) { int tr; byte data[12]; writeTimeToScratchpad(address); readTimeFromScratchpad(address,data); //put in temp all the 8 bits of LSB (least significant byte) tr = data[0]; if (address[0] == 0x10) // DS18B20 { //check for negative temperature if (data[1] > 0x80) { tr = !tr + 1; //twos complement adjustment tr = tr * -1; //flip value negative. } //drop bit 0 tr = tr >> 1; //COUNT PER Celsius degree (10h) int cpc = data[7]; //COUNT REMAIN (0Ch) int cr = data[6]; return tr - (float)0.25 + (cpc - cr)/(float)cpc; } else // DS18B20 { return ((data[1] << 8) + tr) * (float)0.0625; } } void loop(void) { char sensor1Name[] = "1: "; char sensor2Name[] = "2: "; char sensor3Name[] = "3: "; float temp1 = getTemperature(sensor1); float temp2 = getTemperature(sensor2); float temp3 = getTemperature(sensor3); Serial.print(sensor1Name); Serial.print(temp1); Serial.println(" C"); Serial.print(sensor2Name); Serial.print(temp2); Serial.println(" C"); Serial.print(sensor3Name); Serial.print(temp3); Serial.println(" C"); Größere/kleiner Werte bei return ((data[1] << 8) + tr) * (float)0.0625; verändern verändern positive und negative werte wo bei positive ja stimmen :- ( Jemand eine idee ? VIELEN DANK
Direkt fällt mir nichts auf, aber als Ideen: 1) Das Programm minimalisieren, um Flüchtigkeitsfehler auszuschließen. Also z.B. den Zweig bei "if (address[0] == 0x10) // DS18B20" eliminieren, da der eigentlich nicht angesprochen werden sollte. 2) CRC des 0xBE Commands prüfen. 3) Die vollständigen Ergebnisse von ein paar 0xBE Commands als HEX ausgeben lassen und von Hand nachrechnen und ggfs. hier nochmal posten.
hmm Vielen dank habe noch eine weile versuche gemacht und muss sagen: SCHEINT jetzt zu stimmen ob Woll ich im Endeffekt nix geändert habe ? naja allerdings habe ich von 12 auf 10 bit runter geschraubt da ich ohne hin nur 0,5 grad brauche und eine Kabellänge von um 15-18 meter woll seins dazu tut. Genauers teste ich später noch. Also den Adress teil muss ich lassen das scheint was mit der Berechnung zu tuhen zu haben da noch ein anderer Sensor (AM2302) verbaut ist und ausgelesen wird. Bei CRC kann ich dir leider nicht ganz folgen. Wie soll ich das prüfen oder besser mit was vergleichen ? Vielen dank für deine hilfe
hmm komisch Temperatur stimmt nach wie vor nicht. Sensor gibt wert von -0,95C aus und mit andern Messapparaturen sinds minus 6 grad. könnte der 78l05 mit je 1µf bei minus graden ohne Grundlast zu schwingen anfangen ? Auf ein widerstand als Grundlast musste ich verzichten weil der widerstand die box mit dem Sensor aufheizte. Mit einen kurzen kabel und andren Sensor ist die Messung richtig es muss also Hardware seitig was sein. Und da habe ich schon auf ein Festspannungsregler und den 10 bit mode gesetzt und die wartezeit ist auch noch bei 750ms ob woll nur 200 nötig wären.
@ DAVID ------ (bastler-david) >könnte der 78l05 mit je 1µf bei minus graden ohne Grundlast zu schwingen >anfangen ? Sollte er eigentlich nicht. >Mit einen kurzen kabel und andren Sensor ist die Messung richtig es muss >also Hardware seitig was sein. Dann hast du möglicherweise ein Timingproblem. Probiers damit. Beitrag "Re: Onewire + DS18x20 Library"
DAVID -. schrieb: > Jemand eine idee ? Längeren Code bitte mit entsprechenden Tags einrahmen, und vorher TABs durch Leerzeichen ersetzen.
Wenn ich als text Datei anhänge wird rum gejammert das man es erst runterladen muss macht man es so wird auch gejammert ... wie manns macht ists falsch. Eine frage zum Verständnis: wieso brauchen minus grade andere Timings ? Schöne library haste da geschrieben ! Du hast dazu nicht auch eine kleine Anleitung was was heist ?
Das Problem ist: "negative Werte werden falsch übertragen". Wenn man mit dieser Prämisse den Code durchschaut, dann findet man eine Schräge bahandlung genau dieser Situation. Der Sensor liefert in jeder Betriebsart eine int16 Zahl, die als Einheit 1/16 Grad hat. Da muß nichts von Hand komplementiert werden, besonders wenn man dabei nur die unteren 8-Bit behandelt und die oberen 8 vergißt. Einfach
1 | float Temperatur = ( (data[1]<<8) | data[0] ) / 16.0; |
und gut.
Carl D. schrieb: > und gut. Besser: float Temperatur = (int16_t)(data[1]<<8 | data[0]) / 16.0; Falls man mal über 32 Bits stolpert.
:
Bearbeitet durch User
Heisst es in deinem Code wirklich: /c writeTimeToScratchpad(address); /c readTimeFromScratchpad(address,data); Ich hötte bei den Funktionen eher etwas mit ...Temp... erwartet. Oder nutzt du die Funktionen der OneWire RTC?
Super Vielen dank habe es mal mit rein genommen wird fehlerfrei übersetzt. Müsste es aber nicht: float getTemperature = (int16_t)(data[1]<<8 | data[0]) / 16.0; heißen ? Vielen dank euch 2. Mit OneWire RTC kann ich so jetzt auf die schnelle nix anfangen ich frage/habe vor 12 (18b20) Sensoren und ein Feuchtigkeits Sensor abzufragen diese Daten auf 4 Displays anzuzeigen und am Pc zu senden. Das wars erst mal.
DAVID -. schrieb: > Super Vielen dank habe es mal mit rein genommen wird fehlerfrei > übersetzt. > Müsste es aber nicht: > float getTemperature = (int16_t)(data[1]<<8 | data[0]) / 16.0; Nein, denn du benutzt C und nicht Pascal. Deine Funktion wird einfach zu:
1 | float getTemperature() { |
2 | return (data[1]<<8 | data[0]) / 16.0; |
3 | }
|
A.K.: > Besser: > float Temperatur = (int16_t)(data[1]<<8 | data[0]) / 16.0; > Falls man mal über 32 Bits stolpert. wobei das "(int16_t)" nur dokumentiert, was der Compiler eh macht: Mit "native Integer" zu rechnen. Und das ist dann bei einer 32-Bit Plattform immernoch korrekt, aber kompakter als z.B. 16Bit auf ARM mit Signextension etc. Wenn schon, dann "int_fast16_t", dann hat man min 16Bits oder eben mehr, wenn die Architektur damit besser kann.
Carl D. schrieb: > Und das ist dann bei einer 32-Bit Plattform immernoch korrekt, Eben nicht. Der Cast (int16_t) erzwingt die Vorzeichenerweiterung des 16-Bit Wertes des Sensors. Auf 32-Bit Plattformen sind ints 32 Bits breit und daher ist data[1]<<8 immer positiv, ohne Cast damit auch das Gesamtergebnis. > Wenn schon, dann "int_fast16_t" Es funktioniert nur mit int16_t, d.h. mit einem Datentyp, der genau 16 Bits gross ist. Ganz konform ist es trotzdem nicht, denn es wird Zweierkomplement vorausgesetzt - aber das ist heute nur noch akademisch.
:
Bearbeitet durch User
DAVID -. schrieb: > if (data[1] > 0x80) > { > tr = !tr + 1; //twos complement adjustment > tr = tr * -1; //flip value negative. > } Dieser Teil kommt mir seltsam vor. Ist vielleicht
1 | tr = ~tr + 1; |
gemeint?
CC schrieb: > Dieser Teil kommt mir seltsam vor. Ist schlicht falsch. Spielt aber beim DS18B20 keine Rolle, da dieser Codezweig nur beim DS18S20 greift.
:
Bearbeitet durch User
ok: > tr = !tr + 1; //twos complement adjustment > tr = tr * -1; //flip value negative. Ist raus DANKE und ist das jetzt so gemeint ? } float getTemperature(byte* address) { int tr; byte data[10]; float Temperatur = (int16_t)(data[1]<<8 | data[0]) / 16.0; Muss ich da beim Sensor auslesen dann: float temp1 = getTemperature(sensor1); Oder float temp1 = Temperature(sensor1); nehmen ? Verstehe den unterschied noch nicht ganz.
DAVID -. schrieb: > Verstehe den unterschied noch nicht ganz. Nicht immer sind Tipps buchstabengetreu zu verstehen. Soweit keine anderen Erkenntnisse vorliegen werden in Threads oft Grundkenntnisse in C als gegeben vorausgesetzt. Da das hier offenbar nicht so ganz der Fall ist, wäre ein Blick in ein C Handbuch empfohlen.
Kann es sein, dass Du den Sensor zu oft ansprichst und sich der Sensor dadurch erwärmt? Versuche mal, den Sensor nur jede Minute auszulesen. Stimmen die delay(1000)? Es sollten delay(750) ausreichen. Hast Du die F_CPU Anweisung im Makefile oder im C-File stehen?
Die Sensoren sollen wenn ich mit testen durch bin alle 30 sek abgefragt werden. Aber das sich der Sensor bei -7 grad selber um fast 6 grad aufheizt halte ich für unwahrscheinlich aber denkbar. Eher würde sich der 78l05 auf heizen der muss aus 11 volt die 5 volt und bis zu 2 milliampere halten :-) Den CPU Speed habe ich nicht angegeben gehe einfach mal davon aus das die arduino IDE das vom nano richtig erkennt bis jetzt gabs auch keine Probleme damit.
DAVID -. schrieb: > Aber das sich der Sensor bei -7 grad selber um fast 6 grad aufheizt > halte ich für unwahrscheinlich aber denkbar. Alle 30 Sekunden zu messen schadet nicht.
Wie hast Du die Referenz gemessen? Auch genau an dem DS1820 Sensor? Ja, ein Linearregler kann schon reichen, um in direkter Nähe die Messung zu verfälschen. Da sind die DS Sensoren sehr sensibel.
So habe die ändern übernommen und muss sagen nix :-( dachte ich mir kann ja nicht sein. dann habe ich dem 78l05 den strom abgezogen ein tag gewartet und sehe da es kommen auch minus grade vom Sensor ? dann reicht also tatsächlich ein kleiner 78l05 der aus 12 Volt 5 Volt für den Sensor macht die Temperatur so hoch zu treiben in dem 5x5 cm plastikkasten an der Außenseite einer außen mauer. Würde es reichen den Sensor mit Heißkleber Wasser dicht zu bekommen ? oder sollte ich langfristig was anderes nehmen ? er wäre dann den Naturgewalten schutzlos ausgeliefert :-( auf dem 78l05 würde ich nicht verzichten wollen da ich mir nicht sicher bin wegen Spannungsspitzen da das kabel für den Sensor damals neben ein Erdkabel für Steckdosen im garten gelegt wurde. es hat war eine Abschirmung aber so ganz tauen tute ich der Geschichte nicht.
Mein Sensor hängt unter dem Carport. Das ist zwar etwas geschützt und vielleicht 1°C zu hoch im Vergleich zur Umgebung außerhalb des Carports. Aber ich bin damit zufrieden. Funktioniert seit 3 Jahren. Wenn die 1,50m entfernte Tür zum Haus aufmache, kann man das in der Temperaturkurve auch sehen. Einfaches Durchgehen reicht für eine Änderung am DS1820. Kannst Du vielleicht ein 5V Netzteil nehmen oder einen Schaltregler?
:
Bearbeitet durch User
Einfacher wäre wohl parasitäre Versorgung. 2 Leitungen, sonst nix.
DAVID -. schrieb: > Würde es reichen den Sensor mit Heißkleber Wasser dicht zu bekommen ? Es gibt die auch fertig vergossen: http://www.komputer.de/zen/index.php?main_page=product_info&products_id=202&zenid=4tnjnrgckt1n7he26tpthtlno6
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.