Page 1 of 1

some troubles with the DS18B20-PAR temperature sensor

Posted: Mon Feb 18, 2019 6:50 pm
by Sikolenski
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)

Re: some troubles with the DS18B20-PAR temperature sensor

Posted: Wed Feb 27, 2019 12:58 pm
by rhubarbdog
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.

Re: some troubles with the DS18B20-PAR temperature sensor

Posted: Wed Feb 27, 2019 1:20 pm
by Roberthh
That was my first thought too, but according to the data sheet, pin 3 is NC at the DS1820-PAR.

Re: some troubles with the DS18B20-PAR temperature sensor

Posted: Thu Mar 26, 2020 9:06 pm
by SirN Check
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.

Re: some troubles with the DS18B20-PAR temperature sensor

Posted: Sat Jun 13, 2020 8:31 pm
by SirN Check
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.