DS18S20 Fehler beim Auslesen

Hallo,
ich habe ein neues Problemchen :wink:

Meine Heizungstelemetrie läuft inzwischen immer besser, allerdings hab ich einen seltsamen Effekt.
Ich lese 1x pro Minute 9 DS18S20 aus und schicke die Werte, zusammen mit einigen anderen Messwerten √ľbers Netzwerk auf meinen Server, um sie dann online grafisch auszuwerten, gleichzeitig wird alles sch√∂n auf einem 16x2 LCD angezeigt.

In unregelm√§√üigen Abst√§nden, aber durchschnittlich alle 1-2 Tage bringen mir die DS18S20 allesamt nur noch den Wert -0,13¬įC.
Alles andere funktioniert aber noch einwandfrei.
Ein Reset per Reset-Knopf wirkt nicht, auch nach dem Reset wird noch -0,13 angezeigt. Abhilfe schafft dann nur noch Strom abschalten und wieder einschalten.

Ich verwende (u.a.) die Libarys OnWire und DallasTemperature, die Sensoren haben eine eigene Stromversorgung (aus dem gleichen netzger√§t aber ohne umweg √ľber arduino und ohne parasite) und einen passenden Pullup (wenn der nicht passt wird 85¬į ausgegeben - hatte ich schon :smiley: )
Ach ja, es läuft alles auf einem arduino mega256 mit ethernet shield :wink:

Hat evtl jemand einen hei√üen Tipp f√ľr mich wo ich suchen k√∂nnte?
Die Leitungen zu den Sensoren sind recht lang, ich k√∂nnte mir also vorstellen dass Einstreuungen von Stromleitungen eine Rolle spielen k√∂nnten - Aber ich denke eigentlich dann w√ľrden die Sensoren eher vereinzelt 85¬į oder -125¬į ausgeben. Die Leitungsl√§ngen kann ich aus verst√§ndlichen Gr√ľnden nicht √§ndern :wink:

Das ganze sieht in etwa so aus (Normalerweise lass ich auf der Grafik der √ľbersihtlichkeit halber nur 1 Tag anzeigen, aber um den Fehler zu verdeutlichen hab ich 10 Tage und doppelte Bildbreite eingestellt):

Hallo,

sind die Kabel geschirmt?
werden die Wartezeiten nach Temp Request eingehalten? Vielleicht etwas erhöhen.
Sketch?
Wie groß ist der Pullup?
Die 5V sind wirklich stabil? Vielleicht noch ein kleinen Keramikkondensator an den Sensor bauen.

Kabel sind nicht geschirmt (war vielleicht ein fehler)
Ich lese die Sensoren nur 1x pro Minute aus, ansonsten hab ich keine Wartezeiten drin. Ich hab sensors.setWaitForConversion(false); weil die Libary sonst mein Sketch eine Zeitlang per Delay blockiert, und das wollte ich nicht…
Pullup hat 1,5k. Ein kleinerer (ich glaub 330 waren das) brachte mir bei der H√§lfte der Messwerte -127¬į
Die 5V sollten stabil sein, ich kann mich nur drauf verlassen. Es ist ein kleines Schaltnetzteil: http://www.ebay.de/itm/Netzteil-Ladegeraet-Trafo-Adapter-5V-2A-500mA-800-1000mA-2000mA-Routernetzteil-/141552245200?
Wäre es sinnvoll noch was zur Stabilisierung einzubauen?
Kerko direkt an die Sensoren oder reicht einer an der Zuleitung?

Mein Sketch ist mit allem drum und dran 18,5kb groß, und ich zeige mein geschreibsel ganz ungern her :smiley:
Ich hab mal die relevanten Sachen rausgezogen, aber wenn dir das nicht reicht werd ich dannhalt den rest auch posten m√ľssen :wink:

#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>

unsigned long intervall_aktualisierung = 60000;
unsigned long previousMillis_aktualisierung = 0;

DeviceAddress addr_heizungsraum    = { 0x10, 0x30, 0x27, 0xDB, 0x2, 0x8, 0x0, 0x13 }; 
float temp_heizungsraum;

OneWire ow(42);
DallasTemperature sensors(&ow);

void setup()
  {
  sensors.begin();
  sensors.setWaitForConversion(false);
  delay(1000);
  sensors.requestTemperatures();
  delay(1000);
  }

void loop()
  {
  if(millis() - previousMillis_aktualisierung > intervall_aktualisierung) handle_kommunikation();
  }

void handle_kommunikation()
  {
  Sensor_lesen();
  previousMillis_aktualisierung = millis();
  }

void Sensor_lesen()
  {
  sensors.requestTemperatures();
  temp_heizungsraum = sensors.getTempC(addr_heizungsraum);
//...
  }

Die Wartezeit f√ľr die Wandlung musst du aber einhalten! setWaitForConversion(false) ist v√∂llig ok. Aber dann musst du das Delay zwischen Anforderung und Aulesen mit millis() machen.

Ich mache es so:

float temp;

bool readTemperatureSensors()
{
   static unsigned long previousMillis;
   static bool dataRequested;
 
   if(dataRequested == true && millis() - previousMillis > 200)   //hier Wandlungszeit je nach Auflösung festlegen
   {
       temp = sensors.getTempC(sensorList[0]);
       dataRequested = false;
       previousMillis = millis();
       return true;
   }
 
    if(dataRequested == false && millis() - previousMillis > TEMP_POLLING_INTERVAL)
    {
 sensors.requestTemperaturesByAddress(sensorList[0]);
 dataRequested = true;
 previousMillis = millis();
    }

    return false;
}

Das kann man dann ständig aufrufen

Ach so, ich dachte die Wartezeit muss zwischen jedem kompletten Durchlauf sein!

Wenn ich das jetzt also richtig verstehe muss ich zwischen sensors.requestTemperatures(); und sensors.getTempC(); noch eine Pause einbauen?

Kann das denn den beschriebenen Absturz auslösen?

Aus meiner Warte eigentlich nicht. Wenn die Zeit bis zum nächsten Temp request zu kurz ist sollten einfach die letzten Werte gesendet werden. Zumindest beim DS18B20 - ich gehe aber mal einfach davon aus, dass das beim S20 genau so ist. Es hilft dabei wie immer das Datenblatt.

Zeitsklave:
Ach so, ich dachte die Wartezeit muss zwischen jedem kompletten Durchlauf sein!

Nein. Man muss zwischen Anforderung und Auslesen warten, weil die Messung und Wandlung Zeit dauert (das haben AD-Wandler so an sich).

Schau dir mal das Datenblatt an:
http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
Die Zeit h√§ngt von der Aufl√∂sung ab. Siehe Seite 8. F√ľr 10 Bit Aufl√∂sung musst du ca. 190ms warten

Ich denke aber auch nicht, dass das hier das einzige Problem ist.

Hallo,

der TS hat den DS18S20, nicht den DS18B20.
Der "S" macht rein 9 Bit Aufl√∂sung und ben√∂tigt eine Wartezeit von 750ms. Ich w√ľrde 800ms verwenden.

Man kann sicherlich ohne Pause hintereinander weg die letzte Temperatur auslesen. Geht aber ein neuer Request voraus muß man die Conversion Time einhalten.

Nochwas generelles. Wenn jemand ein Problem hat was er selbst nicht l√∂sen kann und nicht bereit ist seinen gesamten Sketch offen zu legen, wie soll man ihn dann helfen. Denn der Fehler liegt meistens nie in den ohnehin nichts sagenden Code Schnipsel, sondern woanders. Ob ein anderer im fremden Code den Durchblick bekommt, ist ein anderes Thema. Es gibt aber √ľberall Experten die das k√∂nnen. Nur so kann man schnelle und gezielte Hilfe bekommen. Zur Zeit eiern wir n√§mlich nur um den hei√üen Brei herum.

Wenn die Keramikkondensatoren Sinn machen sollen, dann an jeden Sensor einen. So 220nF. Vorrausgesetz, es liegt kein anderes Problem vor. Aber probieren kann man es.

ARG! Wieso m√ľssen die auch so √§hnlich hei√üen :blush:

Der Fehler wird aber irgendwie in der Stromversorgung oder Kommunikation liegen. Störungen können da in der Tat eine Rolle spielen. Irgendwie hängt sich wohl der Chip auf und wenn man die Spannung wegnimmt und wieder anliegt macht man praktisch einen Reset.

Hallo,

mach dir nichts draus, kann jeden passieren. Du und andere korrigieren mich auch wenn ich daneben liege. :wink:

Vielen Dank schonmal f√ľr die ganzen Antworten :slight_smile:

@Doc_Arduino … OK, wenn du dir das wirklich antun willst :smiley: ich hänge mal mein komplettes Sketch an, nur die Adressen und so in der Netzwerkconfig hab ich rausgenommen.

Die Verzögerung beim Auslesen hab ich noch nicht eingetippt, und auch ein paar andere Sachen sind noch nicht wirklich fertig, aber so läuft das Sketch momentan in meinem Heizungsraum.

heizung_V2_3.zip (6.16 KB)

Hallo,

hab's mal angeschaut, blicke aber nicht ganz durch. Du liest Deine Sensoren im setup aus. Hier mit festen delays. okay. In loop finde ich keine erneute Abfrage der Sensoren. Du hast eine Sensoren Auslesefunktion namens "Sensor_lesen". Die ich nirgends zum Aufruf wieder finde. Resetest Du den Arduino nach jeden Durchlauf?
Eine Stichwortartige Erklärung was der Code macht oder machen soll wäre jetzt nicht falsch. :wink:

Dann versuch ich das mal zusammen zu fassen :wink:

Die delays im Setup st√∂ren hier nicht, die Startphase dauert dann halt ein bisschen aber so oft soll die ja (eigenlich) nicht passieren. Zweck des Auslesens hier ist eigentlich nur dass ich 1. sofort den richtigen Wert in den Variablen hab und ihn direkt anzeigen kann, und 2. hab ich festgestellt dass die Sensoren beim ersten Auslesen prinzipiell 85¬į ausgeben, warum auch immer. Deswegen der etwas unst√§ndliche Aufbau.
Zum schluss wird in der setup noch loadme() aufgerufen, die aus dem EEPROM liest was das Display anzeigen soll. Das wurde widerum 10 Minuten nach dem letzten Tastendruck mit saveme() gespeichert.

In der loop wird nun:

  • jede Sekunde Display_aktualisieren() ausgef√ľhrt, hier werden die aktuellen Daten ins Display geschickt.
  • jede Minute handle_kommunikation() ausgef√ľhrt, hier werden die sensoren ausgelesen und Daten ins Internet geschickt, s.u.
  • Daten_empfangen() oder verbindung_trennen() ausgef√ľhrt, je nachdem ob eine Antwort vom Server kommt oder ein timeout von 10sec vergangen ist.
  • gepr√ľft ob werte ins EEPROM geschrieben werden sollen
  • s√§mtliche Taster √ľberpr√ľft
  • geschaut ob der ausgang geschaltet werden muss
  • und der Status vom Kessel √ľberpr√ľft.

Die Funktion reset_me() wird momentan nur per Tastendruck ausgef√ľhrt, ich dachte eigentlich ich verwende sie als notl√∂sung f√ľr den Absturz (die dann jedesmal wenn erkannt wird dass die Sensoren 0¬į messen automatisch gestartet wird), aber weder asm volatile (" jmp 0"); noch ein Pinout am Reset-pin brachten Abhilfe. WDT funktioniert ja mit meinem Bootloader leider √ľberhaupt nicht (h√§tte hier aber auch nicht gewirkt). Eine m√∂glichkeit w√§re noch die Stromversorgung kurz per Relais-Ausgang zu unterbrechen‚Ķ Nicht sch√∂n, aber wirkungsvoll.

strom_zaehlen() wird per Interrupt aufgerufen, der vom Optokoppler-ausgang des Stromzählers aktiviert wird. Mir fällt auf dass ich in der Funktion recht oft millis() aufrufe, ist eigentlich auch nicht so schön…

handle_kommunikation() tut jetzt folgendes:

  • Sensor_lesen() : hier werden nun endlich die Sensoren ausgelesen :wink:
  • Daten_senden() : Die neuen Daten an den Server schicken und das Timeout f√ľr die Verbindung einschalten
  • reset_lcd() : Ein sehr unsch√∂ner Workaround der eigentlich nur lcd.begin(16, 2) ausf√ľhrt und dann direkt zu Display_aktualisieren() weiterspringt. Grund hierf√ľr war dass das Display auch hin und wieder abst√ľrzt und nur noch Datenm√ľll anzeigt.

Ich glaub das wars im großen und ganzen.
Vielleicht sollt ich bei dem Umfang, den das Programm inzwischen hat, mal zumindest sämtliche Funktionen mit einer kurzen Beschreibung im ersten Kommentar auflisten. Nur der Übersichtlichkeit halber… Wobei ich mich eigentlich selber recht gut drin auskenne, aber kein wunder, ist ja auch meinem eigenen Hirn entsprungen :grinning:

Edit: Bevor entsprechende Kommentare kommen, nein ich mag keine arrays (sind mir zu undurchsichtig) und ja, ich finde meine eigene code-formatierung sehr √ľbersichtlich; bei code in der ‚Äústandart-schreibweise‚ÄĚ brauch ich sehr lange um durchzublicken :wink:

Hallo,

okay, die Erklärung hilft weiter. Deine Aufteilung in Tabs ist schon okay, finde ich gut.

Wenn Du gleich zu Beginn öfters 85 angezeigt bekommst, dann stimmt etwas grundsätzlich nicht. Vielleicht liegt hier Dein Problem. Falsche Verschaltung der Sensoren?

Hast Du mal die Bsp. der DallasTemperatur Library durchprobiert, ob die funktionieren. Sonst brauchste laut meiner Meinung nicht weitermachen.

So, neue Erkenntnisse :slight_smile:

Ich hab gerade ein bisschen rumgespielt, und das setup um die √ľberfl√ľssigen requests erleichtert:

  sensors.begin();
  sensors.setWaitForConversion(false);
  delay(2000);
  sensors.requestTemperatures();
  delay(1000);
  temp_heizungsraum = sensors.getTempC(addr_heizungsraum);

Funktioniert ganz genauso gut, ich weiß nicht was das war, weswegen ich da mehrere hatte. Also hier gibts schonmal kein Problem.

Die 750ms Verzögerung zwischen sensors.requestTemperatures() und sensors.getTempC() hab ich jetzt auch drin, mal sehen obs was bewirkt.

Mit den Beispielen hatte ich ja angefangen, haben auch super funktioniert, nur dauertests hab ich halt keine :wink:

Mein Verdacht mit den Einstreuungen hat sich ein bisschen verdichtet, ich habe das Gef√ľhl, dass der Absturz manchmal passiert wenn ich abends im Schlafzimmer das Licht ausmache. Ich konnts jetzt momentan nicht reproduzieren (evtl spielen mehrere Faktoren eine Rolle), aber ich werd das beobachten und exakt Zeiten vergleichen.
Mein Schlafzimmer teilt sich eine Wand mit dem Heizungsraum, und es könnte durchaus sein dass ein Kabel vom Lichtschalter bzw vom Licht parallel mit einem Sensorkabel auf der anderen Seite der Wand verläuft. Die Stromstoßschalter sitzen im Sicherungskasten im Keller.

Ich denke ich sollte wirklich die ganze Anlage abschirmen... und vielleicht finde ich eine Möglichkeit auch die Kabel nachträglich zu schirmen, ich möchte sie ungern austauschen. Es war schon ein Haufen Arbeit den Kabelbaum mit den Sensoren zu bauen, vom "einstricken" in den Heizungsraum ganz zu schweigen :frowning:

Was da glaube ich gerne verwendet wird sind Cat5 Netzwerk Kabel. Die gibt es recht billig und man hat gleich einen Schirm dabei.

Also das ganze reagiert definitiv aufs Schlafzimmerlicht.
Und nachdem ich jetzt ein bisschen rumgespielt hab, hab ich festgestellt dass es hilft, kurz die Spannungsversorgung der Sensoren abzuschalten. Der Arduino kann dabei weiterlaufen, wenn man diesen vom Strom trennt und die Sensoren weiter versorgt werden n√ľtzt das gar nix, aber sobald ich die Sensoren ab- und wieder anklemme funktioniert wieder alles.

Das mit dem CAT5 Kabel klingt ganz gut, d√ľrfte auch vom Querschnitt hinkommen, wenn ich je 2 Adern zusammenklemme. Es ist mir nur wahnsinnig zuwider weil die Kabel ziemlich gut in der Heizungsanlage verbaut sind, und das alles ein haufen Arbeit ist ... :frowning: Aber mir wird wohl nichts anderes √ľbrig bleiben wenn ich will dass das zuverl√§ssig funktioniert.

Hallo,

tja, was sollen wir Dir jetzt raten. Entweder pfuschen und die Sensoren vor jeder der Messung immer kurz stromlos schalten oder Kabel wechseln. Ich nicht lustig, ich weis. Aber lege das geschirmte Kabel erstmal parallel zu allen anderen und guck was dann passiert. Bevor Du Wände aufreißt usw.

Hallo,

ein anderer Weg wäre zu schauen, ob man die Schlafzimmerlampe entstören könnte.

Naja, dass ihr mir mein Problem nicht "wegraten" könnt ist leider klar :wink:

Die Pfuschl√∂sung ist erstmal integriert, hatte ja noch 3 freie Reials auf der Schaltung. und jedesmal wenn die Sensoren alle 0¬į liefern wird die Stromversorgung kurz unterbrochen. nicht sch√∂n aber funktioniert.

Trotzdem werd ich was an den Leitungen machen. So schlimm dass ich W√§nde √∂ffnen muss ist es zum Gl√ľck nicht weil da alles in Kabelkan√§len liegt, aber es ist halt ziemlich im Heizungsraum eingeflochten, durch Isolierungen, um Rohre usw.
W√ľrde es denn schon Sinn machen, die Abschnitte zu schirmen die am meisten gef√§hrdet sind? Ich hab gesehen dass sich der letzte Strang, der dann zum Wohnraum durchgeht, sich an einer Stelle direkt mit einem Kabel zum Schlafzimmer kreuzt, ich denke dass da wom√∂glich schon das Problem liegt, deswegen w√ľrd ich da anfangen mit Austauschen!

Ob an der Lampe was Entst√∂rbar ist wei√ü ich nicht, Es sind daf√ľr im Schaltschrank im Keller Kopp-Stromsto√üschalter verbaut, und im Schlafzimmer h√§ngen dann einfach primitive halogen-Stiftsockellampen. Es ist ja alles nach DIN installiert und die Schalter sind Markenger√§te...