0

I'm trying to read 4 DS18B20 sensor probes (https://amazon.com/gp/product/B00Q9YBIJI and https://amazon.com/gp/product/B008HODWBU) with a "Wemos" LOLIN32 ESP-32 board (https://amazon.com/gp/product/B072HBW53G).

Wiring:

  • The probes' Vcc wires are connected to the ESP32 board's "3.3" pin

  • the probes' ground wires are connected to one of the ESP32 board's "Gnd" pins

  • the probes' data wires are connected together at the end of their furnished meter-long cable, and the wire carrying the combined data is connected to GPIO 16 on the ESP32 board.

  • Additionally, there's a 4.7k resistor between GPIO16 and the 3.3v pin on the Lolin32 board to pull the 1-wire bus high.

I'm using the stock Arduino and libraries.

Sometimes, the sensors work. Often, they don't.

Possibly noteworthy is the fact that I purchased 1 probe a few years ago, and a 3-pack of probes this week. Probes from the 3-pack ONLY work if the probe I purchased earlier is ALSO connected. Put another way...

Original probe connected: sometimes works, sometimes doesn't.

1-3 of new probes connected: never works.

1-3 of new probes connected along with original probe: sometimes works, sometimes doesn't.

Wiring should theoretically be a total non-issue... I'm using only the original ~meter-long wires, with short (~3-4") AWG20 solid hookup wire soldered to the end and connected through a breadboard.

If I unplug the wires connected to the ESP32 board's GPIO16, 3.3, and Gnd pins and connect them instead to an old Arduino Uno's D2, 5v, and Gnd pins (and change the port in the code), all tested permutations of the sensors work perfectly and reliably.

Any ideas for troubleshooting this?

At the moment, these are my top theories:

  • GPIO16 is unsuitable for some unknown reason.

  • There's at least one software bug somewhere between the ESP32's low-level firmware, the firmware that enables an ESP32 to act like it's an Arduino, the two Arduino libraries themselves, or some combination of them all. Knowing that something like this is almost certainly the problem would at least spare me from going in circles for the next few days trying to solve a problem that can't be solved.

  • The 3 new sensors really don't like 3.3v, but the older one semi-tolerates 3.3v (theory fails to explain why adding a fourth sensor -- the original one -- would occasionally enable the 3 new ones to work)

  • The ESP32 board can't supply enough current from the 3.3v pin to properly power the sensors (flaws in theory: if it were purely lack of current capacity, adding the fourth sensor on top of the first 3 should make matters worse, not better. And in any case, the DS18B20 sensors don't use much power, and almost by definition MUST be able to work with unstable & intermittent power for parasitic powering to be capable of working. Just to emphasize, I am NOT using parasitic power, though).

I considered trying to feed the sensors 5v, but I'm not entirely sure how to deal with the level translation between their data bus and the ESP32 board.

  • I know Espressif has officially stated that the ESP8266 has 5v-tolerant i/o

  • I could swear I also read somewhere that the ESP32 is unambiguously NOT 5v-tolerant.

  • I have a hunch that level-shifting Dallas 1-wire is more complicated than it seems, and that there's probably at least one "gotcha" lurking that will cause problems if I try blindly using something like a TXB0104 or MAX3378 between the sensors' data wire and the ESP32 board.

Here's the relevant code (when it works, it works for the original sensor or the original sensor + one or more of the new sensors... when it doesn't work, it fails to detect any sensors & just outputs "Temp: " to Serial when running in loop().

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

#define ONE_WIRE_BUS 16
#define TEMPERATURE_PRECISION 12

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature dallasTempSensor(&oneWire);
int totalOneWireDevices = 0;
DeviceAddress tempDeviceAddress;

void setup() {
    Serial.begin(115200);

    dallasTempSensor.begin();
    totalOneWireDevices = dallasTempSensor.getDeviceCount();
    Serial.print("Locating devices...");
    Serial.print(totalOneWireDevices, DEC);
    Serial.println(" devices.");

    Serial.print("Parasite power is: ");
    if (dallasTempSensor.isParasitePowerMode()) 
        Serial.println("ON");
    else
        Serial.println("off");

    for (int x=0; x<totalOneWireDevices; x++) {
        if (dallasTempSensor.getAddress(tempDeviceAddress, x)) {
            Serial.print("Found device ");
            Serial.print(x, DEC);
            Serial.print(" with address: ");
            printAddress(tempDeviceAddress);
            Serial.println();
            Serial.print("Setting resolution to ");
            Serial.println(TEMPERATURE_PRECISION, DEC);
            Serial.print("Resolution actually set to: ");
            Serial.print(dallasTempSensor.getResolution(tempDeviceAddress), DEC);
            Serial.println();
        }
        else {
            Serial.print("Found ghost device at ");
            Serial.print(x, DEC);
            Serial.print(" but could not detect address. Check power and cabling.");
        }
    }
}

// function to print the temperature for a device

void printTemperature(DeviceAddress deviceAddress)

{
  float tempC = dallasTempSensor.getTempC(deviceAddress);
  //Serial.print("Temp C: ");
  //Serial.println(tempC);
  //Serial.print("Temp F: ");
  //Serial.print("    ");
  Serial.print(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}

void loop() {
  // put your main code here, to run repeatedly
    //Serial.print("Requesting temperatures...");
    dallasTempSensor.requestTemperatures();
    //Serial.println("DONE");
    Serial.print("Temp:   ");
    for (int x=0; x < totalOneWireDevices; x++) {
        if (dallasTempSensor.getAddress(tempDeviceAddress, x)) {
            //Serial.print("Temperature for device: ");
            //Serial.println(x, DEC);

            printAddress(tempDeviceAddress);
            Serial.print(" = ");
            printTemperature(tempDeviceAddress);
            Serial.print("    ");
        }
    }
    Serial.println("");
    delay(5000);
}

void printAddress(DeviceAddress deviceAddress) {
    for (uint8_t x=6; x < 8; x++) {
        if (deviceAddress[x] < 16)
            Serial.print("0");
        Serial.print(deviceAddress[x], HEX);
    }
}
  • trying to read 4 DS18B20 sensor probes .... what about only one? – jsotola May 23 '18 at 23:26
  • The original one sometimes works if it's the only one connected. The new ones never work if they're the only one(s) connected. The new ones sometimes work if they're connected along with the original one. – Bitbang3r May 24 '18 at 4:26
  • stop trying to run all four until you get one working rock solid ...... you either have a wiring problem or software problem or power supply problem or a combination of the three ..... please post your code, if you can – jsotola May 24 '18 at 4:32
  • Code added. As noted, the only factor that seems to influence whether it works "sometime" or "not at all" is the presence of the original sensor... present, alone or with the others, the sketch sometimes works. Without the older sensor present, it never works. – Bitbang3r May 24 '18 at 7:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.