Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

DS18X20 multiple sensors
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

DS18X20 multiple sensors

by AS_TCC on Wed Aug 12, 2020 12:24 pm

Hello,
The adafruit DS18X20 guide has been excellent to follow, as well as the SSD1306 guide. At the moment I am successfully reading temperature off a single DS18S20 sensor and displaying the value on a stemma QT 0.96" display. Works great! Now, I'd like to add three more sensors to the onewire bus. The sensors will create a course heat map of a catalyst oven I am designing, so I'd like to know which sensor corresponds to what index of the scan so I know what region of the oven corresponds to each sensor. Do sensors appear in the onewire bus according to their proximity/order of wiring? will the scan be different on different power-ups/resets so I'll need to actually track the ROM values? Do you have a suggestion (or a link to an example that I might have just not seen) for managing multiple sensors?
I hope your day is going great!

Code: Select all | TOGGLE FULL SIZE
import time
import board
import displayio
import terminalio
from adafruit_display_text import label
import adafruit_displayio_ssd1306

from adafruit_onewire.bus import OneWireBus
from adafruit_ds18x20 import DS18X20


# Initialize one-wire bus on board pin D5.
ow_bus = OneWireBus(board.D5)

# Scan for sensors and grab the first one found.
ds18 = DS18X20(ow_bus, ow_bus.scan()[0])

displayio.release_displays()

i2c = board.I2C()
display_bus = displayio.I2CDisplay(i2c, device_address=0x3d)

WIDTH = 128
HEIGHT = 64  # Change to 64 if needed

display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=WIDTH, height=HEIGHT)
welcome = "welcome"
splash = displayio.Group(max_size=10, scale=2)
display.show(splash)
text_welcome = label.Label(terminalio.FONT, text=welcome, color=0xFFFFFF, x=28, y=HEIGHT // 3 - 1)
splash.append(text_welcome)
# Main loop to print the temperature every second.
while True:
    temp_one = ds18.temperature
    text = "Ct "+str(temp_one)+"C"
    text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF, x=0, y=3)
    splash.pop()
    splash.append(text_area)
    print("Temperature: {0:0.3f}C".format(temp_one))
    time.sleep(.5)

AS_TCC
 
Posts: 5
Joined: Mon Sep 10, 2018 1:45 pm

Re: DS18X20 multiple sensors

by tannewt on Thu Aug 13, 2020 2:40 pm

I believe the IDs returned by `ow_bus.scan()` are static for each individual sensor. The IDs and scan order are independent of the wiring. You should be able to remember the 4 IDs and associate them with the actual sensor.

tannewt
 
Posts: 1792
Joined: Thu Oct 06, 2016 8:48 pm

Re: DS18X20 multiple sensors

by AS_TCC on Thu Aug 13, 2020 2:54 pm

Hi Tannewt,
Thanks for getting back to me! I did a little homework last night was able to get the addresses, hard code them as bytearrays, then compare the output from scan and assign each one to the proper sensor. I really appreciate you guys being active on the forum and helping me. I'll put my code below in case someone else wants to do things how I did it. I'm sure there's a much more "pythonic" way... my brain just doesn't quite think like that yet. I also realize I am using global, which is probably a bad thing.

Code: Select all | TOGGLE FULL SIZE
#Known Sensor Roms (determined from successively adding a sensor
#and checking for loop output
s1rom = bytearray(b'\x10\x9f\xa4\xa9\x03\x08\x00\xea') #sensor1's rom
s2rom = bytearray(b'\x10\xea\xdd\xa8\x03\x08\x00\x88') #sensor2's rom
s3rom = bytearray(b'\x101\xb6\xa9\x03\x08\x00Z') #sensor3's rom
s4rom = bytearray(b'\x10\xf0\r\xa9\x03\x08\x00\xcd') #sensor4's rom

# Initialize one-wire bus on board pin D5.
ow_bus = OneWireBus(board.D5)
devices = ow_bus.scan()

# un-comment the for loop to print device roms to make a list of known sensors in the system
# for device in devices:
    #print("ROM = {} \tFamily = 0x{:02x}".format([hex(i) for i in device.rom], device.family_code))
    #print(device.rom) #use the output of this as your sXrom value.

#assign known devices to corresponding sensor# (so we know which sensor is where)
for c, device in enumerate(devices):
    print(c, device.rom)
    if device.rom == s1rom:
        global s1
        s1 = c
    elif device.rom == s2rom:
        global s2
        s2 = c
    elif device.rom == s3rom:
        global s3
        s3 = c
    elif device.rom == s4rom:
        global s4
        s4 = c
    else:
        print("unknown rom, new sensor?")
print("scan indexes: s1:{} s2:{} s3:{} s4:{}".format(s1,s2,s3,s4))

sensor1 = DS18X20(ow_bus, ow_bus.scan()[s1])

sensor2 = DS18X20(ow_bus, ow_bus.scan()[s2])

sensor3 = DS18X20(ow_bus, ow_bus.scan()[s3])

sensor4 = DS18X20(ow_bus, ow_bus.scan()[s4])

AS_TCC
 
Posts: 5
Joined: Mon Sep 10, 2018 1:45 pm

Re: DS18X20 multiple sensors

by tannewt on Thu Aug 13, 2020 3:00 pm

For something this simple hard coding is just fine. I don't think you actually need the `global` keywords. They are only needed inside `def` and `class` I believe.

tannewt
 
Posts: 1792
Joined: Thu Oct 06, 2016 8:48 pm

Please be positive and constructive with your questions and comments.