some troubles with the DS18B20-PAR temperature sensor

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
User avatar
Sikolenski
Posts: 1
Joined: Mon Feb 18, 2019 6:07 pm

some troubles with the DS18B20-PAR temperature sensor

Post by Sikolenski » Mon Feb 18, 2019 6:50 pm

Hi everyone,
First, sorry for my poor english (i'm a french guy...).

I'm actually new with micropython coding and pyboard hardware, and i need some help with my temperature sensors. They are DS18B20-PAR https://datasheets.maximintegrated.com/ ... 20-PAR.pdf and by mounting them like is describe in the datasheet, with an 4.7kohms resistor betwen DQ an Vpu, ds.scan() returns only "[]" instead the three sensor's bytearrays . When i swap the resistor with another of 1kohm, ds.scan() give me the sensor's bytearrays.

>>> ds.scan()
[bytearray(b'(\xb6\x10\xd7\n\x00\x00:'), bytearray(b'(\xd4\x06\xd7\n\x00\x00w'), bytearray(b'((\x1b\xd7\n\x00\x00\xe8')]


but now, when i'm reading temperatures with the ds.read_temp(), i only have 85 for all my sensors, and no other temperatures... I don't know what 's happening, i think it's come from the Parasite-Power, but i don't know know what kind of stuf i can do to fix this problem... so can someone help me ?

For information, i'm actually doing an diffusion chamber to look at the moving muons and other atomic and cosmic rays.
I give you my main.py

Code: Select all

import machine
import onewire, ds18x20


dat = machine.Pin('X1')
ow = onewire.OneWire(dat)
ds = ds18x20.DS18X20(ow)
while True:
  roms = ds.scan()
  ds.convert_temp()
  oled.fill(0)
  #oled.text("CPU tmp: " +("%2.1f"% ((esp32.raw_temperature()-32.0)*5/9))+"C", 0,1)
  oled.text("Temp  : "+"%2.3f"% ds.read_temp(roms[0]) +"C", 0, 1)
  oled.text("Temp2 : "+"%2.3f"% ds.read_temp(roms[1]) +"C", 0, 10)
  oled.text("Temp3 : "+"%2.3f"% ds.read_temp(roms[2]) +"C", 0, 19)
  ow.reset()
  oled.show()
  pyb.delay(500)

rhubarbdog
Posts: 168
Joined: Tue Nov 07, 2017 11:45 pm

Re: some troubles with the DS18B20-PAR temperature sensor

Post by rhubarbdog » Wed Feb 27, 2019 12:58 pm

In order for the DS18B20 to be able to perform accurate temperature conversions, sufficient power must be provided over the DQ line when a temperature conversion is taking place. Since the operating current of the DS18B20 is up to 1.5 mA, the DQ line will not have sufficient drive due to the 5k pullup resistor. This problem is particularly acute if several DS18B20s are on the same DQ and attempting to convert simultaneously.
To assure that the DS18B20-PAR has sufficient supply current, it is necessary to provide a strong pullup on the 1-Wire bus whenever temperature conversions are taking place or data is being copied from the scratchpad to EEPROM. This can be accomplished by using a MOSFET to pull the bus directly to the rail as shown in Figure 2. 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, and the bus must be held high by the pullup for the duration of the conversion (tconv) or data transfer (twr = 10 ms). No other activity can take place on the 1-Wire bus while the pullup is enabled.
See figure 2 in your pdf ds18b20-par.pdf for required extra circuitry.

Have you tried connecting pin 3 on your sensor to Vdd to not run them in parasitic power mode or are your sensors specifically 2 wire parasitic power only sensors.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: some troubles with the DS18B20-PAR temperature sensor

Post by Roberthh » Wed Feb 27, 2019 1:20 pm

That was my first thought too, but according to the data sheet, pin 3 is NC at the DS1820-PAR.

SirN Check
Posts: 10
Joined: Fri Dec 15, 2017 11:11 am

Re: some troubles with the DS18B20-PAR temperature sensor

Post by SirN Check » Thu Mar 26, 2020 9:06 pm

Reading DS18B20-PAR temperature (with ESP32)

This is how I got eight DS18B20’s, in PAR-mode, running using one I/O pin. (each on a 3m cable.)
Well, probably GXCAS 18B20, according to https://github.com/cpetrich/counterfeit_DS18B20

What really compelled me to use parasitic mode was the fact that some sensors did “latch-up” causing massive overheating. The 100mA PTC on Vdd saved the day…
I still use a PTC (+ “zener”) but just to protect the ESP32’s IO. Now EMC/ESD works ok…

The difficulty is to apply the strong pull-up directly(!) following the “.convert_temp()” as the “.init(machine.Pin.OUT)” takes a too long time. Less than 10us is required.
Using @micropython.viper to write to ESP32’s register seems to do the trick. In essence:

Code: Select all

@micropython.viper
def set_owPin_out():  # GPIO 0-39. Level already high. Turns on ‘normal output’.
    _GPIO_OUT = ptr32(0x3ff44088)  # ESP32.      See: esp32_technical_reference_manual_en.pdf 
    _GPIO_OUT[OneWirePin] = 0x0  # Normal output.   GPIO_PINn_REG(n:0-39)(0x88+0x4*n)
But !!! See next post for more.

Thank you ALL for facts and inspirations!
Looking forward to comments and improvements.
Last edited by SirN Check on Sat Jun 13, 2020 8:35 pm, edited 1 time in total.

SirN Check
Posts: 10
Joined: Fri Dec 15, 2017 11:11 am

Re: some troubles with the DS18B20-PAR temperature sensor

Post by SirN Check » Sat Jun 13, 2020 8:31 pm

First PAR-buzz didn't last very long.

The patch, using "viper" to turn on strong pullup, stopped working when const was replaced by variables in the onewire.py Sorry.

Thus, this proposal is to add the strong pullup before the _CONVERT byte is written.
The following class modifications work, alas not exactly according to bus intentions.

Code: Select all

from micropython import const
import onewire, ds18x20


class OneWire(onewire.OneWire):

    def normal_pull(self): 
        self.pin.init(self.pin.OPEN_DRAIN, self.pin.PULL_UP, value=1)

    def strong_pull(self):
        # pulls the 1-wire pin actively high. Use a small PTC as protection...
        self.pin.init(self.pin.OUT, value=1)

    def power_off_par(self):
        # may protect against (or even clear) latch-up.
        # If the pull-up resistor is connected to VCC, make sure it can withstand it.
        # To save power: Connect external pull-up to a seperate GPIO.
        self.pin.init(self.pin.OPEN_DRAIN, pull= None, value=0)  

    def reset(self, required=False):
        self.normal_pull()  # needed to restore Open Drain Output
        return super().reset(required)


class DS18X20(ds18x20.DS18X20):
    _CONVERT = const(0x44)

    def normal_pull(self):
        self.ow.normal_pull()

    def convert_temp_par(self):  # 0 => no strong. Neg => pull low. Pos => pull high.
        self.ow.reset(True)  # This will clear any remaining strong pull
        self.ow.writebyte(self.ow.SKIP_ROM)
        self.ow.strong_pull()  # Not very nice but works!
        self.ow.writebyte(_CONVERT)
Then try it:

Code: Select all

import utime
from machine import Pin
OneWirePin = const(14)  # GPIO for DS18x20-PAR connected sensors.

oneW = DS18X20(OneWire(Pin(OneWirePin)))

while True:
    try:
        oneW.convert_temp_par()
        utime.sleep_ms(750)
        roms = oneW.scan()
        for rom in roms:
            print('{:<8}'.format(oneW.read_temp(rom)), end=' ')
        print('Done: convert+delay, scan & read_temp. Now I take a short nap...')
        oneW.ow.power_off_par()  # Latch-up protection...
        utime.sleep(5)

    except Exception as e:
        print('Probably no sensor.', e)
        utime.sleep(2)
The impact of sensor self-heating during convert is reduced by taking the nap.

Post Reply