Go Down

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

Wiki_

Moin,
auf nem breadboard hab ich den ESP32 mit vier DS18B20 (konfiguriert auf parasite power) zusammengesteckt, funktioniert soweit gut.

Die Temperaturen möchte ich gerne über Wifi abfragen, starte dazu den Wifi Server. Zugriff funktioniert auch stabil und gut.

Nur in dem Moment, wenn ich Wifi.begin() aufrufe wird die Abfrage der Temperaturen ein Zufallsspiel. Die Sensoren antworten auf die Abfrage nur sehr sporadisch, mal der eine, dann mal ein anderer. Vor Aufruf von Wifi.begin(), in demselben sketch innerhalb von void setup() antworten die Sensoren unverzüglich.

Liegt die Störung an dem Aufbau auf dem breadboard oder ist etwas grundsätzliches dazu bekannt?

Code: [Select]

/*
Webkontrolle für 4 12V Akkus
 */

#include <WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Adafruit_Sensor.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
//#include <Adafruit_SH1106.h>
#include <OakOLED.h>
#include <driver/adc.h>
#include <Fonts/FreeSans9pt7b.h>




OakOLED display;

const char* Version = "0.9.7";
   
#define ONE_WIRE_BUS 17
#define TEMPERATURE_PRECISION 12

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

int numberOfDevices;
DeviceAddress tempDeviceAddress;

const char* ssid     = "XXX";
const char* password = "YYY";

WiFiServer server(80);


uint32_t delayMS;

#define sensorPin0 32
#define sensorPin1 33
#define sensorPin2 34
#define sensorPin3 35

float sensorValue0 = 0;  // variable to store the value coming from the sensor
float sensorValue1 = 0;  // variable to store the value coming from the sensor
float sensorValue2 = 0;  // variable to store the value coming from the sensor
float sensorValue3 = 0;  // variable to store the value coming from the sensor
float Volt0;
float Volt1;
float Volt2;
float Volt3;
float temp[8];
float Reading;
float temp0;
float temp1;
float temp2;
float temp3;

void setup()
{
  Serial.begin(115200);
  pinMode(5, OUTPUT);      // set the LED pin mode
  sensors.begin();
  display.begin();
  display.clearDisplay();
  display.setFont(&FreeSans9pt7b);
 
 
  numberOfDevices = sensors.getDeviceCount();
 
  // Loop through each device, print out address
  for(int i=0;i<numberOfDevices; i++)
  {
    // Search the wire for address
    if(sensors.getAddress(tempDeviceAddress, i))
  {
    Serial.print("Found device ");
    Serial.print(i, DEC);
    Serial.print(" with address: ");
    printAddress(tempDeviceAddress);
    Serial.println();
   
    Serial.print("Setting resolution to ");
    Serial.println(TEMPERATURE_PRECISION, DEC);
   
    // set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions)
    sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
   
     Serial.print("Resolution actually set to: ");
    Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
    Serial.println();
  }else{
    Serial.print("Found ghost device at ");
    Serial.print(i, DEC);
    Serial.print(" but could not detect address. Check power and cabling");
  }
  }

Serial.print(numberOfDevices);
  sensor_t sensor;
  delayMS = sensor.min_delay / 1000;

 

    delay(10);
Serial.print("Temperatur holen"); 
    sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("...Done");
    for(int i=0;i<numberOfDevices; i++)
  {
   
    if(sensors.getAddress(tempDeviceAddress, i))
   
  {

        Serial.print("Temperature for device: ");
    Serial.println(i,DEC);

    float tempC = sensors.getTempC(tempDeviceAddress);
    temp[i]=tempC;
  Serial.println(temp[i]);
  Serial.println(i);
    delay(30);
  }
  }
    // We start by connecting to a WiFi network

    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
   
    server.begin();

}

int value = 0;

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

            for (int i = 1; i < 101; i++)
            {
            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);
            }
           
            Volt0=ADCKorrektur(Volt0/100);
            Volt1=ADCKorrektur(Volt1/100);
            Volt2=ADCKorrektur(Volt2/100);
            Volt3=ADCKorrektur(Volt3/100);

Serial.print("Temperatur holen"); 
    sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("...Done");
    for(int i=0;i<numberOfDevices; i++)
  {
   
    if(sensors.getAddress(tempDeviceAddress, i))
   
  {

        Serial.print("Temperature for device: ");
    Serial.println(i,DEC);

    float tempC = sensors.getTempC(tempDeviceAddress);
    temp[i]=tempC;
  Serial.println(temp[i]);
  Serial.println(i);
    delay(30);
  }
  }

    VoltSchreiben(Volt0, Volt1, Volt2, Volt3, temp);

webif();
           
}

ElEspanol

#1
Dec 05, 2017, 01:45 pm Last Edit: Dec 05, 2017, 01:46 pm by ElEspanol
Parasite power geht nicht zuverlässig mit 3,3V. Hab das ausführlich an einer nodemcu getestet

Wiki_

Moin,

verzeih mir, das stimmt imho nicht ganz, lt. Datenblatt Vpu 3.0-5.5V.

Ich hab zwei weitere ESP32 mit 3,3V parasite power stabil am Laufen, nur eben nicht als Wifi.server.

postmaster-ino

Hi

Da 1-wire ein recht zeitkritisches Protokoll ist, könnte ich mir vorstellen, daß der ganze Wifi-Kram, Der dann auch noch 'zwischendurch' abgearbeitet werden soll, sich irgendwie mit der Kommunikation der DS18B20 kloppt.

Kannst Du die Daten auf dem 1-wire-Bus mitlesen? Oszi/LA?

MfG

Whandall

könnte ich mir vorstellen, daß der ganze Wifi-Kram, Der dann auch noch 'zwischendurch' abgearbeitet werden soll, sich irgendwie mit der Kommunikation der DS18B20 kloppt.
Das ist eher unwahrscheinlich, da WiFi auf dem anderen Core läuft.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Mardetuino

...
Liegt die Störung an dem Aufbau auf dem breadboard oder ist etwas grundsätzliches dazu bekannt?
...
Ich sehe in deinem Hackstück-Code kein Timing.

Wie oft pro Sekunde rufst du die Werte der DS ab?

Code sollte generell "nicht blockierend" geschrieben werden.

SkobyMobil

Hallo,
wenn Du davon (DS18B20) 4 Stück auslesen möchtest, dann brauchen die ihre Zeit.
Mindestens 3Sek gesammt für alle. Die Biester sind zeit-kritisch.
Gruß und Spaß
Andreas
die zweite Maus bekommt den Speck...

Mardetuino

Hallo,
wenn Du davon (DS18B20) 4 Stück auslesen möchtest, dann brauchen die ihre Zeit.
Mindestens 3Sek gesammt für alle. Die Biester sind zeit-kritisch.
Gruß und Spaß
Andreas
Aber auch nur im parasitären Modus.
Ob der ESP einen 1k bis 2k PullUp verträgt ist weiß ich nicht...

Wenn die DS als drei Pin angeschlossen sind, ist die benötigte AD-Wandel-Dauer unabhängig von der Anzahl der Sensoren.

SkobyMobil

#8
Dec 05, 2017, 07:59 pm Last Edit: Dec 05, 2017, 07:59 pm by SkobyMobil
Hallo,
mal so...
Gruß und Spaß
Andreas
die zweite Maus bekommt den Speck...

Mardetuino


Der Sensor braucht min 750ms.
Egal wieviele das sind, das braucht jeder einzelne. Somit steht an allen Sensoren nach 750ms ein neuer Wert bereit.

Unabhängig von der Anzahl.

postmaster-ino

#10
Dec 05, 2017, 09:39 pm Last Edit: Dec 05, 2017, 10:10 pm by postmaster-ino
Hi

Bei parasitärer Versorgung musst Du diese Zeit warten, bei normaler Versorgung kannst Du zwischendrin abfragen, ob der DS noch mit Umwandeln beschäftigt ist.
Wenn Du zu früh die Sensorwerte abholst, wird beim parasitär betriebenem DS die Messung unterbrochen (die Versorgung wird ja weg genommen), beim normal versorgtem DS wirst Du einen alten Messwert bekommen.

Oder eben:
1. Messung auslösen
2. irgend was sinnvolles tun während der Wartezeit
3. nach der angegebenen maximalen Umwandlungszeit (750ms bei 12bit) die Daten auslesen.

MfG

*Edit* Ein DU in ein Du geändert, sind doch nur nette Leute hier, da schreit man doch Keinen an :O

Wiki_

Moin,

ich danke schonmal für die Anregungen.

Ich muss dazu sagen, ich in auf der Arduino-Schiene recht frisch unterwegs, ist meine erste Begegnung mit C. Meine vorherigen Projekte spielten auf dem Tiny Tiger und auf dem Raspi.

Zum Timing: in der void loop () werden als erstes analog die vier Spannungen in einer Schleife von 0-100 mit zwischengeschaltetem delay von 10ms abgefragt, um einen Mittelwert zu bilden (Versuch, Störungen auszublenden). Anschliessend schiebe ich die analogen Werte durch eine Korrketurtabelle, um das nichtlineare Verhalten des ESP32 auf dem ADC zu korrigieren. D.h., die DS werden frühestens alle zehn Sekunden abgefragt.

Da die Antwort des Aufrufes von "sensors.requestTemperatures();" ca. drei Sekunden für ne Antwort braucht, hab ich mir vorab keine Gedanken um das Timing bei der Abfrage gemacht sondern vorausgestzt, das erledigt die library. Ich werd mal den Code bereinigen und an der Stelle dann neu ansetzen. Denn wie deutlich zu sehen, hab ich erstmal q&d aus den Beispielsketches das rausgeholt, was mir sinnvoll erschien.

Das, was mich allerdings stutzig macht ist die Tatsache, dass mit ähnlich unstrukturierten sketches die Abfrage der Sensoren absolut stabil läuft, eben nur nicht mit Wifi (als Server).

Wiki_

#12
Dec 05, 2017, 11:49 pm Last Edit: Dec 05, 2017, 11:55 pm by Wiki_
1. Messung auslösen
2. irgend was sinnvolles tun während der Wartezeit
3. nach der angegebenen maximalen Umwandlungszeit (750ms bei 12bit) die Daten auslesen.
Moin,

aso void loop() sieht bei mir jetzt so aus:

Code: [Select]

void loop()
{
  Volt0=0;
  Volt1=0;
  Volt2=0;
  Volt3=0;
  sensors.requestTemperatures();          // Temperaturen holen
  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);
  }
  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);
      temp[i]=tempC;
      delay(30);
    }
  }
  VoltSchreiben(Volt0, Volt1, Volt2, Volt3, temp);
  webif();                                   // Web-Schnittstelle abfragen, ob ein request vorhanden
}


Damit sollte der Sensor bzw die lib genügend Zeit haben....hilft aber nicht.

Immer noch: vor Wifi.begin(); klappt das Auslesen der Temperaturen gnadenlos, nach Wifi.begin(); nur noch sporadisch. Ich hab probeweise den Wifi-Klamauk komplett auskommentiert, dann tuts wie erwartet. Sobald Wifi im Spiel isses Essig.

...ratlos...

[edit]
-s +d
[/edit]

DerLehmi

2 Dinge, die mir zum Ausprobieren noch einfallen würden:
1) Abfrage der Sensordaten sekundenweise, nicht pausenlos.
2) Normal anschließen, also nicht im Parasitenmodus

Wiki_

Moin,

Danke für die Ideen, nur leider

1.: Abgefragt werden die Dinger so ca. im 10-Sekundentakt, das zwischendurch stattfindende Auslesen der A/D Wandler dauert ca. so lange.

2.: geht leider nicht, nur zwei Drähte pro Sensor vorhanden. Ich hätte ansonsten von vornherein auf die parasitäre Einspeisung verzichtet.

OK, Dank @all für ihre Gedanken. Werd ich scheints so mit leben müssen und im Web Interface noch die Info über das Alter der einzelnen Temperaturdaten mit auswerfen.

Ich hab so langsam das Gefühl, dass der ESP32 nicht so richtig ausgereift ist. Schon die nicht-Liearität der ADC hat mir schwer zu Schaffen gemacht und jetzt dies noch obendrauf...

Go Up