Hello everyone. Just as background, I have been using 1-wire devices since the very first devices were released. I did the original ASM code for PIC processors which was ported to the AVR, PSoC, and several others by myself. I did not write the C version in the Particle OneWire lib. I just made it work and I maintain it for all of you. It is clearly a derivative of my original work. Connecting the output pin directly to the 1-wire buss is not exactly per the spec but it IS electrically compliant with the spec. I will explain the specifics here.
The bus is as an open collector based bus with a single pull-up resister. So, the only way to actually be in 100% compliance would be to use a transistor since there are usually no open collector outputs available on most MCUs. There is a work around for totem pole outputs that provides the same electrical profile. The proper implementation using a totem pole output is to set the output register (bus bit) LOW, then toggle the Data Direction Register between input and output rather than the output register. This drives the bus LOW (output), and allows it to float HIGH (input) exactly like an open collector. This is how I implement this bus on a modern MCU and how the OneWire lib is implemented.
As noted in the previous post, the STM32 outputs can be configured to support an open collector (drain), but there is more to consider…
One little problem when using parasitic power, some devices, like DS18S20’s need more power than is available through the pull-up to do internal processing. In this case, Dallas recommended using ‘strong drive’ or some such thing which was to place a transistor in parallel with the pull-up resistor so you can connect the bus to Vcc through the transistor, bypassing the resistor and providing plenty of power, still only using 2 wires total (bus & GND). This solution also addressed the older processors that could only drive 2-3ma. Our modern MCUs can typically drive >20ma per pin and looking at the totem pole above, you can see the top of the pole is exactly what we need!
The two options for power hungry devices:
1> Obvious solution - Hook up the power pin. This is the ONLY option that frees the bus during conversions! This is not an option for iButtons though.
2> Not so obvious - drive the pin HIGH (possible on modern MCUs) giving us 3 states, LOW, Float, HIGH.
I use the latter approach, and typically connect an unused IO line to the 1-wire power bus for complete flexibility.
Bit reads always leave the bus floating since in read mode, the device needs to drive the bus low.
The Write function has the option of leaving the bus driven HIGH or leaving it floating so you can provide power when needed without any extra hardware. This is why I choose this approach, it is electrically compliant with the spec and app notes, yet completely flexible in how you want to run the bus based on your application and devices used.
Make sure you read the specs on the devices your using and get creative using them. For example when using multiple temp sensors, send a broadcast convert command, wait for the conversion then read all devices. This allows the reading of many devices ~ every second instead of just one.
I have been using this same basic code for more that two decades, it is as solid as it gets and the most flexible solution available. The OneWire lib isn’t perfect and there are places where I would like to do some clean up, but, these ARM MCUs are zippy fast and have plenty of resources so there isn’t much of a reason to do it like there is on a 2K PIC running at 4MHz.
Thanks to @ScruffR for bringing this thread to my attention. I hope I addressed your questions, if not, send’em my way. I try to check in every few days or so but I can get busy from time to time. I will respond when I have time.