Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1-Wire direct support #429

Open
dariuszzbyrad opened this issue Dec 3, 2024 · 6 comments
Open

1-Wire direct support #429

dariuszzbyrad opened this issue Dec 3, 2024 · 6 comments
Assignees

Comments

@dariuszzbyrad
Copy link
Member

Following our discussion about adding direct support for 1-Wire in Pi4J, I made some research.

Devices Connected:

For experiments, I've connected two DS18B20 temperature sensors and one DS2413 GPIO device.

darek@raspberrypi:/sys/bus/w1/devices $ ls -l
total 0
lrwxrwxrwx 1 root root 0 Dec  2 13:57 28-06219443087e -> ../../../devices/w1_bus_master1/28-06219443087e
lrwxrwxrwx 1 root root 0 Dec  2 13:57 28-06219564daed -> ../../../devices/w1_bus_master1/28-06219564daed
lrwxrwxrwx 1 root root 0 Dec  2 12:26 3a-0000005eaee8 -> ../../../devices/w1_bus_master1/3a-0000005eaee8
lrwxrwxrwx 1 root root 0 Dec  2 13:57 w1_bus_master1 -> ../../../devices/w1_bus_master1

1. Using sysfs for DS18B20:

The DS18B20 works via sysfs, and you can read temperature data as follows:

darek@raspberrypi:/sys/bus/w1/devices/28-06219443087e $ ls -l
total 0
-rw-r--r-- 1 root root 4096 Dec  2 14:06 alarms
-rw-r--r-- 1 root root 4096 Dec  2 14:06 conv_time
lrwxrwxrwx 1 root root    0 Dec  2 12:23 driver -> ../../../bus/w1/drivers/w1_slave_driver
--w------- 1 root root 4096 Dec  2 14:06 eeprom_cmd
-r--r--r-- 1 root root 4096 Dec  2 14:06 ext_power
-rw-r--r-- 1 root root 4096 Dec  2 14:06 features
drwxr-xr-x 3 root root    0 Dec  2 12:23 hwmon
-r--r--r-- 1 root root 4096 Dec  2 14:06 id
-r--r--r-- 1 root root 4096 Dec  2 14:06 name
drwxr-xr-x 2 root root    0 Dec  2 14:06 power
-rw-r--r-- 1 root root 4096 Dec  2 14:06 resolution
lrwxrwxrwx 1 root root    0 Dec  2 12:23 subsystem -> ../../../bus/w1
-r--r--r-- 1 root root 4096 Dec  2 14:06 temperature
-rw-r--r-- 1 root root 4096 Dec  2 12:23 uevent
-rw-r--r-- 1 root root 4096 Dec  2 14:06 w1_slave
darek@raspberrypi:/sys/bus/w1/devices/28-06219443087e $ cat temperature 
21437

or from the w1_slave file:

darek@raspberrypi:/sys/bus/w1/devices/28-06219443087e $ cat w1_slave 
57 01 4b 46 7f ff 0c 10 38 : crc=38 YES
57 01 4b 46 7f ff 0c 10 38 t=21437

2. Using sysfs for DS2413:

The DS2413 GPIO device works similarly, but it uses a different mechanism for interacting with the output state. You can check its state as follows:

darek@raspberrypi:/sys/bus/w1/devices/3a-0000005eaee8 $ ls -l
total 0
lrwxrwxrwx 1 root root    0 Dec  2 12:24 driver -> ../../../bus/w1/drivers/w1_slave_driver
-r--r--r-- 1 root root 4096 Dec  2 12:24 id
-r--r--r-- 1 root root 4096 Dec  2 12:24 name
-rw-rw-r-- 1 root root    1 Dec  2 12:27 output
drwxr-xr-x 2 root root    0 Dec  2 12:24 power
-r--r--r-- 1 root root    1 Dec  2 12:24 state
lrwxrwxrwx 1 root root    0 Dec  2 12:24 subsystem -> ../../../bus/w1
-rw-r--r-- 1 root root 4096 Dec  2 12:23 uevent
darek@raspberrypi:/sys/bus/w1/devices/3a-0000005eaee8 $ cat state | xxd -b
00000000: 01111000                                               x

And change state:

darek@raspberrypi:/sys/bus/w1/devices/3a-0000005eaee8 $ printf '\xF2' | tee output >> /dev/null
tee: output: Permission denied

It requires sudo:

darek@raspberrypi:/sys/bus/w1/devices/3a-0000005eaee8 $ printf '\xF2' | sudo tee output >> /dev/null

As I described, each type of 1-Wire device would still require a separate implementation. This is because the w1-gpio driver does not provide a unified interface for all device types. This means we need to implement a class for each device we want to support. Additionally, since it is part of sysfs, it should be included in our LinuxFS provider. Lastly, the statement 'Doesn’t need sudo' on this page will no longer be valid.

3. Using OWFS (External Library):

While theoretically, the owfs library can be used for interacting with 1-Wire devices and controlling the GPIO pins (such as with JNI), it is not recommended due to well-known issues with races and other bugs:

"Despite the project name, the owfs package itself is NOT recommended for any real use, it has well known issues with races etc."

4. Using ioctl:

The w1-gpio driver in Linux does not support ioctl commands for direct interaction with 1-Wire devices. Instead, it uses sysfs for device interaction. ioctl is more commonly used with devices that expose a character device interface in /dev/, but 1-Wire devices are managed through sysfs entries, not ioctl.

Conclusion:

  • sysfs doesn't provide a universal method to send commands directly to all types of 1-Wire devices.
  • Each 1-Wire device often requires its own specific driver and sysfs interface.
  • Other solution is use the DS2482 I2C-to-1-Wire bridge (it also provided dedicated board, as it provides more robust handling of 1-Wire devices through I2C.
  • Writing a custom kernel driver to meet your specific needs is an option, but it requires significant effort and is definitely not a 'low-hanging fruit' solution."

Question

@FDelporte, @eitch, @taartspi: Do we agree to introduce limited support for 1-Wire devices as part of the LinuxFS provider, starting with the DS18B20 and progressively adding support for other devices like the DS2413?

@FDelporte
Copy link
Member

The move from Pi4J V1 to V2 specifically included the removal of device-specific implementations to reduce maintenance and minimize testing. That's why @taartspi created a lot of example implementations for specific devices in https://github.com/Pi4J/pi4j-example-devices.

Can we have a similar approach for 1wire with only generic methods in Pi4J and device code in an example project?

@FDelporte
Copy link
Member

BTW thanks for the detailed info and research @dariuszzbyrad :-)

@eitch
Copy link
Member

eitch commented Dec 3, 2024

I agree with @FDelporte thanks for the research!
And i also have to agree, that adding specific 1-wire device in pi4j-v2 is not the way to go, as this will lead to an explosion of maintenance on the core repository. Perhaps we can add the one or other class in the core repository which would be needed over and over regardless of the devices then added to @taartspi 's repository.

@taartspi
Copy link
Collaborator

taartspi commented Dec 3, 2024

I also agree these individual devices should be added to the example project and not the pi4j project

@dariuszzbyrad
Copy link
Member Author

Thanks for answer!
For me, it's clear: we should avoid implementing support for specific devices.

The next step is to make experiments with additional 1-Wire devices (I’ve ordered DS2438, DS2408, DS28E05, DS2431, DS9092 from 'my friends') to identify common communication patterns. I mean about reading from or writing to specific virtual files (single or multiple bytes) and other operations. Once the experimentation is complete, I'll propose an API for 1-Wire support.

@dariuszzbyrad dariuszzbyrad self-assigned this Dec 3, 2024
@dariuszzbyrad dariuszzbyrad changed the title Summary of 1-Wire direct support 1-Wire direct support Dec 3, 2024
@dariuszzbyrad
Copy link
Member Author

I’m back with a proposal for an API to support 1-Wire devices. Currently, it’s just the API itself, but implementation in the LinuxFS plugin and a mock version still need to be added.

Changes:
You can review the proposed changes here:
develop...onewire-poc

Available API:
The API is available at the following location:
https://github.com/Pi4J/pi4j-v2/blob/onewire-poc/pi4j-core/src/main/java/com/pi4j/io/onewire/OneWireFileDataReaderWriter.java

Example Usage:
For an example of how to use this API with DS18B20 and DS2413 devices, refer to the following code:
https://github.com/Pi4J/pi4j-v2/blob/onewire-poc/pi4j-test/src/main/java/com/pi4j/test/OneWireTest.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants