DS18X20 rom ID lookup

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
devnull
Posts: 473
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

DS18X20 rom ID lookup

Post by devnull » Tue Jan 17, 2017 5:16 am

I am attempting to associate the ROM of a DS18X20 with a dictionary so that I can identify it.

First thing I noticed is that onewire.py sometimes prepends a '(' to the byte array.

Second problem is I am unable to select the dictionary ds_roms using the parsed rom id.

Running this on python2 succeeds on https://repl.it/FLDY but refuses to work on upython.

The device is WIPY2 with latest firmware.

```
ds_roms = {
"(\xff\xfe\x88\x84\x16\x03\xd1":"living_room",
"\x10\xe5x\xd5\x01\x08\x007":"bed_room"
}

devices = [bytearray(b'(\xff\xfe\x88\x84\x16\x03\xd1'), bytearray(b'\x10\xe5x\xd5\x01\x08\x007')]

for device in devices:
DEV = str(bytes(device)).replace("'",'').strip('b')
print(ds_roms[DEV])
```

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: DS18X20 rom ID lookup

Post by pythoncoder » Tue Jan 17, 2017 8:21 am

WiPy2 is supported on the Pycom Forum https://forum.pycom.io/.
Peter Hinch
Index to my micropython libraries.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: DS18X20 rom ID lookup

Post by dhylands » Tue Jan 17, 2017 8:36 am

String in python will use ASCII characters whenever possible. So the string '(\xff' is really the same thing as '\x28\xff'. If you want the string to always be hex, you can use ubinascii.hexlify:

Code: Select all

>>> import ubinascii
>>> id = b'(\xff\xfe\x88\x84\x16\x03\xd1'
>>> ubinascii.hexlify(id)
b'28fffe88841603d1'
MicroPython is based on Python 3, and this has some changes to the way strings and bytestrings work. "abc" is a string and b'abc' is a byte string. If your keys are strings then you can't use byte strings as lookups or vice-versa. So this works:

Code: Select all

ds_roms = {
b"(\xff\xfe\x88\x84\x16\x03\xd1":"living_room",
b"\x10\xe5x\xd5\x01\x08\x007":"bed_room"
}

devices = [bytearray(b'(\xff\xfe\x88\x84\x16\x03\xd1'), bytearray(b'\x10\xe5x\xd5\x01\x08\x007')]

for device in devices:
    print(ds_roms[bytes(device)])
. Because strings are utf-8 encoded, you probably shouldn't try to convert the ROM ids into strings since they may contain invalid utf-8 sequences. If you have a string which only contains ASCII characters, then you can convert a byte string into a string by using:

Code: Select all

>>> x = b'abc'
>>> str(x, 'utf-8')
'abc'
So if you used the hex string version of the ROM id then you could do:

Code: Select all

import ubinascii

ds_roms = {
'28fffe88841603d1':"living_room",
'10e578d501080037':"bed_room"
}

devices = [bytearray(b'(\xff\xfe\x88\x84\x16\x03\xd1'), bytearray(b'\x10\xe5x\xd5\x01\x08\x007')]

for device in devices:
    dev_key = str(ubinascii.hexlify(device), 'utf-8')
    print(ds_roms[dev_key])
Hopefully that will give you some ideas about how to deal with this.

User avatar
devnull
Posts: 473
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: DS18X20 rom ID lookup

Post by devnull » Fri Jan 20, 2017 3:53 am

Dave, thanks so much for helping with this, and for such a comprehensive explanation.

That certainly works and is much more concise than the work around method I came up with

Cheers

Post Reply