Go Down

Topic: DS18b20 mit ESP32 wird durch Wifi gestört (Read 8816 times) previous topic - next topic

Tommy56

In Deinem Code ist nichts vom 10-Sekunden-Takt zu sehen.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Wiki_

Moin,

öhm:

Code: [Select]

 for (int i = 1; i < 101; i++)           // Etwas sinnvolles tun
  {
    sensorValue0 = analogRead(sensorPin0);
    Volt0 = Volt0 + sensorValue0;
    sensorValue1 = analogRead(sensorPin1);
    Volt1 = Volt1 + sensorValue1;
    sensorValue2 = analogRead(sensorPin2);
    Volt2 = Volt2 + sensorValue2;
    sensorValue3 = analogRead(sensorPin3);
    Volt3 = Volt3 + sensorValue3;
    delay(10);
  }


Danke für den Hinweis. Hast recht, 100 Schleifen mit jeweils 10 ms delay sind keine zehn Sekunden, sondern nur eine. Hatte da iwas im Kopf, was nicht stimmt, man sollte schon in der Lage sein, den eigenen Code zu lesen - zumindest was so eine popelige Schleife anbelangt.

In Summe heisst das, wenn pro Sensor 750 ms benötigt werden, dass ich zu schnell unterwegs bin. Hmmmm, werd mal die millis() zu Rate ziehen, um die Abfrage der Sensoren zu takten.

Tommy56

Versuche mal rauszufinden, ob der nichtblockierende Modus auch parasitär funktioniert. Wenn ja, dann Messung anfordern und nach 1 Sekunde Messwerte holen, ansonsten Pech gehabt.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Wiki_

#18
Dec 06, 2017, 02:30 pm Last Edit: Dec 06, 2017, 02:49 pm by Wiki_
Moin,

@Tommy: was heist "nichtblockierender Modus"? [edit] Schon gefunden (WaitforConversion(), richtig?)[/edit]

q&d hab ich auf die Schnelle das delay in der Schleife auf 50ms gesetzt, damit hab ich eine Zeitverzögerung von 5 Sekunden zwischen Anforderung der Daten und der Abfrage.

Geändert hat sich nix, Werte kommen nur sporadisch, manchmal erst nach mehreren Minuten im Zufallsprinzip. Im seriellen Log sehe ich, für die lib sind die Sensoren entweder überhaupt nicht erreichbar (nix kann gelesen werden), es kommt als Wert -127 zurück oder eben halt sporadisch der korrekte Wert.

Dann hab ich q&d die Wifi-Funktion auskommentiert (die ich aber benötige). Es kommen sauber und stabil alle fünf Sekunden die Temperaturdaten von allen vier Sensoren an. D.h., es ist genügend Zeit für die Antwort der Sensoren vorhanden, am Timing lieegts also eher nicht.

In Summe sieht es für mich also so aus, dass die Kommunikation mit den parasitär mit 3,3V gespeisten Sensoren bei laufendem Wifi empfindlich gestört wird. Da die I/O Pins des ESP32 nicht 5V-tolerant sein sollen und ich keine Möglichkeit zur separaten Spannungsversorgung der Sensoren hab, muss ich wohl ersteinmal damit leben.

Wie ich schon schrub: Schade, trotzdem Dank @all für die Hilfestellungen.

Auf jeden Fall hab ich schonmal gelernt, dass 100x10=1.000 ist und !=10.000  :-*

ElEspanol

Hab gerade das nochmal mit einem nodemcu mit wifi on durchgetestet.
Bei parasiärer Versorgung über D6 und 1k Pullup geht es mit nur einem Sensor. Bei 2en kommt 127.94 bei beiden als Messung

Tommy56

Kann es sein, dass Du Deinen Sketch auf analogRead() geändert hast? Das wird für den DS1820 nix.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

ElEspanol

#21
Dec 06, 2017, 03:47 pm Last Edit: Dec 06, 2017, 04:21 pm by ElEspanol
Weitere Erkenntnisse:
2 x ds18b20, parasitär an D6 nodemcu, 1k pullup, gehen nicht. Erhöhe ich jedoch die Spannung für den Pullup (NICHT für den nodemcu) von 3,3V auf 3,9V, geht es wie es soll.
dto. mit 1.5k Pullup geht nicht mehr, da brauchts dann min. 4,4V am Pullup

mit 600 Ohm geht es bei 3,3V, bei 3,25V schon nicht mehr

Wiki_

Kann es sein, dass Du Deinen Sketch auf analogRead() geändert hast? Das wird für den DS1820 nix.

Gruß Tommy
Moin,

nö, für die DS18B20 wäre das mal ein echt sportlicher Ansatz, haste Recht. analogRead() sind die Spannungsmessungen. In der i 1 to 100 werden die Messwerte von den vier ADC summiert, daraus bilde ich danach den Mittelwert. Ansonsten sind die Einstörungen zu groß, so funktionierts recht gut. Mit dem delay(50) hab ich zwischen Messwert anfordern und auslesen eine Verzögerung von 5 Sekunden. Sorry für die Irritation, hier nochmal die komplette void loop():


Code: [Select]

void loop()
{
  Volt0=0;
  Volt1=0;
  Volt2=0;
  Volt3=0;

  sensors.requestTemperatures();          // Messanforderung

  for (int i = 1; i < 101; i++)           // Etwas sinnvolles tun
  {
    sensorValue0 = analogRead(sensorPin0);
    Volt0 = Volt0 + sensorValue0;
    sensorValue1 = analogRead(sensorPin1);
    Volt1 = Volt1 + sensorValue1;
    sensorValue2 = analogRead(sensorPin2);
    Volt2 = Volt2 + sensorValue2;
    sensorValue3 = analogRead(sensorPin3);
    Volt3 = Volt3 + sensorValue3;
    delay(50);
  }
  Volt0=ADCKorrektur(Volt0/100);          // Nicht-Linearität des ESP32 grob geradeziehen
  Volt1=ADCKorrektur(Volt1/100);
  Volt2=ADCKorrektur(Volt2/100);
  Volt3=ADCKorrektur(Volt3/100);

  for(int i=0;i<numberOfDevices; i++)     // Schleife zum Auslesen der Temperaturen
  {
    if(sensors.getAddress(tempDeviceAddress, i))
    {

      float tempC = sensors.getTempC(tempDeviceAddress);  // Temperaturen holen

      temp[i]=tempC;
      Serial.println(temp[i]);
      delay(30);
    }
  }
  VoltSchreiben(Volt0, Volt1, Volt2, Volt3, temp);
  webif();                                   // Web-Schnittstelle abfragen, ob ein request vorhanden
}


@ElEspanol: Danke für Deine Mühe, ist wohl zwar mit dem ESP8266, gibt mir aber noch ne Idee für mein ESP32 DevBoard.

Ich hab als pullup 4,7k an 3,3V, streng nach Dokumentation. Werde heute abend mal mit kleinerem Widerstand versuchen, wirklich gute Idee.

Ich werd berichten...

Wiki_

Moin,

aso mehrere Pullup-Widerstände bis runter auf 470ohm probiert, das Thema bleibt.

Nach jedem Tausch des Widerstandes immer quergecheckt mit ausgeschaltetem WLAN, dann funktionieren die Dallas - immer, stabil und akkurat.

Fazit: der ESP32 ist nen blödes Teil. Gibt mir zwar ne große Anzahl an ADC (die ich nunmal brauche), Wifi (das ich numal brauche), viel Speicher (den ich zukünftig brauchen werde), geniale Energiesparfunktionen (die ich zukünftig brauchen werde), Bluetooth (ist bei mir auf der Wunschliste), aber die völlig daneben liegenden nicht-linearen Werte der ADC-Ports sowie das jetzige Theater mit dem oneWire und Wifi veranlasst mich zu folgender Aussage:

Sobald Ihr etwas komplexes verwirklichen wollt, lasst die Finger vom ESP32. Als Webserver genial, da viel Speicher und mittlerweile SPIFFS, aber ansonsten für IoT völlig unbrauchbar - auf unterstem Entwicklungsstand auf den Markt geworfener Schrott.

Da ich bei meiner Batterieüberwachung keine Realtime-Werte benötige und bei der Spannungsmessung nix unheimlich genaues bei rumkommen muss, werd ich damit leben und ein Workaround für die Webinfo schaffen, indem ich das Alter der Daten mit anzeige.

Es sei denn, es meldet sich jemand, der mit dem ESP32 oneWire zusammen mit Wifi ans Laufen bekommen hat.

Dank Euch allen für die Infos und Ideen, ich geb an dieser Stelle jetzt auf. Schliesslich ist die Überwachung von vier in Serie geschalteten Bleiakkus keine schwarze Magie und letzendlich nicht so unheimlich zeitkritisch.

Gruß Wiki

combie

Quote
Schon die beliebten Keramikkondensatoren großzügig z.B. bei den DS18B20 verbaut (sofern möglich)
Wie soll das denn gehen?
Damit tötest du jegliche Kommunikation mit den Dingern.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

SkobyMobil

#25
Dec 07, 2017, 10:56 am Last Edit: Dec 07, 2017, 10:57 am by SkobyMobil
Hallo,
ich bin der Meinung, Du hast hier immer noch ein TimingProblem.

Das halte ich für gefährlich und unberechenbar:
Code: [Select]
for (int i = 1; i < 101; i++)           // Etwas sinnvolles tun
  {
    sensorValue0 = analogRead(sensorPin0);
    Volt0 = Volt0 + sensorValue0;
    sensorValue1 = analogRead(sensorPin1);
    Volt1 = Volt1 + sensorValue1;
    sensorValue2 = analogRead(sensorPin2);
    Volt2 = Volt2 + sensorValue2;
    sensorValue3 = analogRead(sensorPin3);
    Volt3 = Volt3 + sensorValue3;
    delay(50);
  }

Es reicht vollkommen den Port nur EINMAL zu lesen. Dieses delay(50) ist völlig
fehl am Platz.

Das hier:
Code: [Select]
  for(int i=0;i<numberOfDevices; i++)     // Schleife zum Auslesen der Temperaturen
  {
    if(sensors.getAddress(tempDeviceAddress, i))
    {

      float tempC = sensors.getTempC(tempDeviceAddress);  // Temperaturen holen

      temp[i]=tempC;
      Serial.println(temp[i]);
      delay(30);
    }
  }
  VoltSchreiben(Volt0, Volt1, Volt2, Volt3, temp);
  webif();                                   // Web-Schnittstelle abfragen, ob ein request vorhanden
}

Auch hier ist das delay(30) wieder völlig überflüssig, bringt nichts.
Auch sehe ich keine Zeit, die benötigt wird um die Sensoren zu lesen.
Dein Code besteht hier ja nur aus Schnipsel.

Ich würde da noch einmal anders rangehen.
Erst die analogen Port´s einmal lesen, einen nach dem anderem.
Die Werte dann in eine Variable speichern.
Dann die digitalen Sensoren einmal lesen, einen nach dem anderem.
Die Werte dann in eine Variable speichern.

DAFÜR GEHEN MINDESTENS 3 SEKUNDEN BEI DRAUF!

Wenn Du dann die acht Variablen gefüllt hast, dann erst würde ich die Werte
an WiFi übergeben.
Wenn WiFi dann fertig ist, wieder vorne beginnen.
WiFi ist langsam und Deine digitalen Sensoren sind noch langsamer.
Bei Dir rauscht das aber alles durch.

Das, was Du da vor hast, funktioniert einwandfrei ohne Problem- wenn man es
richtig macht!
Gruß und Spaß
Andreas
die zweite Maus bekommt den Speck...

Wiki_

Hallo,
ich bin der Meinung, Du hast hier immer noch ein TimingProblem.
Moin,

nö. Hatte ich auch nie, das Timing wird von der Library DallasTemperature.h abgefackelt, solange der Wert waitForConversion nicht gesetzt ist, da hat mich Tommy56 draufgebracht. In der lib werden die Timeouts sauber nach gesetzter Auflösung abgearbeitet, ich kann da nicht zu schnell sein.


Das halte ich für gefährlich und unberechenbar:
Code: [Select]
for (int i = 1; i < 101; i++)           // Etwas sinnvolles tun
  {
    sensorValue0 = analogRead(sensorPin0);
    Volt0 = Volt0 + sensorValue0;
    sensorValue1 = analogRead(sensorPin1);
    Volt1 = Volt1 + sensorValue1;
    sensorValue2 = analogRead(sensorPin2);
    Volt2 = Volt2 + sensorValue2;
    sensorValue3 = analogRead(sensorPin3);
    Volt3 = Volt3 + sensorValue3;
    delay(50);
  }

Es reicht vollkommen den Port nur EINMAL zu lesen. Dieses delay(50) ist völlig
fehl am Platz.
Wenn Du Dich schonmal mit den ADC des ESP32 auseinandergesetzt hättest, dann wüsstes Du wozu ich diesen Blödsinn mache. Es kommt kein konstanter Wert rein, erst der Mittelwert bring nutzbare Ergebnisse. delay(50) dient rein dazu, die Zeit zum Sammeln der Werte zu strecken. Glaub mir, ich hab lang daran herumgedoktert.

Auch sehe ich keine Zeit, die benötigt wird um die Sensoren zu lesen.
s.o., macht die lib bei der Anforderung der Messwerte, hier ist es nicht mehr zeitkritisch, da die Werte mittlerweile gefüllt sind.

Wenn Du dann die acht Variablen gefüllt hast, dann erst würde ich die Werte
an WiFi übergeben.
Wenn WiFi dann fertig ist, wieder vorne beginnen.
WiFi ist langsam und Deine digitalen Sensoren sind noch langsamer.
Bei Dir rauscht das aber alles durch.
Da rauscht nix durch, der geneigte Leser meines Codes im ersten Post mag registriert haben:

Code: [Select]

WiFiServer server(80);

[..]

void loop(){

[..]

webif();
}


Der ESP32 spielt Webserver. Die Werte sind in den Variablen Volt0...Volt3 und temp[] gespeichert und werden im Web-Interface auf Anforderung präsentiert.

Und da liegt imho genau das Problem, da für den Serverbetrieb die Wifi-Schnittstelle durchgehend aktiv ist. Würd ich das Ding als Client verwenden der nur ein paarmal sendet, hätte ich das Thema wohl nicht. Ich habs schon ein paarmal geschrieben: Sowohl die Messung der Spannungen als auch die der Temperaturen funktionieren einwandfrei, stabil und akkurat. Die Mittelwertbildung der analogen Signale funktioniert klaglos und gibt mir nutzbare Ergebnisse, die Sensoren werden einwandfrei ausgelesen. Erst die Aktivierung der (Server-)Wifi-Schnittstelle bringt den Ärger ein.

Eins sei mir bitte zum Schluss gestattet. Das:

Das, was Du da vor hast, funktioniert einwandfrei ohne Problem- wenn man es
richtig macht!
nehm ich persönlich.

SkobyMobil

Hallo,
der Schuh paßt Dir…

"delay(50) dient rein dazu, die Zeit zum Sammeln der Werte zu strecken"

Da wird nichts gesammelt und gestreckt, hier wird genau nichts- gemacht.

" Es kommt kein konstanter Wert rein, erst der Mittelwert bring nutzbare Ergebnisse"

Es ist absolut kein Problem am analogen Eingang ein konstanten Wert zu lesen.
Und Mittelwert- ist der falsche Weg, um hier ein nicht- geschätzten Wert zu
erhalten.

Also, viel Spaß noch bei Deinem Projket.
Gruß und Glück
Andreas
die zweite Maus bekommt den Speck...

postmaster-ino

Hi

Hattest Du schon probiert, die DS18B20 auf einen anderen Pin/anderes Port zu setzen?
Wenn Das auch nicht hilft, spucken sich diese beiden Funktionen gegenseitig in die Suppe!
Nicht mehr, aber auch nicht weniger.
Wie viele DS18B20 musst Du in welcher Zeit abfragen?
Kann man der Dallas-Lib auch sagen, daß ALLE DS18B20 die Temperatur konvertieren sollen?
(also per SkipRom, convertTemp)
Hätte den Vorteil, daß man EIN MAL diese 750ms warten muß, da alle Sensoren gleichzeitig die Generierung vornehmen - möglich, daß hier dann im parasitären Modus ein Leitungslängenproblem auftritt, da die Sensoren dafür halt etwas Strom brauchen - äh, Stichwort: wird das Port ggf. vom Wifi-Teil abgeschaltet? Dadurch würden die Sensoren keinen Strom mehr haben und somit nicht mehr fähig, die Temperatur herzuleiten - das anschließende Auslesen liefert dann -> Müll.

Alternativ:
Man kann das ganze Gelump auch zu Fuß machen (wobei mir nocht bekannt ist, wie genau man in C selber zeitkritische Abläufe steuern kann) - eben mit der Möglichkeit, per SkipRom, ConvertTemp der ganzen Bargage gleichzeitig zu Befehlen, die Temperatur herzuleiten.
Das Auslesen ist dann nur noch abhängig vom 1-wire-Bus und sollte vernachlässigbar kurz ausfallen.

Zumindest den Convertierungsbefehl könnte man als Inline-Assembler raus hauen - dann kann man beim Auslesen auf jegliche Pause verzichten.

MfG

Wiki_

Moin,

jo, mehrere Ports ausprobiert. Ergebnis immer dasselbe: ohne Wifi prächtig, mit Wifi Zufall.

Ich frage zZt. vier Dallas ab, dafür dient die Schleife

Code: [Select]

  for(int i=0;i<numberOfDevices; i++)     // Schleife zum Auslesen der Temperaturen
  {
    if(sensors.getAddress(tempDeviceAddress, i))
    {
      float tempC = sensors.getTempC(tempDeviceAddress);
      temp[i]=tempC;
      delay(30);
    }
  }


Dabei wird die im setup ermittelte Anzahl der Sensoren nacheinander abgefragt. Wieviele Sensoren dran sind hab ich nicht fest auf die schon vorhandenen Sensoren verdrahtet sondern offen gelassen, da vllt. Umgebungstemperatur und solch profane Infos wie Vorlauftemperatur der Heizung später mal dazukommen könnten. Dann brauch ich nur in der Webseite weitere im Array gespeicherten Daten ausgeben, ohne die Auslesefunktion zu ändern.

Zeitlich ist die Messung in diesem Anwendungsfall völlig unkritisch. Die Sensoren kleben an vier 12V Bleiakkus. Was ich wissen will ist, ob einer der Blöcke in der Volladungs- oder Ausgleichsphase temperaturmässig aus dem Ruder läuft. Oder bei tieferen Entladungen zu weit einbricht. Und Bleiakkus ändern ihren Zustand nicht im Millisekunden- sondern im Minutenbereich. Genauso mit der Spannung, auch da hab ich eigentlich alle Zeit der Welt. Von daher hab ich absolut kein Problem, auf die Antwort der lib zu warten, in diesem Fall sind das drei Sekunden.

Der Dallas Lib sage ich mit requestTemperatures(), sie möge alle ihr erreichbaren Sensoren anstossen, funzt auch prächtig. Die lib blockiert derweil - abhängig von der eingestellten Genauigkeit - den Fortlauf vom Programm. Das ist gut so, denn ich muss mich dann nicht ums Timing kümmern - ist schon smart.

Zu Fuß könnte ich den Klumpatsch schon abfackeln. Dafür gibts das Keyword waitForConversion() in der lib. Wenn auf false, blockiert die lib nicht und ich hätte das Timing selbst in der Hand. Will ich nicht, ich lass der lib gern die Kontrolle.

Imho gibt es hier kein Timing-Problem, das Auslesen der Dallas ist popelig einfach und die Abfrage eines A/D Wandler profan. Die Dallas-Sensoren sind völlig unschuldig an meinem Problem. Dass selbst espressif für ihre eigene IDE eine Lib zum "Kalibrieren" der A/D-Wanlder zur Verfügung stellt deutet für mich darauf hin, dass in der Hardware selber diverse Probleme mit eingebaut sind. So kann zB niemand genau sagen, in welcher Hertsellungs-Charge welche Referenzspannung intern vorhanden ist - in meinen Augen ein absolutes Unding. Dazu noch die Tatsache, dass die Ausgabe der A/D-Wandler nicht linear ist, ich muss eine umfangreiche Tabelle zurate ziehen, um lineare Werte zu generieren. In meinen 30 Jahren Handling von A/D Wandlern ist mir soetwas noch nicht untergekommen. Und ja, ich weiss, Dallas wird nicht analog abgefragt ;-).

Ich gehe mittlerweile davon aus, dass die I/O Ports des mC keinerlei Dämpfung enthalten und somit das Protokoll des 1Wire durch die ständige Präsenz des Wifi zerschossen wird.

Eine Weiterverfolgung dieses Themas ist wohl müßig. Es scheint keine Erfahrung damit zu geben, einen ESP32 als Webserver mit DS18B20 zu betreiben.

Go Up