[ungelöst erledigt] DS18x20 Abfrage über Userdatabyte - 60ms und mehr

Es soll ja Nutzer geben, die das Userdatabyte benutzen um die Sensoren durchzunummerieren.
Das ist tatsächlich schick, spart man sich die Adressen einzutippen und kann sein Array anhand der Sensornummer füllen.

Was mich jedoch nicht glücklich macht, das ich zur Ermittlung des Userdatabyte und zur Ermittlung der Temperatur jeweils um die 30ms benötige. Hinweis: Der Temperaurrequest erfolgt ausserhalb dieser Zeit.

Das macht je Sensor gutgehend 60ms und bei 15 Sensoren ne Sekunde.
In den DaBla zum DS18S/B20 find ich nicht so richtig was zu den Antwortzeiten.

Ist das Verhalten tatsächlich so und/oder kann man das ggfls. noch irgendwie optimieren?

Aufbau:
Alles Sensoren sind aktiv versorgt - kein ParasitePower.

TestSketch:

// Forumfrage: https://forum.arduino.cc/index.php?topic=699153.msg4698339#msg4698339

#include <DallasTemperature.h> // by Miles Burton Version: 3.7.7
const uint8_t temperaturPin = 4;
const uint8_t temperaturSensoren = 5;
OneWire TSensoren (temperaturPin);
DallasTemperature tempbus (&TSensoren);
float tempsensors[temperaturSensoren] = {};
uint32_t lastmillis;
DeviceAddress adress;

void setup()
{
  Serial.begin (115200);
  while (!Serial);
  tempbus.begin();
  tempbus.requestTemperatures();
  lastmillis = millis();
}

void loop()
{
  if (millis() > 5000) while (1);
  if (millis() - lastmillis > 750)
  {
    uint8_t deviceCount = tempbus.getDeviceCount();           // Ermittlung der Anzahl der Sensoren
    for (uint8_t index = 0; index < deviceCount; index++)
    {
      Serial.println (F ("index: "));                         // Ausgabe Startzeit auf dem SerMon
      tempbus.getAddress (adress, index);                     // ermittle Adresse des Sensors
      Serial.println (index);                                 // Ausgabe für Zeit auf dem SerMon
      uint8_t number = tempbus.getUserData (adress);          // ermittle Userbyte
      Serial.println (F ("sensors "));                        // Ausgabe für Zeit auf dem SerMon
      tempsensors[number] = tempbus.getTempC (adress);        // ermittle °C für Sensor
      Serial.print (number);                                  // Ausgabe Endezeit Userbyte
      Serial.print ("\t");
      Serial.println (tempsensors[number]);                   // Ausgabe Inhalt
    }
    Serial.println ("Starte request");                        // Startzeit request
    tempbus.requestTemperatures();
    Serial.println ("Ende request");                          // Ende
    lastmillis = millis();
  }
}

Ausgabe:

12:17:33.915 -> index: 
12:17:33.948 -> 0
12:17:33.948 -> sensors 
12:17:33.948 -> 0 28.50
12:17:33.948 -> index: 
12:17:33.982 -> 1
12:17:34.015 -> sensors 
12:17:34.015 -> 1 28.50
12:17:34.015 -> index: 
12:17:34.048 -> 2
12:17:34.082 -> sensors 
12:17:34.082 -> 2 28.50
12:17:34.082 -> index: 
12:17:34.148 -> 3
12:17:34.148 -> sensors 
12:17:34.148 -> 3 28.50
12:17:34.181 -> Starte request
12:17:34.248 -> Ende request

So schnell ändern sich Temperaturen nicht. Da genügen 10 Sekunden Messabstand oder mehr.
Warum sollen die Sensoren da Spitzengeschwindigkeiten erzielen.
Wichtig ist die Trennung von Request und Messwert abholen im nicht blockierenden Modus und die hast Du drin, wie ich Deiner Beschreibung entnehme.

Gruß Tommy

Die Frage ist: Was soll genessen werden?

Ich habe über 50 Sensoren im Haus verteilt, die alle über 1-Wire laufen und in eine Datenbank geschrieben werden.

Die Temperaturen werden im Minutentakt geschrieben.
Es würde aber sicherlich auch im 5, oder 15min Takt reichen, je nachdem was man beobachten will.

Beibachtet man den Vor- und Rücklauf der Heizung ist ein 1min Messinterval sinnvoll, dann sieht man schön, wie die Fussbodenheizung misst und entscheided wann geheizt wird.

Lieben Gruß,
Chris

Tommy56:
Da genügen 10 Sekunden Messabstand oder mehr.
Wichtig ist die Trennung von Request und Messwert abholen im nicht blockierenden Modus und die hast Du drin

Die Auswertung erfolgt tatsächlich in noch grösseren Abständen .
Wir haben das heute morgen mit einem Produktivsystem durchgespielt und festgestellt, das für 1,5 Sekunden der Sketch im übernehmen der Temperaturen verharrt.

Wenn man das ganze über die Adresse macht, ist das nicht so.
Zum Vergleich “Multiple” aus dem Example genommen und nur die Zeilen “printData …” im loop vorher und nachher von einem Serial.Println() eingeschlossen, erledigt das (für zwei Sensoren) in der selben ms.

Da im Sekundentakt wechslende Ausgaben gemacht werden ist das nicht so schön.
Jetzt sind wir am überlegen, ob wir das anders lösen und in jedem Umlauf nur einen Sensor auslesen.

Vielleicht ergibt sich ja noch was.

themanfrommoon:
Ich habe über 50 Sensoren im Haus verteilt, die alle über 1-Wire laufen und in eine Datenbank geschrieben werden.

Die Temperaturen werden im Minutentakt geschrieben.

Es ist nicht die Frage was und in welchem Intervall gemessen werden soll.
Beim umstellen des Ansprechen der Sensoren über die Adresse des Sensors auf Ansprechen über das Userbyte, steigt das Timing von 0ms auf 60-70ms für jeden Sensor.

Damit blockiert der Sketch, trotz entsprechender Vorkehrungen für das Abfrageintervall.

Evtl. könnte man im Setup ein Array der Adressen und zugehörigen der Userbytes aufbauen und dann über die Adressen die Temperatur auslesen. Das zugehörige Userbyte hat man ja dann bereits.

Gruß Tommy

Was genau soll denn gemacht werden?

Ich messe wie gesagt fast auf 100 Kanälen Temperaturen, Luftdruck, Luftfeuchtigkeit, Wasserzähler, Stromzähler, Lüfterdrehzahlen usw. Die Daten werden in eine Datenbank eingetragen. Dann kann man mit verschiedenen Frontends auf die Daten zugreifen und diese nach belieben anzeigen und auswerten.
Das ganze läuft auf einem Raspberry Pi und die Auswertung und Anzeige geht über den PC, Smartphone und ESP8266 mit Display.
Und zwar läuft das schon ein paar Jahre.

Man könnte die Daten auch nehmen um irgendwelche Steuerungen damit zu bauen.

Is halt die Frage was man genau machen will.

Was soll denn genau gemacht werden?

Lieben Gruß,
Chris

my_xy_projekt:
Es ist nicht die Frage was und in welchem Intervall gemessen werden soll.
Beim umstellen des Ansprechen der Sensoren über die Adresse des Sensors auf Ansprechen über das Userbyte, steigt das Timing von 0ms auf 60-70ms für jeden Sensor.

Damit blockiert der Sketch, trotz entsprechender Vorkehrungen für das Abfrageintervall.

my_xy_projekt:
Es ist nicht die Frage was und in welchem Intervall gemessen werden soll.
Beim umstellen des Ansprechen der Sensoren über die Adresse des Sensors auf Ansprechen über das Userbyte, steigt das Timing von 0ms auf 60-70ms für jeden Sensor.

Damit blockiert der Sketch, trotz entsprechender Vorkehrungen für das Abfrageintervall.

Klar ist das relevant.
Wenn man was ähnliches vor hat wie ich oben ist das vielleicht nicht das richtige Konzept.
Wechselt man das Konzept ist, dann ist das Problem gar nicht mehr existent.
Heute ist es vielleicht nur die Temperaturmessung, aber dein Fernziel ist in Wirklichkeit Daten von deinem Haus zu loggen. Und da wäre das bessere Konzept dann z.B. das Open-Source www.volkszahler.org Projekt, dass du möglicherweise noch nicht kennst.

Lieben Gruß,
Chris

themanfrommoon:
Klar ist das relevant.

Und da wäre das bessere Konzept dann z.B. das Open-Source www.volkszahler.org Projekt, dass du möglicherweise noch nicht kennst.

Nein es ist nicht relevant was ich damit machen will.
Ganz klar oben beschrieben, das im Sekundentakt eine Ausgabe erfolgt und die jetzt in der Form nicht mehr funktioniert.

Und ja, ich kenne die eine oder andere technische Alternative.
Das ist z.B. auch der Grund warum ich (auch hier) jedem von Stromsensoren in Verteilungen abrate und (Rollen-)zähler mit S0-Schnittstelle empfehle.

Und in der hiesigen Installation ist mehr als ne Handvoll davon verbaut.

Trotzdem Danke!

Kurzes Zwischenfazit:

Ich bin mir noch nicht sicher, wie das Problem umschifft werden kann, eine Praxistaugliche Lösung gibt es, aber ist nicht schön.

Tommy56:
Evtl. könnte man im Setup ein Array der Adressen und zugehörigen der Userbytes aufbauen und dann über die Adressen die Temperatur auslesen. Das zugehörige Userbyte hat man ja dann bereits.

Wäre ne Idee. Und überlegenswert.
Zwischenzeitlich den Code geändert:
Mit jedem Umlauf wird ein Sensor gelesen. Zusätzlich im Setup:
tempbus.setWaitForConversion (false);
da ich selbst die Wartezeit bestimme.

// Forumfrage: https://forum.arduino.cc/index.php?topic=699153.msg4698709#msg4698709

#include <DallasTemperature.h> // by Miles Burton Version: 3.7.7
const uint8_t temperaturPin = 4;
const uint8_t temperaturSensoren = 5;
OneWire TSensoren (temperaturPin);
DallasTemperature tempbus (&TSensoren);
float tempsensors[temperaturSensoren] = {};
uint32_t lastmillis;
DeviceAddress adress;

void setup()
{
  Serial.begin (115200);
  while (!Serial);
  tempbus.begin();
  tempbus.requestTemperatures();
  tempbus.setWaitForConversion (false);
  lastmillis = millis();
}

void loop()
{
  if (millis() > 5000) while (1);
  if (millis() - lastmillis > 750)
  {
    static uint8_t index = 0;
    uint8_t deviceCount = tempbus.getDeviceCount();           // Ermittlung der Anzahl der Sensoren
    if (index < deviceCount)
    {
      Serial.println (F ("index: "));                         // Ausgabe Startzeit auf dem SerMon
      tempbus.getAddress (adress, index);                     // ermittle Adresse des Sensors
      Serial.println (index);                                 // Ausgabe für Zeit auf dem SerMon
      uint8_t number = tempbus.getUserData (adress);          // ermittle Userbyte
      Serial.println (F ("sensors "));                        // Ausgabe für Zeit auf dem SerMon
      tempsensors[number] = tempbus.getTempC (adress);        // ermittle °C für Sensor
      Serial.print (number);                                  // Ausgabe Endezeit Userbyte
      Serial.print ("\t");
      Serial.println (tempsensors[number]);                   // Ausgabe Inhalt
      index++;                                                // Index erhöhen
    }
    else
    {
      Serial.println ("Starte request");                      // Startzeit festhalten
      tempbus.setWaitForConversion (false);
      tempbus.requestTemperatures();
      Serial.println ("Ende request");                        // Ende
      lastmillis = millis();
      index = 0;
    }
  }
}

Ausgabe:

17:43:45.845 -> index: 
17:43:45.845 -> 0
17:43:45.878 -> sensors 
17:43:45.878 -> 0 36.00
17:43:45.878 -> index: 
17:43:45.911 -> 1
17:43:45.954 -> sensors 
17:43:45.954 -> 1 37.00
17:43:45.954 -> index: 
17:43:45.978 -> 2
17:43:46.017 -> sensors 
17:43:46.017 -> 2 37.50
17:43:46.017 -> index: 
17:43:46.079 -> 3
17:43:46.079 -> sensors 
17:43:46.113 -> 3 36.00
17:43:46.113 -> Starte request
17:43:46.113 -> Ende request

Ich muss hier nochmal einhaken:

themanfrommoon:
Ich habe über 50 Sensoren im Haus verteilt, die alle über 1-Wire laufen und in eine Datenbank geschrieben werden.

Die Temperaturen werden im Minutentakt geschrieben.

Das stellt niemand - und ich schon garnicht - infrage.
Dann sind es eben 3 oder vielleicht auch 4 Sekunden.
Das ist weder zeitkritisch noch ausschlaggebend für DEINE Anwendung.
Deiner Umgebung ist es egal, ob if (aktuelleMinute != letzteMinute) um 20:15:00 oder 20:15:45 eintritt.

Denke mal drüber nach, was derjenige macht, der in seinem LCD die Zeit mitlaufen lässt - ja, ist nicht kritisch, wenn mal 2 Sekunden ausfallen.

Wer aber auf if (letzteSekunde != aktuelleSekunde) prüft oder gar noch weniger und darauf angewiesen ist, der hat ein ernstaftes Problem.

Mich würde ja mal interessieren, was passiert, wenn Du den Sketch über Deine 50 Sensoren laufen lässt.
Das wäre bei jedem Umlauf um die 4, wohl eher auch 5 Sekunden.

Damit wird der regelmäßige "vermeide delay()" - Aufruf ad absurdum geführt.
Dann kann auch für 20ms nach der Tastenabfrage gewartet werden.
Wenn auf dem ARDUINO ein Webserver läuft, ist das noch viel interressanter. Über 5 Sekunden warten im lokalen LAN - Seiten aus Japan im Handumdrehen.

Du siehst also, die Anwendung als solche kann alles Mögliche sein. Und nein, eine Raspberry als Ersatz für einen Webserver auf einem funktionierendem ARDUINO-System ist KEINE Lösung.

...meine Zeit auf dem Display, welches von ESP8266 angesteuert wird läuft auch im Sekundentakt fehlerfrei ohne Verzögerung oder Verschleppung...

themanfrommoon:
...meine Zeit auf dem Display, welches von ESP8266 angesteuert wird läuft auch im Sekundentakt fehlerfrei ohne Verzögerung oder Verschleppung...

Mit Nutzung des Userdatabyte zur

  • Sensorauswahl?
    Ja/Nein
  • Messwertübertragung?
    Ja/Nein
    Edit:
  • Mit 50 Sensoren
    Ja/Nein
  • in der selben Sekunde?
    Ja/Nein

Das zwischen Euch Beiden wird langsam Kindergarten.
Jeder hat seine eigenen Präferenzen und Abläufe. Die kann man nicht gegeneinander aufrechnen.

Gruß Tommy

Tommy56:
Das zwischen Euch Beiden wird langsam Kindergarten.

Danke für den Hinweis.

Das eigentliche Thema bleibt aber interessant.

Gruß Tommy

...ich weiss auch nicht, ob der TO die passende Problemstellung für meine Lösung hat. Das hat er ja bisher nicht verraten, was er messen will und was er damit anfangen will. Wahrscheinlich gibt's dafür auch noch ne Menge andere Lösungen.

Möglicherweise könnte auch der Umstieg auf einen ESP32 eine Lösung sein. Da dieser zwei Kerne hat, kann man vielleicht die Uhr auf dem einen Kern und die Temperatursensoren auf dem anderen Kern laufen lassen. Kostet deutlich unter 10,-€ und ist sicherlich einen Versuch wert. Hab ich selber zwar noch nicht gemacht, könnte aber funktionieren.

Lieben Gruß,
Chris

Tommy56:
Das eigentliche Thema bleibt aber interessant.

Ich habe mich heute wiederholt mit der Thematik beschäftigt.

Es gibt hier eine Übereinkunft, das in der nächsten Woche ein erneuter Anlauf genommen wird.
Bis dahin werde ich Deinen Ansatz:

Tommy56:
Evtl. könnte man im Setup ein Array der Adressen und zugehörigen der Userbytes aufbauen und dann über die Adressen die Temperatur auslesen. Das zugehörige Userbyte hat man ja dann bereits.

mal in Code tackern.

Leider komme ich nur noch zweimal - und das auch nur für eine sehr begrenzte Zeit - dazu, das als Test unbeschadet in einem Livesystem einzuspielen.
Und ja, ich hab mir mal ne Handvoll mehr DSer bestellt....

Danke für den Gedankengang.