DS18B20 temperature sensor



  • I'd like to read the temperature from my LoPy using a DS18B20 sensor. My problem is that this is a digital sensor using the 1-wire protocol, and as far as I can tell, there's no 1-wire library on the LoPy? Looking at the Micro Python documentation (https://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/onewire.html) I see that they've got a onewire module, they've even got a ds18x20 module, but that's not available on my LoPy I think. I've been searching the Internet looking for a suitable 1-wire library, but so far without any luck. I can find some that require libusb or the like, but that won't work I assume.

    Does anyone know how I should go about reading from a 1-wire sensor on a LoPy?

    Best regards,
    Mads



  • @livius
    it didn't seem to work with Pymakr. The Atom IDE with Pymakr pluggin solution that was updated as a tutorial last week definitely helped.
    It seems to be good now.
    Thank you!



  • @Guizmolux

    but do you have upgraded firmware?
    current is 1.6.12.b1
    what is yours? you can check firmware version by

    os.uname()
    

    if it is really old then go to
    https://www.pycom.io/resources/

    next, is this how your onewire looks like?
    https://github.com/pycom/pycom-libraries/blob/master/lib/onewire/onewire.py

    put it in the same place where you have main.py or in lib subfolder

    and then you can simply use it

    import time
    from machine import Pin
    from onewire import DS18X20
    from onewire import OneWire
    
    #DS18B20 data line connected to pin P10
    ow = OneWire(Pin('P10'))
    temp = DS18X20(ow)
    
    while True:
        print(temp.read_temp_async())
        time.sleep(1)
        temp.start_convertion()
        time.sleep(1)
    


  • @livius
    I get that. Copied the code into a onewire.py file. Where should I put it?
    I've tried to execute before the main.py file and I always get the "cannot import name OneWire" or "DS18X20".
    is the const() a problem in class OneWire ?



  • @Guizmolux
    I do not know if you ask for this
    but fully working examlpe code you can find in official docs
    https://docs.pycom.io/pycom_esp32/pycom_esp32/tutorial/includes/onewire.html



  • @dchappel
    I'm very new to this (and LoPy and python) : where is your lib directory ?(I'll adapt to my own config).



  • @DonHugo

    (sysname='LoPy', nodename='LoPy', release='1.5.1.b1', version='v1.8.6-423-g18444a2 on 2017-02-07', machine='LoPy with ESP32', lorawan='1.0.0')
    

    The pin not going high message sounds more like a wiring issue? Are you sure your wiring is correct and the pullup resistor bridges +3.3V and data? I had same issue and realized that I had sensor wire colors mixed up...



  • @dchappel i cant get this to work, i get

    # code block
    Running 
    Traceback (most recent call last):
      File "<stdin>", line 7, in <module>
      File "ds18x20.py", line 47, in __init__
      File "onewire.py", line 246, in scan
      File "onewire.py", line 269, in _search
      File "onewire.py", line 90, in reset
    OSError: OneWire pin didn't go high
    >
    MicroPython v1.8.6-464-g0f843911 on 2017-02-17; LoPy with ESP32
    Type "help()" for more information.
    

    what firmware are you using?



  • @sk

    onewire.py and ds18x20.py are in my lib directory (available here per @LoneTech: http://donkey.vernier.se/~yann/onewire.zip)

    This works for me:

    import time
    from machine import Pin
    from ds18x20 import DS18X20
    
    while True:
        
        d=DS18X20(Pin('P23', mode=Pin.OUT))
        
        result=(d.read_temps())
        
        if result:
            val=str(result[0]*1.8+32)
        else:
            val="-1"
            
        print(val)
        
        time.sleep(5)
    


  • @iber how did you import the ds18x20 module? I am getting the error:

    Traceback (most recent call last):
    File "<stdin>", line 2, in <module>
    ImportError: no module named 'ds18x20'
    

    I have pasted the ds18x20.py into the folder my other py files and project is in. Is that not where it goes?



  • @madsdk P23/G10 has SD_CLK (pulse clock) required for bit banging.



  • @Colateral I checked the code an conv_temp function shall be changed as following

    def convert_temp(self, rom0, data):
        """
        Convert the raw temperature data into degrees celsius and return as a fixed point with 2 decimal places.
        """
        temp_lsb = data[0]
        temp_msb = data[1]
        if rom0 == 0x10:
            if temp_msb != 0:
                # convert negative number
                temp_read = temp_lsb >> 1 | 0x80  # truncate bit 0 by shifting, fill high bit with 1.
                temp_read = -((~temp_read + 1) & 0xff) # now convert from two's complement
            else:
                temp_read = temp_lsb >> 1  # truncate bit 0 by shifting
            count_remain = data[6]
            count_per_c = data[7]
            temp = 100 * temp_read - 25 + (count_per_c - count_remain) // count_per_c
            return temp
        elif rom0 == 0x28:
            temp = (temp_msb << 8 | temp_lsb) / 16
            if (temp_msb & 0xf8) == 0xf8 :  # for negative temperature
               temp -= 0x1000
    
            return temp * 1000
        else:
            assert False


  • @michal The temperature output(2525 = 25.25 degrees celsius) is as 4 digits output. The strange fact is that If I read the same sensor with raspberry pi or on Arduino I got the value as 5 digits. (eq 25437)



  • @LoneTech Thank you! I'll give it a try as soon as I have time :)



  • I got it working now.

    from machine import Pin
    from ds18x20 import DS18X20
    d=DS18X20(Pin('G17', mode=Pin.OUT))
    result=d.read_temps()
    print(result)
    


  • @LoneTech have you got a working example with the Lopy/Wipy?
    When I try to get it working on a Lopy I get a 'OneWire pin didn't go high' error when I run this piece of code d=DS18X20(Pin('G5'))



  • @JF002 Sure. The patch and modules are in http://donkey.vernier.se/~yann/onewire.zip - sorry for taking so long.



  • @LoneTech Would you mind sharing your port of the MicroPython library on the Lopy?It's too bad that this library is not portable across different MicroPython board...
    Once I've confirmed that my DS18B20 works fine on the Lopy, I'll try to use the RMT instead of this bitbanging library :)



  • While I've had success porting the prior micropython bitbanging onewire code (it was mostly changing the IO mode to open drain, and replacing pyb with machine), I just managed to wake up the RMT peripheral. It could conceivably run onewire with extremely precise timing without requiring much CPU. It should only require two RMT channels (one input, one output) mapped on the same GPIO, set to open drain. 6µs should be no problem at all considering I did 0.05µs for the WS2812 :)

    The micropython onewire example code is at https://github.com/micropython/micropython/tree/master/drivers/onewire and my initial RMT access code is at https://github.com/lonetech/LoPy

    By the way, I suspect the issue with P19 was the bug when accessing GPIO>=31. P19 is GPIO 32.



  • @acheesehead can you provide a link to the onewire, ds18x20 and pyb.py files?


Log in to reply
 

Looks like your connection to Pycom Forum was lost, please wait while we try to reconnect.