My Pi Description

My Experiences With the Raspberry Pi -- Tracking My Learning -- My Pi Projects

Monday, July 7, 2014

DS18B20 Connected Using Parasitic Power

This is a continuation of my last two blog posts.

Parasitic Power and 1-Wire Devices

The 1-Wire devices have three pins, one for power, one for ground, and one for data. However, it is possible to connect the device without connecting to a source of power. In that case, both the ground and power pins are connected to ground. That simplifies cabling as it is only necessary to run two wires instead of three. A device connected in this matter is said to be connected using parasitic power. The device gets its power, parasitically, from the data line. And, the data line is powered through a 4.7K pull-up resistor to the power source (5V for the Arduino). That relatively high value of resistance still allows the Arduino or a DS18B20 to pull the data line to a low logic state (near ground). That arrangement is sufficient to power the device for all operations except when the device is undergoing temperature conversion and when writing from the scratchpad to the device's EEPROM (not the ATmega EEPROM). For those operations, the device may draw as much as 1.5mA. That's not a lot of current, but still more than can be supplied through that pull-up resistor. For those two operations, we connect the data line, directly, to the power source. Of course, once we do that, we can't have any other operation going on that requires a transfer of data in either direction (can't pull the data line low).

Parasitic Power Control Circuit

Obviously, we need a switch to control when we connect the data line to the power source. The switch I devised can be seen in the figure below:
My switch is the 2N5087 PNP transistor. Why that transistor? I just happened to have a couple. The transistor can supply about 100ma., so more than 67 parasitically connected devices could sit on the bus. Sparfun has a 2N3906 which should work just as well. Actually, this one will sink 200ma. If you are interested, Sparkfun has a tutorial about how transistors operate. Look here.
Once a low voltage (near 0) is applied through the 1K resistor to the base of the transistor, the transistor "turns on" making a near short circuit between the collector (connected to the power source) and the emitter (connected to the the data line). I use an Arduino pin to control the transistor (PB1 in my case). When I want the switch to be off, I program PB1 to be an input. As an input, the Arduino can not supply any current to the transistor's base-emitter junction so the transistor can not turn on. When I want the switch on, I program the logic level at PB1 to be LOW and program the pin to be an output.

Detecting Devices Connected Using Parasitic Power

It is not necessary to keep track of the devices that are connected using parasitic power. You can use the library function command read_power_supply(). Like all function commands it must be preceded by initialization(), and either match_rom() or skip_rom(). Function match_rom() will address only one device - the one with the ROM code you pass to it. If that device is connected with parasitic power it will pull the data line low. If skip_rom() is employed, ANY device connected with parasitic power will pull the data line low.

Programming Consequences of Devices Connected Using Parasitic Power

In my library function Convert_t(), if a device is not connected using parasitic power, I let the device inform my code when the convert operation is complete. The device will pull the data line to a logic LOW while the conversion is taking place. My library function reads the data line every millisecond. When a logic HIGH is read my code can move on and do its next operation. According to the data sheet, the resolution at 12 bits should take no more than 750ms. I found that the conversion is done in about 550ms. at 12 bit resolution.
If using parasitic power, the device can not pull the data line low because of the hard pull-up. The only option is to pass the resolution to the convert_t() function and use a delay() statement to give the device enough time to make the conversion. To be sure enough time is given, I use the specification in the data sheet.
You can look at my Read_Temperature.ino sketch to see more of my implementation of parasitic power. It is one of my files on GitHub, but you can see it here.

No comments:

Post a Comment