-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
Expected behavior
CONVERT_T should be broadcast for parasite powered sensors too (use a single delay ~750ms).
Actual behavior
Currently for parasite mode the readings are done one by one in a loop fashion, creating a delay for each sensor. But it turns out that this is not needed, we can broadcast the conversion for all sensors at once, provided that in ow_write the MODE is set to 1 (set a strong pull-up), which it is.
Context
It is known that the one-wire bus will be occupied during parasite power mode for some operations due to the power requirements that make the gpio to send a strong pull-up which is achieved by sending MODE=1 to ow_write.
The strong pull-up is actually a HIGH gpio.OUTPUT, which can provide 12mA in ESP8266. The DS18B20 datasheet states that the CONVERSION_T operation may draw up to 1.5mA, that is, the default ESP8266 gpio can power up to 8 sensors during CONVERSION_T operation in the worst case scenario (all of them are drawing the peak current at the same time which is highly unlike), which will meet most usual applications.
So there is no need for the special handling of parasite powered mode and we could safely broadcast CONVERT_T for all sensors, since we are actually providing ow_write with MODE=1 to every operation. For the sake of perfect correctness for conventional powered sensors the ow_write could actually be set to MODE=0, then it wouldn't block the bus HIGH and the user would be able to issue write/read operations to other devices during the CONVERT_T operations.
Testing
Within module change conversion = function to:
conversion = (function (self)
local sens = self.sens
debugPrint("starting conversion: all sensors")
ow_reset(pin)
ow_skip(pin) -- skip ROM selection, talk to all sensors
ow_write(pin, CONVERT_T, MODE) -- and start conversion
for i, _ in ipairs(sens) do status[i] = 1 end
tmr_create():alarm(750, tmr_ALARM_SINGLE, function() return readout(self) end)
end)Within lua.init:
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)And the sensors will be re-read as soon as the alarm is triggered. Everything works as expected and instead of having delay * n_parasite_sensors, it will print at the fixed ~750ms delay.
NodeMCU startup banner
NodeMCU 3.0.0.0 built with Docker provided by frightanic.com
branch: release
commit: 36cbf9f017d356319a6369e299765eedff191154
release:
release DTS: 202402250804
SSL: false
build type: float
LFS: 0x0 bytes total capacity
modules: adc,bit,dht,file,gpio,gpio_pulse,i2c,mqtt,net,node,ow,rtctime,sntp,spi,tmr,uart,wifi
build 2025-08-21 23:29 powered by Lua 5.1.4 on SDK 3.0.1-dev(fce080e)
Hardware
Usual NodeMCU ESP8266.