zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.39k stars 6.37k forks source link

Add sample and documentation on how to convert mulitple ds18b20 using an ds2482-800 #63710

Open dolence opened 10 months ago

dolence commented 10 months ago

There is no sample on how to connect and read multiple ds18b20 connected trhough an ds2482-800. I have two ds2482-800 connected on my custom board. I'm able to scan sensors connected on channel 0 of the first IC using the sample provided, but there is no information on how to convert the temperature on multiple sensors connected using this IC.

Is everything done using ds2482 functions to read and set bytes of data or is there any easier way to do this using sensor api and ds18b20 functions?

On my use case I will need to scan every channel on both ds2482 and store them in order on my eeprom. One way I found was scanning an entire channel and order them cycling from the first to the last sensor, identifying them by forcing a temperature change on the sensor on that particular cable, doing this in sequence from the first to the last one.

Also, I'm not sure my overlay dts file is correct. I do need to declare every channel or just the first on each ds2482 would be OK?

This is what I have right now:

&i2c2 {
    w1@18 {
        compatible = "maxim,ds2482-800";
        reg = <0x18>;

        #address-cells = <1>;
        #size-cells = <0>;

        w1_a_ch0: ch@0 {
            compatible = "maxim,ds2482-800-channel";
            reg = <0>;
        };      
        w1_a_ch1: ch@1 {
            compatible = "maxim,ds2482-800-channel";
            reg = <1>;
        };
        w1_a_ch2: ch@2 {
            compatible = "maxim,ds2482-800-channel";
            reg = <2>;
        };      
        w1_a_ch3: ch@3 {
            compatible = "maxim,ds2482-800-channel";
            reg = <3>;
        };
        w1_a_ch4: ch@4 {
            compatible = "maxim,ds2482-800-channel";
            reg = <4>;
        };      
        w1_a_ch5: ch@5 {
            compatible = "maxim,ds2482-800-channel";
            reg = <5>;
        };
        w1_a_ch6: ch@6 {
            compatible = "maxim,ds2482-800-channel";
            reg = <6>;
        };      
        w1_a_ch7: ch@7 {
            compatible = "maxim,ds2482-800-channel";
            reg = <7>;
        };              
    };
    w1@19 {
        compatible = "maxim,ds2482-800";
        reg = <0x19>;

        #address-cells = <1>;
        #size-cells = <0>;

        w1_b_ch0: ch@0 {
            compatible = "maxim,ds2482-800-channel";
            reg = <0>;
        };      
        w1_b_ch1: ch@1 {
            compatible = "maxim,ds2482-800-channel";
            reg = <1>;
        };
        w1_b_ch2: ch@2 {
            compatible = "maxim,ds2482-800-channel";
            reg = <2>;
        };      
        w1_b_ch3: ch@3 {
            compatible = "maxim,ds2482-800-channel";
            reg = <3>;
        };
        w1_b_ch4: ch@4 {
            compatible = "maxim,ds2482-800-channel";
            reg = <4>;
        };      
        w1_b_ch5: ch@5 {
            compatible = "maxim,ds2482-800-channel";
            reg = <5>;
        };
        w1_b_ch6: ch@6 {
            compatible = "maxim,ds2482-800-channel";
            reg = <6>;
        };      
        w1_b_ch7: ch@7 {
            compatible = "maxim,ds2482-800-channel";
            reg = <7>;
        };              
    };
};

Any help would be very appreciated.

github-actions[bot] commented 10 months ago

Hi @dolence! We appreciate you submitting your first issue for our open-source project. 🌟

Even though I'm a bot, I can assure you that the whole community is genuinely grateful for your time and effort. 🤖💙

dolence commented 10 months ago

Giving the lack of documentation on this, I was told to mention and ask @str4t0m for help.

dolence commented 8 months ago

Hi! Any guidance on here?

ubieda commented 2 months ago

Hi, I'm going over this and the on-going discussions on Discord. I'm capturing some thoughts here to hopefully provide some guidance on how to move forward:

  1. I suggest decoupling the issue in separate areas and tackle them in isolation. In this case, I see two issues: a. How to add multiple devices to a W1 bus with DS2482-800. b. How to use the Sensor APIs to interact with multiple DS18B20s at once.

  2. Thoughts on how to add multiple devices to a W1 bus with DS2482-800 DS2482-800 implements a W1 driver, and from a perspective of W1 device drivers (e.g: DS18B20), it should be transparent whether that signal comes from a MCU pin or from a bridge. As you've already mentioned, there's a different device-tree syntax to express devices that go on each of the W1 lines (e.g: one on IO1, one on IO2, and so forth) vs lump them in the same line (e.g: both on W1). By the looks of it, this should just work and no additional effort on your side.

  3. Thoughts on how to use the Sensor APIs to interact with multiple DS18B20s at once: a. Fitting in the "Device Model" to your use-case: The difference here is what we consider a "device" in terms of the sensor APIs. Currently, the DS18B20 driver models the "device" as a single-instance. Your use-case calls for changing that paradigm towards a "device" being an array of DS18B20, with each instance being a channel. Unfortunately, this is not developed so you'd have to come up with this solution or wait until someone else contributes it. b. Suggestions on expanding the driver: Essentially, you'd implement a driver using the sensor read/decode APIs to take advantage of the sensor_chan_spec (which includes the channel-type + index). Some specifics on how to achieve that:

    • Have the sensor driver use the W1 bus driver API vs DS2480-800 methods directly: This will keep the abstraction on whether it's an expander vs a direct driver (as pointed above).
    • Define Number of channels: Define a place to declare how many channels you expect to handle per device (again, array of DS18B20). Ideally, this would be using YAML, I believe, but it may not be ready yet: #71235), so using DTS bindings may also be OK.
    • Define Strategy for scanning the bus: Define when should the device "scan" the bus to know how many channel readings to expect. This could be either upon initialization (once per boot) or on every read. My two cents is the simpler the better.
    • Gathers samples: Using the sensor_read API, performing a non-blocking read and then a blocking portion to collect those samples.
    • Decodes them into Celsius: Implement a decoder in your driver to turn all those results in an array of temperature readings in SI units.

I'm CC-ing @teburd in case I've missed anything.

LMK if you have any questions!