Parasite power
kebner opened this issue · 12 comments
Hi David
do you have any idea why the lib isn't working with parasite power? I can detect the devices, but temperature reading just delivers 85.0 - and that's not true :)
Weird thing is: The ROM code is read and the device is detected. Just reading from scratchpad didn't get the right results.
Thanks for your insights (and of course for providing that lib in the first place! Nicely written!)
Klaus
Hi Klaus,
Thank you for your compliment. Frankly I haven't actually tested the library with parasitic power - I've not actually had an application that used it so far. However I'd be happy to help add support if you need it.
Do you have the CRC check enabled? Do you see CRC errors in the monitor console?
Give me a day or so to play around with the parasitic power mode, and I'll see what it will take to add support.
I found it :) It had absolutely nothing to do with your code (Although I changed the timings a bit to better suit the documentation, but as this didn't seem to matter at all, I changed them back again): After some more searching and asking Google, I found a discussion regarding 85 degree celcius in one Arduino forum, where someone pointed to the footnote on page 4 saying "*The power-on reset value of the temperature register is +85°C.". I've pulled up the one wire bus with 3.3V (with a 4.7K resistor in place) - that should have been enough, but wasn't.
Now I changed that to 5V and used a signal shifter to provide the max of 3.3V to the gpio pin.
Voila. It starts reading temperatures:
Temperature readings (degrees C): sample 410
0: 24.8 0 errors
Temperature readings (degrees C): sample 411
0: 24.9 0 errors
You can take away the remark stating parasite power not supported :) It is, witht eh right pullup voltage applied.
Thanks again for that code. I went down to rock bottom and was amazed.
Kind regards
Klaus
Hi Klaus, thank you for this great info. I'm glad to hear that parasitic power is working for you.
Apart from the electronics change to ensure enough charge is provided, are there any changes required to my ds18b20-example project to make it work with parasitic power? I'd like to either make a note about whether parasitic power will work, or explicitly comment that it won't without changes. You mentioned some changes earlier (remove convert_all
, add owb_reset
, etc) - do you still need those?
I tried something a little different, I used a BS250 p-channel MOSFET controlled by a separate GPIO to pull up the data line during the temperature conversion. This gave me reliable operation of two DS18B20 devices on the same bus, both using parasitic power.
This suggests there are two ways of using parasitic power - either provide more current (e.g. higher voltage, with your level shifter), or provide an externally switched "strong" pull-up circuit. With that in mind I will extend the API to support both.
Note that I wasn't able to get temperature conversions to work with even a single device at 3.3V, even by reducing the original pull-up from 4k7 to 2k2ohms. Device communication was fine, no CRC errors, but by looking at my scope I could see that the conversion never quite completed properly. I think this matches what you saw?
EDIT: I was able to get conversions to work at 3.3V with a 1kohm resistor and no MOSFET, along with an artificial 750ms delay (rather than calling ds18b20_wait_for_conversion
that waits for the device to signal conversion is complete, which can't be used in parasite power mode.
I think therefore that there are three modes:
- external power mode - can wait for devices to signal conversion is complete
- parasite power mode, no MOSFET - must wait a prescribed period of time
- parasite power mode, with MOSGET - must power GPIO during conversion, to turn on MOSFET, then turn off after conversion. Must wait a prescribed period of time.
I'll see what I can do to support all of these without breaking the API too much.
@kebner I've added support for both parasitic mode with a "stronger" (i.e. lower) pull-up resistor (1 kOhm works for me with two DS18B20 devices on the bus, both parasitic), as well as a mode that allows a second GPIO to be used to switch a MOSFET as a "strong" pull-up, as per the datasheet. If you'd be so kind to test this PR, even if it's just with your level shifter, I'd appreciate it, please. The link to the PR is just above this comment.
Hi David
Thanks for the work. I did some testing:
a) Nothing was broken for my setup (5V, level shifting)
b) Using 3.3v/4.7K results in detecting the slave but returning errors when reading (It reads -2048 (Thankfully not true) and a "ds18b20 device not responding")
c) Using 3.3v/1K works great!
d) I only found this mosfet here IRF9610 - Using that together with 3.3/4.7K and commenting out the call to owb_use_parasitic_power(owb, parasitic_power) but calling owb_use_strong_pullup_gpio(owb, CONFIG_STRONG_PULLUP_GPIO) instead results in errors same as in b)
Bottom line: 5V/4.7K and 3.3V/1K both works here using your exact example code, regarding the mosfet solution, I need to get my hands on a suitable one (any recommendations?)
Hi Klaus, thank you for testing it.
If you want to use the strong pullup GPIO/MOSFET you do need to call owb_use_parasitic_power(..., true)
otherwise it won't make use of the GPIO. It should show a warning in the console in this case. Try putting that call back in and see if that helps. Note you may need a small (200-300 ohm) resistor between VCC and the mosfet (or just after) to ensure your ESP32 doesn't sink too much current into its OWB data GPIO.
I used a BS250 p-channel mosfet in my testing. From what I can tell the IRF9610 should work too though.
Let me know if you need more help with setting up the MOSFET - maybe I can draw a diagram or something.
Thanks for the sketch - my layout is slightly different, as I put the resistor between the MOSFET source and the 3.3V rail. No resistor needed on the Gate, it's high-impedance anyway.
I used this diagram as my basis: https://electronics.stackexchange.com/a/94254/159201
You will want to check that setting GPIO18 high (I assume you configured that in menuconfig
?) is sufficient to switch on the MOSFET, but you will want to move that 220 "current limiting" resistor otherwise you're basically shorting 3.3V to GPIO19 if the MOSFET is on when GPIO19 goes low.
As long as you've got a way forward I'm happy to test this particular configuration here - and it does work for me, so that's good enough for the PR. But I am of course interested to hear how you go, if you choose to give it another try.
Thank you again for your feedback, and for helping to improve the library.
I tried again: For one device, that works. For two devices, I got a reading of 127.9... If I use 5V together with the mosfet, two devices can be read again.
As this should be the most reliable solution, I'll stick with that :)
Have a good day & thanks for the help
Klaus
Thanks for reporting back. All the best.