Handling Multiple DS18B20 Sensors on One-Wire Bus with nRF52840 DK Using Zephyr OS

Hello,

I am currently working on a project using the nRF52840 DK, where I am trying to connect multiple DS18B20 temperature sensors to a single One-Wire bus. I am using Zephyr OS 3.5.99 for this project.

Here is the relevant part of my Device Tree configuration:

&arduino_serial {
status = "okay";

w1_0: w1-zephyr-serial-0 {
compatible = "zephyr,w1-serial";
#address-cells = <1>;
#size-cells = <0>;
status = "okay";

testlabel: ds18b20 {
compatible = "maxim,ds18b20";
family-code = <0x28>;
resolution = <12>;
status = "okay";
};

testlabel2: ds18b202 {
compatible = "maxim,ds18b20";
family-code = <0x28>;
resolution = <12>;
status = "okay";
};
};
};


When I compile, I receive the following error: <err> DS18B20: ROM required, because multiple slaves are on the bus

Here is the C code I am using to interact with the sensors:

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/sensor.h>

static const struct device *get_ds18b20_device(void) {
const struct device *const dev = DEVICE_DT_GET_ANY(maxim_ds18b20);

if (dev == NULL) {
printk("\nError: no device found.\n");
return NULL;
}

if (!device_is_ready(dev)) {
printk("\nError: Device \"%s\" is not ready; check the driver initialization logs for errors.\n", dev->name);
return NULL;
}

printk("Found device \"%s\", getting sensor data\n", dev->name);
return dev;
}

int main(void) {
const struct device *dev = get_ds18b20_device();

if (dev == NULL) {
return 0;
}

while (1) {
struct sensor_value temp;
sensor_sample_fetch(dev);
sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp);

printk("Temp: %d.%06d\n", temp.val1, temp.val2);
k_sleep(K_MSEC(2000));
}
return 0;
}

 

I'm struggling to incorporate the readings from both sensors into a single output. I am a beginner, so I would appreciate any help or guidance on how to resolve these issues.

Thank you!




  • #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/sensor.h>
    #include <zephyr/drivers/sensor/w1_sensor.h>
    #include <zephyr/sys/byteorder.h>
    #include <zephyr/sys/util.h>
    
    int main(void) {
        const struct device *dev0, *dev1;
        struct sensor_value temp;
        struct w1_rom w1rom0, w1rom1;
        struct sensor_value romval0, romval1;
    
        dev0 = device_get_binding("SENSOR_DS18B20_0");
        if (!dev0 || !device_is_ready(dev0)) {
            printk("DS18B20 sensor device 0 is not ready or found.\n");
            return -1;
        }
    
        dev1 = device_get_binding("SENSOR_DS18B20_1");
        if (!dev1 || !device_is_ready(dev1)) {
            printk("DS18B20 sensor device 1 is not ready or found.\n");
            return -1;
        }
    
        uint64_t rom_address0 = 0x282d0b07d6013c05;
        uint64_t rom_address1 = 0x28f80407d6013c45;
    
        w1_uint64_to_rom(rom_address0, &w1rom0);
        w1_rom_to_sensor_value(&w1rom0, &romval0);
        w1_uint64_to_rom(rom_address1, &w1rom1);
        w1_rom_to_sensor_value(&w1rom1, &romval1);
    
        printk("Starting to read temperatures from both W1 devices...\n");
    
        while (1) {
            sensor_attr_set(dev0, SENSOR_CHAN_ALL, SENSOR_ATTR_W1_ROM, &romval0);
            if (sensor_sample_fetch(dev0) < 0) {
                printk("Failed to fetch data from DS18B20_0 with ROM %llx.\n", rom_address0);
            } else {
                sensor_channel_get(dev0, SENSOR_CHAN_AMBIENT_TEMP, &temp);
                printk("Temperature from DS18B20_0 at ROM %llx: %d.%06d°C\n", rom_address0, temp.val1, temp.val2);
            }
    
            k_sleep(K_SECONDS(2));
    
            sensor_attr_set(dev1, SENSOR_CHAN_ALL, SENSOR_ATTR_W1_ROM, &romval1);
            if (sensor_sample_fetch(dev1) < 0) {
                printk("Failed to fetch data from DS18B20_1 with ROM %llx.\n", rom_address1);
            } else {
                sensor_channel_get(dev1, SENSOR_CHAN_AMBIENT_TEMP, &temp);
                printk("Temperature from DS18B20_1 at ROM %llx: %d.%06d°C\n", rom_address1, temp.val1, temp.val2);
            }
    
            k_sleep(K_SECONDS(2));
        }
    
        return 0;
    }



    &arduino_serial {
        status = "okay";
    
        w1_0: w1-zephyr-serial-0 {
            compatible = "zephyr,w1-serial";
            #address-cells = <1>;
            #size-cells = <0>;
            status = "okay";
    
            ds18b20 {
                label = "SENSOR_DS18B20_0";
                compatible = "maxim,ds18b20";
                family-code = <0x28>;
                resolution = <12>;
                status = "okay";
            };
            ds18b201 {
                label = "SENSOR_DS18B20_1";
                compatible = "maxim,ds18b20";
                family-code = <0x28>;
                resolution = <12>;
                status = "okay";
            };
        };  
    };



Related