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?
@livius thanks that did the trick
@dchappel I followed your main.py with both onewire.py and ds18x20.py in my lib, this works for the first temp reading, every following temp reading doesn't change from the first. I moved the sensor into the fridge and then freezer and the readings styed the same. Once I reset the device it will bring the new reading but only again for the first reading. Did you find this with yours?
- what you got from (you must change P10 to pin you use):
ow = OneWire(Pin('P10')) ow.roms
if nothing then test(double ow)
- which sensor do you have exactly? woterproof or some different?
soren last edited by soren
When I do exactly as you state here, and connect the temperature sensor to 3.3v, and with the 4,7k resistor between sig and 3.3v - I get this error:
File "main.py", line 22, in <module>
File "/flash/lib/onewire.py", line 190, in read_temp_async
IndexError: list index out of range
I have latest firmware and atom plugin
EDIT: after checking that I have latest onewire from here https://github.com/pycom/pycom-libraries/blob/master/lib/onewire/onewire.py this error was gone. I then had to correct your spelling mistake in "convertion" and now it's working, but despite everything being hooked up correctly - it prints out "None"...
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.
livius last edited by livius
but do you have upgraded firmware?
what is yours? you can check firmware version by
if it is really old then go to
next, is this how your onewire looks like?
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)
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 ?
I do not know if you ask for this
but fully working examlpe code you can find in official docs
I'm very new to this (and LoPy and python) : where is your lib directory ?(I'll adapt to my own config).
(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?
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*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 temp_msb = data 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 count_per_c = data 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 :)
iber last edited by
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)