Using an ESP32 based S2 mini board to interface to 3x DS18B20 in parallel
Arduino IDE
Using board 'lolin_s2_mini' from platform in folder: /home/martin/.arduino15/packages/esp32/hardware/esp32/3.3.6
Using library Preferences at version 3.3.6 in folder: /home/martin/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/Preferences
Using library DallasTemperature at version 4.0.5 in folder: /home/martin/Arduino/libraries/DallasTemperature
Using library OneWire at version 2.3.8 in folder: /home/martin/Arduino/libraries/OneWire
Using library WiFi at version 3.3.6 in folder: /home/martin/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/WiFi
Using library Networking at version 3.3.6 in folder: /home/martin/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/Network
Using library ESPmDNS at version 3.3.6 in folder: /home/martin/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/ESPmDNS
Using library ArduinoOTA at version 3.3.6 in folder: /home/martin/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/ArduinoOTA
Using library Update at version 3.3.6 in folder: /home/martin/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/Update
Using library espMqttClient at version 1.7.1 in folder: /home/martin/Arduino/libraries/espMqttClient-1.7.1
Using library NetworkClientSecure at version 3.3.6 in folder: /home/martin/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/NetworkClientSecure
Using library Hash at version 3.3.6 in folder: /home/martin/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/Hash
Using library Async TCP at version 3.4.10 in folder: /home/martin/Arduino/libraries/Async_TCP
It seems, that after some time of operation, the measurements of one of the three sensors (not always the same one) is not correct in a way that faulty measurements are not detectable automatically always.
At one event, the measurements are too low (-20°C instead of +20°C). That will be an inplausible measurement, perhaps can be "repaired" by a device reset.
Another event the readings were 8°C too high... that wrong measurement is not easy to filter by a plausibility check.
After disconnecting the ESP32 from power supply and reconnecting it, all went fine again
3-wire connection
Vcc = +5V, Gnd, DATA with pull up 3,3 kOhm to +3.3 V
It seems, that there is a newer DallasTemperature library version in Github (4.0.6 vs 4.0.5) Release notes and closed issues do not point to an issue similar to my problems ...
I Googled DS18B20 and see they cost under $5. I bet an equivalent sensor that costs $100 to $500 will be much more accurate and reliable.
Another way is to use a running average algorithm. I have seen one or two but at 84 the details are not always remembered. Search the forum first as many projects use this kind of algorithm. This is also a good candidate for AI. I found 9 when I asked Google.
Writing outside array boundaries???
Huge industrial motor started running nearby and wires are long and not shielded???
Bad connection?
Please post pictures of your setup...
Huge hickup in mains power supply?
Memory leak?
Both these cases look like a single bit error.
Q1: do you have pull up resistors in place?
As proposed by @sonofcy you could use a running average, but for these kind of outliers a runningMedian is far better as it is not affected by outliers.
Drawback is that the measurements do run a bit behind, how much depends on the volatility of the temperature and the size of the median window.
Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Have you a simple bit of code that just shows this problem without all the MQTT junk around it?
In other words just reads the three sensors and outputs it on the ESP32 serial to the IDE serial monitor.
This will check if your problem is hardware or software.
If I had your DS18B20's, I would hook them up to a Nano classic and test them with a basic, proven sketch.
#include <OneWire.h>
// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// https://github.com/milesburton/Arduino-Temperature-Control-Library
OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary)
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
byte i;
byte present = 0;
byte type_s;
byte data[9];
byte addr[8];
float celsius, fahrenheit;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(250);
return;
}
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.println(" Chip = DS18S20"); // or old DS1820
type_s = 1;
break;
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
}
This is the one from Wiki - with no delay after requestTemperatures()
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
Serial.print("Temperature for Device 1 is: ");
Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire
}
My code is more than 3 years in use. Recently I expanded the code for OTA updates and preferences library ....
But Version 3.7 introducing "async mode" is of 2015
I will try to use Delay(750);
Since the measurement errors are occuring quite seldom (several days of normal operation), it is not easy to get the cause....
I have checked serial numbers towards github repository about DS18B20 clones ...