Skip to content

Conversation

@caiohamamura
Copy link

@caiohamamura caiohamamura commented Aug 25, 2025

Fixes #3682.

  • This PR is for the dev branch rather than for the release branch.
  • This PR is compliant with the other contributing guidelines as well (if not, please describe why).
  • I have thoroughly tested my contribution.
  • The code changes are reflected in the documentation at docs/*.

This PR will remove the special handling for parasite powered devices, because ow_write is already able to correctly handle the strong pull-up required by the DS18B20 and will return to its usual state when issuing new ow operations.

Testing

During testings I parasitic powered two different sensors with a 1m length cable each: pins 1 and 3 are GND and pin 2 directly connected to pin=7 (D7) of a NodeMCU.

I uploaded the ds18b20.lua and the following init.lua:

local t = require("ds18b20")
local pin = 7
gpio.mode(pin, gpio.INPUT, gpio.PULLUP)

function readout(temp)
  t:read_temp(readout, pin, t.C)
  if t.sens then
    print("Total number of DS18B20 sensors: ".. #t.sens)
    for i, s in ipairs(t.sens) do
      print(string.format("  sensor #%d address: %s%s",  i, ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(s:byte(1,8)), s:byte(9) == 1 and " (parasite)" or ""))
    end
  end
  for addr, temp in pairs(temp) do
    print(string.format("Sensor %s: %s °C", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(addr:byte(1,8)), temp))
  end
end


t:read_temp(readout, pin, t.C)

Opened the serial monitor and everything is working as expected, printing every ~750ms.

@caiohamamura caiohamamura changed the title DS18Bb20: correctly set gpio mode for parasite power readings DS18Bb20: broadcast CONVERT_T to parasite powered devices Aug 25, 2025
@marcelstoer
Copy link
Member

Ideally this should be reviewed by the original author @vsky279.

@marcelstoer
Copy link
Member

(needs a rebase as well)

@vsky279
Copy link
Contributor

vsky279 commented Aug 30, 2025

Hi caiohamamura,
I am not sure that the strong pull-up is guaranteed for all hardware modules. Do we have a proof?

I'm pretty sure I needed to implement this code to make it work for larger number of parasite powered devices few years ago.

So I suggest to make the simplification optional.
The modification of the code could look like this

-- Add a config flag
local ds18b20 = {
  use_fw_pullup = false,  -- default: keep old behavior
  ...
}

conversion = (function (self)
  local sens = self.sens
  if self.use_fw_pullup then
    -- simplified variant: trust firmware's strong pull-up
    debugPrint("starting conversion: all sensors (fw pullup)")
    ow_reset(pin)
    ow_skip(pin)
    ow_write(pin, CONVERT_T, MODE)
    for i, _ in ipairs(sens) do status[i] = 1 end
    tmr_create():alarm(750, tmr_ALARM_SINGLE, function() return readout(self) end)
  else
    -- old fallback code (your original handling of parasite vs powered)
    debugPrint("starting conversion: per-sensor (manual parasite handling)")
    return old_conversion(self)
  end
end)

@caiohamamura
Copy link
Author

caiohamamura commented Sep 2, 2025

Yes, on second thought it would be better if we delegate that decision to the user itself. As stated by the datasheet it can consume up to 1.5mA, so if we consider the esp 8266 datasheet that says it can provide up to 12mA, the maximum parasite powered at the same time would be exactly 8, but considering other possible sources of loss such as wire resistance+its length it would probably be safer to assume 7 sensors or even less. That said, it makes sense that your configuration using 8 sensors would not work.

In that scenario the user should follow the recommendation from the datasheet and use a MOSFET for controlled by another gpio port to control the strong pull-up for feeding the sensors. Actually in Arduino Framework DallasTemperature library they assume the user will make that configuration when parasite power and the user is required to setup the pin number which is connected to the strong pull-up on initialization of the library.

It would probably be better to document those contraints within the nodemcu documentation itself, because I myself struggled a little bit, maybe the library should give more control to the user and split sending the CONVERT_T command function and reading the temperatures, and that function needs to be very simple and quick so that the user can still use a gpio controlled pull up if needed, because as the datasheet states:

The 1-Wire bus must be switched to the strong pullup within 10µs (max) after a Convert T [44h] or Copy Scratchpad [48h] command is issued.

I don't even think in lua we can provide that 10µs at most delay, maybe that would require a C module or tweaking one wire to allow controlling a second pull-up pin.

@vsky279
Copy link
Contributor

vsky279 commented Sep 3, 2025

Thanks for the clarification. I see your point and it makes sense – especially the current limitation and the 10µs requirement from the datasheet.

From my side, I’d prefer to keep the module simple and backward compatible. That’s why I proposed to add the use_fw_pullup option: users with a small number of parasite powered sensors can rely on the firmware, while others can still fall back to the old handling.

If you believe the module should also expose a lower-level API (e.g. splitting CONVERT_T from the readout, or supporting an external MOSFET pin), please feel free to propose such modification – I’m not planning to implement it myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants