diff --git a/content/_index.md b/content/_index.md
index 8f50b4dc44..0c314f69f9 100644
--- a/content/_index.md
+++ b/content/_index.md
@@ -4,7 +4,7 @@ title: Welcome to Pi4J
## Welcome to Pi4J
-**Latest release: V3.0.3 (2025-09-23, see [Release Notes](/about/release-notes/)).**
+**Latest release: V4.0.0 (2025-??-??, see [Release Notes](/about/release-notes/)).**
This project is intended to provide **a friendly object-oriented I/O API and implementation libraries for Java Programmers** to access the **full I/O capabilities of the Raspberry Pi platform**. This project abstracts the low-level native integration and interrupt monitoring to enable Java programmers to **focus on implementing their application business logic**.
@@ -28,6 +28,8 @@ The Pi4j project has evolved in all these years as the whole Java eco-system and
* In 2.5.0, support for the Raspberry Pi 5 was added. Because of the new [GPIO chip RP1](https://www.raspberrypi.com/documentation/microcontrollers/rp1.html), a new GPIO Provider was needed. See the [this interview](/blog/2024/20240318_interview_alexander_liggesmeyer/).
* [V3.X.X](/about/info-v3): Based on Pi4J 2.8.0 and Java 21.
* Please [read this blog post for more info](/blog/2025/20250211-welcome-java-21/).
+* [V4.X.X](/about/info-v4): Based on Pi4J 3.0.3 and Java 25, introducing the [FFM plugin](/documentation/providers/ffm/).
+ * Please [read this interview with Nick Gritsenko (aka DigitalSmile) for more info](/blog/2025/2025????-interview-nick-ffm/).
### Project Mission/Goals
diff --git a/content/about/info-v4.md b/content/about/info-v4.md
new file mode 100644
index 0000000000..d54fa0d610
--- /dev/null
+++ b/content/about/info-v4.md
@@ -0,0 +1,21 @@
+---
+title: 'What''s New in V4'
+weight: 23
+tags: ["FFM API"]
+---
+
+Versions 4.0.0 is based on 3.0.3 (released on 2025-09-23), but bumps the **Java version to 25** and has a new plugin that uses the Foreign Function & Memory (FFM) API. See the [release notes](/about/release-notes/???).
+
+## FFM Plugin
+
+The goal of this bump to V4 is to enable the use of the Foreign Function & Memory (FFM) API in Pi4J. This FFM API has been introduced in OpenJDK 22 and simplifies the use of native libraries in Java. And native libraries are "the heart" of the Pi4J project as they provide the connection between your Java code and the hardware.
+
+Thanks to the contributions by [Nick Gritsenko (aka DigitalSmile)](https://github.com/DigitalSmile) in [pull request #458](https://github.com/Pi4J/pi4j/pull/458), a complete new plugin got added to Pi4J. Read more about the work by Nick in this [interview](/blog/2025/2025????-interview-nick-ffm/).
+
+## Sources
+
+The Pi4J V4 source code is available in this GitHub repository: [`pi4j/pi4j` GitHub Repository](https://github.com/Pi4J/pi4j)
+
+```shell
+git clone https://github.com/Pi4J/pi4j
+```
diff --git a/content/about/release-notes.md b/content/about/release-notes.md
index 26fd875fff..85c39a1134 100644
--- a/content/about/release-notes.md
+++ b/content/about/release-notes.md
@@ -5,6 +5,33 @@ weight: 40
All releases of Pi4J V2+ are listed on [github.com/Pi4J/pi4j/releases](https://github.com/Pi4J/pi4j/releases).
+## V4
+
+Requires Java 25, see [What's New in V4](/about/info-v4/) for more info.
+
+### 2025-0123 - V4.0.0
+
+This is a big one with almost 400 commits and 300+ files added/changed...! **Pi4J V4 introduces the new [FFM plugin](/documentation/provider/ffm) and bumps the Java version to 25**. The FFM plugin makes use of the now Foreign Function & Memory API (FFM) to access the GPIOs. The FFM API got introduced in Java 22 with [JEP 454](https://openjdk.org/jeps/454).
+
+This is also the first release of Pi4J that has been so extensively tested as it contains a complete new plugin (FFM) and a lot of the existing code has been refactored and improved. To simplify the testing process, an inexpensive hardware setup has been created to run automated "Smoke Tests" in combination with a [set of tests in the 'pi4j-test' module in the core project](https://github.com/Pi4J/pi4j/blob/develop/pi4j-test/src/main/java/com/pi4j/test/Main.java). This test is documented [on the page "Hardware Testing"](/architecture/about-the-code/hardware-testing/) and the goal is to have the same test setup for all core developers and is easy to create by anyone who wants to run these tests. Because these tests require hardward and must be run on a Raspberry Pi, they cannot be executed as unit tests.
+
+Some highlights of all the changes:
+
+* [Issue #454](https://github.com/Pi4J/pi4j/issues/454): Implement new FFM API approach. First big pull request: [#458](https://github.com/Pi4J/pi4j/pull/458) with more for further improving, finetuning, and testing.
+* Consistent use of `bcm`, `channel`, `bus`, `chip` when initializing an IO instead of the sometimes confusing `pin`or `address`. With related changes in the Pi4J registry to be able to correctly remove and reuse IO instances.
+* [Issue #478](https://github.com/Pi4J/pi4j/issues/478): Race condition in GpioDDigitalInput causes monitor thread to exit
+* BoardInfo: added CM5 Lite, and 500 Plus
+* Bump Docker builder to JDK 25
+* Nexus staging plugin replaced with Central Publishing plugin
+* Rework of the [pi4j-test](https://github.com/Pi4J/pi4j/tree/develop/pi4j-test) module.
+* Various LinuxFS plugin improvements.
+* Overall code fixes, improvements, new helper methods, cleanup, etc..
+* Complete removal of serial support, use jSerialComm instead of Pi4J for serial communication, as [explained here](https://www.pi4j.com/documentation/io-types/serial/).
+
+Thanks to contributions by [@DigitalSmile](https://github.com/DigitalSmile), [@IAmNickNack](https://github.com/IAmNickNack), [@stefanhaustein](https://github.com/stefanhaustein), [@taartspi](https://github.com/taartspi), [@eitch](https://github.com/eitch), [@fdelporte](https://github.com/fdelporte).
+
+Detailed list of all the changes: https://github.com/Pi4J/pi4j/compare/3.0.3...4.0.0
+
## V3
Requires Java 21, see [What's New in V3](/about/info-v3/) for more info.
diff --git a/content/architecture/about-the-code/build-instructions.md b/content/architecture/about-the-code/build-instructions.md
index f2de75ed08..813fe279b2 100644
--- a/content/architecture/about-the-code/build-instructions.md
+++ b/content/architecture/about-the-code/build-instructions.md
@@ -3,7 +3,7 @@ title: Build Instructions
weight: 30
---
-Building the Pi4J Project is simple and requires minimal effort. Pi4J is primarily built using Apache Maven and Java 21.
+Building the Pi4J Project is simple and requires minimal effort. Pi4J is primarily built using Apache Maven and Java 25.
Pi4J can be built directly on your host computer or inside a Docker container where all toolchains and dependencies are
already installed, configured and cached.
@@ -16,10 +16,10 @@ already installed, configured and cached.
In order to build Pi4J, the host system must have the following toolchains pre-installed.
-| Name | Version | URL |
-| :--- | :--- | :-- |
-| Java Development Kit (JDK) | 11.0.7 (_or newer_) | https://openjdk.java.net/ |
-| Apache Maven | 3.6.3 (_or newer_) | https://maven.apache.org/download.cgi |
+| Name | Version | URL |
+| :--- |:--------------------| :-- |
+| Java Development Kit (JDK) | 25 (_or newer_) | https://openjdk.java.net/ |
+| Apache Maven | 3.9.11 (_or newer_) | https://maven.apache.org/download.cgi |
---
diff --git a/content/architecture/about-the-code/download-sources.md b/content/architecture/about-the-code/download-sources.md
index 8cdfea0c58..b30a14d95f 100644
--- a/content/architecture/about-the-code/download-sources.md
+++ b/content/architecture/about-the-code/download-sources.md
@@ -1,18 +1,18 @@
---
-title: Download/Install
+title: Download the Sources
weight: 20
---
You can build the project from sources available on [GitHub](https://github.com/Pi4J/pi4j).
-* Checkout the project [pi4j](https://github.com/Pi4J/pi4j)
-* Use a JDK version 21 or newer, e.g. `sdk use java 21.0.6-zulu`
-* In the root of pi4j run `mvn clean install`
+* Checkout the `develop` branch of the [pi4j repository](https://github.com/Pi4J/pi4j).
+* Use a JDK version 25 or newer, e.g. `sdk use java 25.0.1-zulu`.
+* In the root of the `pi4j directory, run `mvn clean install`.
```
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
-[INFO] Reactor Summary for Pi4J :: Parent POM 2.0-SNAPSHOT:
+[INFO] Reactor Summary for Pi4J :: Parent POM 4.0.0-SNAPSHOT:
[INFO]
[INFO] Pi4J :: Parent POM ................................. SUCCESS [ 0.972 s]
[INFO] Pi4J :: DOCKER :: Docker Parent POM .............. SUCCESS [ 0.290 s]
@@ -30,27 +30,3 @@ You can build the project from sources available on [GitHub](https://github.com/
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
```
-
-## Example application
-
-### Building the example application
-
-* Checkout the project [Pi4J V2+ - Telegraph Demo Project](https://github.com/Pi4J/pi4j-demo-telegraph)
-* Select JDK 21, e.g. `sdk use java 21.0.6-zulu`
-* In the root of pi4j-demo-telegraph run `mvn clean install`
-* Check the directory target\distribution --> this contains all the files to be copied to the Raspberry Pi
-
-```
-/target/distribution/pi4j-core-2.0-SNAPSHOT.jar
-/target/distribution/pi4j-demo-telegraph-1.0-SNAPSHOT.jar
-/target/distribution/pi4j-library-pigpio-2.0-SNAPSHOT.jar
-/target/distribution/pi4j-plugin-pigpio-2.0-SNAPSHOT.jar
-/target/distribution/pi4j-plugin-raspberrypi-2.0-SNAPSHOT.jar
-/target/distribution/run.sh
-/target/distribution/slf4j-api-2.0.0-alpha0.jar
-/target/distribution/slf4j-simple-2.0.0-alpha0.jar
-```
-
-### Running on the Raspberry Pi
-
-* After copying all files from target/distribution to a Raspberry Pi, start `./run.sh`
\ No newline at end of file
diff --git a/content/architecture/about-the-code/hardware-testing.md b/content/architecture/about-the-code/hardware-testing.md
index 90b2c7787f..7c6aad553c 100644
--- a/content/architecture/about-the-code/hardware-testing.md
+++ b/content/architecture/about-the-code/hardware-testing.md
@@ -1,28 +1,6 @@
---
-title: Hardware testing
+title: Hardware Testing
weight: 50
---
-{{% notice warning %}}This is an experimental project which will need a lot of love... The new Raspberry
-Pi Pico with a lot of GPIOs for a very low price, seems even to be a better fit for this project compared to the
-Arduino Due... To be further investigated!{{% /notice %}}
-
-To minimize the required time and efforts to test a new release, V2+ aims to include an automated test which performs
-I/O testing on each I/O interface on each model of RPi. Ideally this would happen as part of the unit testing sequence
-for each code commit or at least as part of the release cycle.
-
-To achieve this, an Arduino Due board with lots of on board I/O capability is being used. The
-[firmware that gets loaded onto the Arduino board](https://github.com/Pi4J/pi4j/tree/master/pi4j-test-harness/src/main/arduino)
-listens on the serial port for instructions on which pins to use and what type of test to perform. The
-"Test Harness" project also includes a [Java library that is used to communicate with the Arduino and instrument tests](https://github.com/Pi4J/pi4j/tree/master/pi4j-test-harness/src/main/java).
-
-Next, a given [I/O provider plugin](https://github.com/Pi4J/pi4j/tree/master/plugins/pi4j-plugin-pigpio/src/test/java/com/pi4j/plugin/pigpio/test)
-includes test classes that instrument the test harness and perform live I/O testing between the SBC (or other hardware)
-and the Arduino Test Harness.
-
-To be able to fully test all board types, a custom PCB needs to be created to perform all the interconnects between
-the Raspberry Pi 26-pin/40-pin headers, and the Arduino board. This way enough test harnesses could be build for each
-Raspberry Pi model and have a permanent setup for on-demand testing. This of course is a huge effort just by itself,
-and perhaps too ambitious -- but seeking a means to reach automated testing is really needed for the long term.
-
-
\ No newline at end of file
+{{< github-readme "https://github.com/Pi4J/pi4j/blob/develop/pi4j-test/README.md" >}}
diff --git a/content/architecture/future-ideas/_index.md b/content/architecture/future-ideas/_index.md
new file mode 100644
index 0000000000..07768590e7
--- /dev/null
+++ b/content/architecture/future-ideas/_index.md
@@ -0,0 +1,8 @@
+---
+title: Ideas For The Future
+weight: 999
+---
+
+You can find more info on these pages about some of ideas for the future:
+
+{{% children %}}
\ No newline at end of file
diff --git a/content/architecture/advanced/annotated-provisioning.md b/content/architecture/future-ideas/annotated-provisioning.md
similarity index 100%
rename from content/architecture/advanced/annotated-provisioning.md
rename to content/architecture/future-ideas/annotated-provisioning.md
diff --git a/content/architecture/advanced/dependency-injection.md b/content/architecture/future-ideas/dependency-injection.md
similarity index 100%
rename from content/architecture/advanced/dependency-injection.md
rename to content/architecture/future-ideas/dependency-injection.md
diff --git a/content/architecture/advanced/remote-support.md b/content/architecture/future-ideas/remote-support.md
similarity index 77%
rename from content/architecture/advanced/remote-support.md
rename to content/architecture/future-ideas/remote-support.md
index e2c384295e..2d2399c610 100644
--- a/content/architecture/advanced/remote-support.md
+++ b/content/architecture/future-ideas/remote-support.md
@@ -2,11 +2,11 @@
title: 'Remote support'
---
-One of the big features on the wish-list for V2+: native support for remote I/O capability. Predominantly to support
-the ability for a user to perform development work on their desktop/laptop and be able to run their project with
-remote support slaving the I/O to a daemon running on the Raspberry Pi (or other supported SBC).
-
{{% notice warning %}}TO BE DECIDED: the V2+ codebase does support this currently by using the PiGpio daemon.
This may be an OK place to start for the first release, but a separate Pi4J daemon may be ideal for a long term
solution to capture some of the edge cases and provide remote I/O capability no matter which underlying I/O library
-is being used. {{% /notice %}}
\ No newline at end of file
+is being used. {{% /notice %}}
+
+One of the big features on the wish-list for V2+: native support for remote I/O capability. Predominantly to support
+the ability for a user to perform development work on their desktop/laptop and be able to run their project with
+remote support slaving the I/O to a daemon running on the Raspberry Pi (or other supported SBC).
\ No newline at end of file
diff --git a/content/architecture/pi4j-logo.md b/content/architecture/pi4j-logo.md
index 3e7675a87a..ebd4d55b6f 100644
--- a/content/architecture/pi4j-logo.md
+++ b/content/architecture/pi4j-logo.md
@@ -1,6 +1,6 @@
---
title: The Pi4J Logo
-weight: 999
+weight: 998
---
{{% notice tip %}}
diff --git a/content/blog/2026/2026-interview-nick-ffm.md b/content/blog/2026/2026-interview-nick-ffm.md
new file mode 100644
index 0000000000..6ad38ed379
--- /dev/null
+++ b/content/blog/2026/2026-interview-nick-ffm.md
@@ -0,0 +1,106 @@
+---
+title: "Interview Nick Gritsenko"
+date: 2026-01-01
+tags: ["FFM API"]
+---
+
+2026-??-?? by Frank Delporte
+
+## Pi4J Goes Beyond Raspberry Pi with Java 22's FFM API
+
+*Nick Gritsenko (aka [DigitalSmile](https://www.linkedin.com/in/nick-gritsenko/)) joined the Pi4J project recently with an interesting plugin that uses Java 22's Foreign Function & Memory API. His work could open up Pi4J to run on a significantly wider range of hardware than just Raspberry Pi.*
+
+---
+
+### About Nick
+
+
+
+**Frank:** Thanks for joining the Pi4J community! What's your background?
+
+**Nick:** I work at Yandex in the infrastructure department. One of my tasks is to monitor the evolutions in computer infrastructure. The hardware landscape is changing fast, and I think RISC-V will make serious progress in the next 10 years.
+
+**Frank:** What brought you to Pi4J?
+
+**Nick:** I was already working on an [FFM API-based GPIO library for Raspberry Pi](https://github.com/DigitalSmile/gpio), and it seemed like a perfect fit to become a Pi4J plugin. The thing is, with FFM we can make Pi4J work on any hardware that runs Linux... Orange Pi, RISC-V system-on-chips, whatever. The FFM API basically lifts the hardware abstraction above the Linux ecosystem level.
+
+### What is the FFM API
+
+**Frank:** Can you explain what the FFM API is for readers who haven't heard of it?
+
+**Nick:** The Foreign Function & Memory API is part of the [OpenJDK Project Panama](https://openjdk.org/projects/panama/), which actually started way back in 2014. The big difference between FFM and traditional approaches like JNI, JNA, or JNR is huge: **you don't need to know C or C++**. As Java developers, why should we have to become C++ experts just to talk to native code?
+
+The traditional approaches have two main problems. First, writing production-ready C++ code requires deep expertise. You can't learn that from some "C++ in 21 days" book. Second, all those abstraction layers create serious runtime overhead with multiple layers the JVM has to handle.
+
+**Frank:** How is FFM different?
+
+**Nick:** With FFM, you stay in pure Java. Not a single line of C or C++ in your application. You describe C structures using Java, and FFM handles the conversion. Since it's pure Java bytecode, the JIT compiler can optimize it properly, so you can use it safely in, for example, high-load Spring applications.
+
+### How it Works with Pi4J
+
+**Frank:** How does this work in practice?
+
+**Nick:** If you look, for example, at the [sources of the GPIO package structures](https://github.com/Pi4J/pi4j/tree/develop/plugins/pi4j-plugin-ffm/src/main/java/com/pi4j/plugin/ffm/common/gpio/structs) I've created, you'll see that they're Java representations of the C structures that describe how GPIO functionality works in Linux. You're building the same model that represents the C world, but in Java terms.
+
+When you want to change a digital output state, you're calling `ioctl` directly from Java to the kernel. FFM automatically handles converting between Java objects and the native C world.
+
+**Frank:** What about performance?
+
+**Nick:** I've done measurements comparing the FFM implementation with existing Pi4J approaches. The results are impressive, as the removal of all the steps in between, with JNI and JNA, shows a big difference between the "old" implementation and the FFM plugin. Removing the abstraction layers brings big performance improvements.
+
+```text
+Benchmark Mode Cnt Score Error Units
+GPIOPerformanceTest.testFFMInputRoundTrip avgt 5 0.173 ± 0.003 ms/op
+GPIOPerformanceTest.testGpioDInputRoundTrip avgt 5 10.537 ± 6.196 ms/op
+GPIOPerformanceTest.testLinuxFsInputRoundTrip avgt 5 111.781 ± 42.199 ms/op
+
+Benchmark Mode Cnt Score Error Units
+GPIOPerformanceTest.testFFMInputWithListenerRoundTrip avgt 5 1.594 ± 5.830 ms/op
+GPIOPerformanceTest.testGpioDInputWithListenerRoundTrip avgt 5 9.015 ± 12.139 ms/op
+GPIOPerformanceTest.testLinuxFsInputWithListenerRoundTrip avgt 5 110.115 ± 18.796 ms/op
+
+Benchmark Mode Cnt Score Error Units
+GPIOPerformanceTest.testFFMOutputRoundTrip avgt 5 0.042 ± 0.001 ms/op
+GPIOPerformanceTest.testGpioDOutputRoundTrip avgt 5 0.110 ± 0.002 ms/op
+GPIOPerformanceTest.testLinuxFsOutputRoundTrip avgt 5 108.306 ± 12.490 ms/op
+```
+
+### Challenges
+
+**Frank:** Are there any downsides to FFM?
+
+**Nick:** The main issue is crash handling. If something in the native code throws an exception, your entire JVM crashes, not just your application. This isn't unique to FFM, though. The potential solution would be sandboxing, where native crashes wouldn't kill the whole JVM, but I haven't seen concrete plans for that yet.
+
+**Frank:** How do you handle different hardware requirements?
+
+**Nick:** This is important! I'm strictly against putting any Raspberry Pi-specific code directly in the FFM implementation. Everything should go through plugins. Pi4J already has a plugin system for providers, but I think we should extend this to hardware-specific things... plugins for Raspberry Pi, Orange Pi, RISC-V chips, etc.
+
+The beauty of FFM is that it works with any hardware running Linux. We're not abandoning Raspberry Pi, but we can expand to other platforms much easier. So we probably won't need to do any changes to Pi4J itself to have it working on other boards.
+
+### Future Vision
+
+**Frank:** Where do you see this going?
+
+**Nick:** This opens up completely new possibilities. At work, we're already seeing the industry move toward ARM and RISC-V because Java runs much more efficiently on ARM than x86. With FFM, Pi4J can be part of that future across all these platforms.
+
+The goal is making Pi4J truly platform-agnostic while keeping the ease of use Java developers expect. No more dealing with native libraries, compilation issues, or platform-specific builds.
+
+When the previous plugins would be removed from Pi4J, and only the FFM plugin would remain, the Pi4J codebase would become much smaller, easier to maintain. Also, custom Docker builds for the native compilations of the JNI/JNA dependencies for those plugins could be removed, further simplifying the Pi4J code base.
+
+**Frank:** Advice for developers who want to contribute?
+
+**Nick:** The FFM learning curve isn't as steep as you might think. Once you understand the byte mathematics and how to map structures between Java and native worlds, it becomes straightforward, though I won't say it's just "copy and paste"!
+
+I'd say about 70-80% of my time was spent understanding how FFM works. Once that clicked in my brain, development speeded up significantly.
+
+### Getting Involved
+
+**Frank:** How can the community help?
+
+**Nick:** Testing is crucial. I've been working with a Raspberry Pi 5, and basic functionality like digital outputs works well. But we need testing across all providers to identify corner cases that only show up in real-world usage. We also need feedback from developers trying different hardware platforms. The more diverse our testing, the more robust the implementation becomes.
+
+---
+
+*Nick's work integrating Java 22's FFM API represents a big step forward for Pi4J, potentially opening doors to a much broader ecosystem of single-board computers and IoT devices. Try it out and let us know how it works!*
+
+*Want to learn more about Pi4J or contribute? Check out the [GitHub repository](https://github.com/Pi4J/pi4j) or visit the [Pi4J website](https://www.pi4j.com).*
\ No newline at end of file
diff --git a/content/blog/2026/_index.md b/content/blog/2026/_index.md
new file mode 100644
index 0000000000..ce73865c56
--- /dev/null
+++ b/content/blog/2026/_index.md
@@ -0,0 +1,6 @@
+---
+title: "2026"
+date: 2026-01-01
+---
+
+{{% children depth="3" sort="date" order="desc" %}}
\ No newline at end of file
diff --git a/content/documentation/io-types/digital-input.md b/content/documentation/io-types/digital-input.md
index 71ff8bf5d3..5a1e13ae5b 100644
--- a/content/documentation/io-types/digital-input.md
+++ b/content/documentation/io-types/digital-input.md
@@ -6,43 +6,33 @@ aliases:
- /documentation/io-examples/digital-input/
---
-Similar to a digital output pin, a digital input translates an input value of 0V or 3.3V to the value false/true. This
-means any type of device which can toggle between 3.3V and 0V, can generate an input value to the Raspberry Pi. Here the
-most basic example is a toggle button. If you use other components, always check which is the voltage provided by the device.
-Or if you use a power pin from the Raspberry Pi itself, to use a 3.3V pin and not a 5V pin.
+Similar to a digital output pin, a digital input translates an input value of 0V or 3.3V to the value false/true. This means any type of device which can toggle between 3.3V and 0V, can generate an input value to the Raspberry Pi. The most basic example is a toggle button. If you use other components, always check the voltage provided by the device. Or if you use a power pin from the Raspberry Pi itself, use a 3.3V pin and not a 5V pin.
V2+ provides a declarative style of configuration for I/O provisioning instead of the hard-coded approach offered in V1.
-The following example shows the minimal code to configure the `DIGITAL_INPUT_PIN`
-as an input pin and monitor the pin state with by adding a Listener. The code uses methods which are
-provided by the Pi4J library. This implementation will operate with a Pi4j default Provider.
-The default Provider is not a concrete implementation and therefore
-running this program will not access the GPIO Hardware and the Hardware state will not be read/monitored.
-To access the Hardware a concrete Provider is required.
-See [Providers](/documentation/providers/)
-
-Examples of the various methods and approaches which can be used to provision the I/O needs [are available in the examples project](
-https://github.com/Pi4J/pi4j-examples/tree/master/src/main/java/com/pi4j/example/gpio/digital/input).
+The following example shows the minimal code to configure the `BCM_BUTTON`
+as an input pin and monitor the pin state with by adding a Listener. The code uses methods which are
+provided by the Pi4J library. This implementation will operate with a Pi4j [provider](/documentation/providers/) that accesses the GPIO hardware.
```java
-Properties properties = new Properties();
-properties.put("id", "my_digital_input");
-properties.put("address", DIGITAL_INPUT_PIN);
-properties.put("pull", "UP");
-properties.put("name", "MY-DIGITAL-INPUT");
+// Connect a button to PIN 15 = BCM 22
+int BCM_BUTTON = 22;
-var config = DigitalInput.newConfigBuilder(pi4j)
- .load(properties)
- .build();
+var inputConfig = DigitalInput.newConfigBuilder(pi4j)
+ .id("button")
+ .name("Press button")
+ .bcm(BCM_BUTTON)
+ .pull(PullResistance.PULL_DOWN)
+ .debounce(3_000L);
-var input = pi4j.din().create(config);
+var input = pi4j.create(inputConfig);
```
Once an input has been initialized, a listener can be attached to execute code on state changes of the input.
```java
input.addListener(e -> {
- if (e.state() == DigitalState.HIGH) {
+ if (e.state() == DigitalState.LOW){
console.println("Button is pressed");
}
});
diff --git a/content/documentation/io-types/digital-output.md b/content/documentation/io-types/digital-output.md
index db62cf518d..1e04766bed 100644
--- a/content/documentation/io-types/digital-output.md
+++ b/content/documentation/io-types/digital-output.md
@@ -13,56 +13,40 @@ For a LED you will need to put a resistor with the correct value between the GPI
you can find a lot of examples and calculators online, for example on
[circuitdigest.com/calculators/led-resistor-calculator](https://circuitdigest.com/calculators/led-resistor-calculator).
-The following example shows the minimal code to configure the `DIGITAL_OUTPUT_PIN` pin number
+The following example shows the minimal code to configure the `BCM_LED` pin number
as an output pin and change the state with different methods which are provided by the Pi4J library.
- This implementation will operate with a Pi4j default Provider.
-The default Provider is not a concrete implementation and therefore
-running this program will not access the GPIO Hardware and the Hardware state will not be modified.
-To access the Hardware a concrete Provider is required.
-See [Providers](/documentation/providers/)
-
-Examples of the various methods and approaches which can be used to provision the I/O needs [are available in the examples project](
-https://github.com/Pi4J/pi4j-examples/tree/master/src/main/java/com/pi4j/example/gpio/digital/output).
-
+This implementation will operate with a Pi4j [provider](/documentation/providers/) that accesses the GPIO hardware.
```java
+// Connect a LED to PIN 18 = BCM 24
+int BCM_LED = 24;
+
// Initialize Pi4J with an auto context
// An auto context includes AUTO-DETECT BINDINGS enabled
// which will load all detected Pi4J extension libraries
// (Platforms and Providers) in the class path
var pi4j = Pi4J.newAutoContext();
-// create a digital output instance using the default digital output provider
-var output = pi4j.dout().create(DIGITAL_OUTPUT_PIN);
-output.config().shutdownState(DigitalState.HIGH);
-
-// setup a digital output listener to listen for any state changes on the digital output
-output.addListener(System.out::println);
-
-// lets invoke some changes on the digital output
-output.state(DigitalState.HIGH)
- .state(DigitalState.LOW)
- .state(DigitalState.HIGH)
- .state(DigitalState.LOW);
-
-// lets toggle the digital output state a few times
-output.toggle()
- .toggle()
- .toggle();
-
-// another friendly method of setting output state
-output.high()
- .low();
-
-// lets read the digital output state
-System.out.print("CURRENT DIGITAL OUTPUT [" + output + "] STATE IS [");
-System.out.println(output.state() + "]");
-
-// pulse to HIGH state for 3 seconds
-System.out.println("PULSING OUTPUT STATE TO HIGH FOR 3 SECONDS");
-output.pulse(3, TimeUnit.SECONDS, DigitalState.HIGH);
-System.out.println("PULSING OUTPUT STATE COMPLETE");
-
-// shutdown Pi4J
+// Create a digital output config and object
+var ledConfig = DigitalOutput.newConfigBuilder(pi4j)
+ .id("led")
+ .name("LED Flasher")
+ .bcm(BCM_LED)
+ .shutdown(DigitalState.LOW)
+ .initial(DigitalState.LOW);
+
+var led = pi4j.create(ledConfig);
+
+// Lets invoke some changes on the digital output
+for (int i = 0; i < 10; i++) {
+ if (led.equals(DigitalState.HIGH)) {
+ led.low();
+ } else {
+ led.high();
+ }
+ Thread.sleep(500);
+}
+
+// Shutdown Pi4J
pi4j.shutdown();
```
\ No newline at end of file
diff --git a/content/documentation/io-types/pwm.md b/content/documentation/io-types/pwm.md
index 1065291fcf..08bcbaaae9 100644
--- a/content/documentation/io-types/pwm.md
+++ b/content/documentation/io-types/pwm.md
@@ -352,3 +352,7 @@ public class BuzzerComponent extends Component {
}
}
```
+
+## Read More
+
+* [DigiKey: The Role of Pulse Width Modulation in Electronics](https://www.digikey.com/en/articles/the-role-of-pulse-width-modulation-in-electronics)
diff --git a/content/documentation/io-types/serial.md b/content/documentation/io-types/serial.md
index fcb90fdbb9..85464255d8 100644
--- a/content/documentation/io-types/serial.md
+++ b/content/documentation/io-types/serial.md
@@ -6,12 +6,8 @@ aliases:
- /documentation/io-examples/serial/
---
-{{% notice warning %}}
-As of version 3 of the Pi4J library, the serial methods have been marked as deprecated, and we advise to use the [jSerialComm library](https://fazecast.github.io/jSerialComm/), as discussed in [#308: Remove serial support from Pi4J?](https://github.com/Pi4J/pi4j/discussions/308). The example code below is still applicable, but serial support will be fully removed in later versions of Pi4J.
-{{% /notice %}}
-
-**{{% notice tip %}}
-GITHUB PROJECT: [https://github.com/Pi4J/pi4j-example-components/blob/main/src/main/java/com/pi4j/catalog/applications/SerialGps_App.java](https://github.com/Pi4J/pi4j-example-components/blob/main/src/main/java/com/pi4j/catalog/applications/SerialGps_App.java)
+**{{% notice warning %}}
+Serial support got deprecated in V3 of the Pi4J library, and completely removed in V4. We advise using the [jSerialComm library](https://fazecast.github.io/jSerialComm/) for this purpose.
{{% /notice %}}**
## What is it?
@@ -66,11 +62,6 @@ Raspberry Pi GPIO14 and GPIO15 support operation as a mini UART.
The fuller function PL011 uarts are available via GPIO Alternative Function Assignments.
See Pi command `raspi-gpio funcs`.
-## Limitations
-
-At the present time the PiGpio library supports only Parity *None* on any/all uarts. Any future additional UART
-functionality within the PiGpio library will require changes within the Pi4J code base.
-
## Checking Serial Configuration
You can check the Serial configuration of your Raspberry Pi with the following command, using [JBang](/prepare/install-java/#install-sdkman-maven-and-jbang) and a checker tool available in the [GitHub Pi4J OS repository](https://github.com/pi4J/pi4j-os). One or more checks are performed depending on the IO type checked by the tool. You will get a result like this, indicating if the check passed or failed, with more info about the expected and found result:
@@ -95,8 +86,8 @@ Results from Serial Detection
Result:
/dev/ttyS0 not available
/dev/ttyAMA0 exists (readable, writable)
- /dev/ttyUSB0 exists (readable, writable)
- /dev/ttyACM0 not available
+ /dev/ttyUSB0 not available
+ /dev/ttyACM0 exists (readable, writable)
```
If you have used the IOChecker before and want to make sure you are using the latest version, you need to clear the JBang cache:
@@ -107,163 +98,18 @@ $ jbang cache clear
## Code example
-The following example demonstrates how you can connect to a GPS module to read the data. This example is based on an
-example from the book ["The Definitive Guide to Modern Java Clients with JavaFX" by Stephen Chin, Johan Vos and James Weaver](https://www.apress.com/gp/book/9781484249253).
-That example uses V1 of Pi4J with a listener provided by the library. In V2+ this listener is no longer provided but can
-easily be achieved with a Thread to handle the incoming data.
-
-{{% notice tip %}}
-This example has been used by Mark Baird to create an application to record GPS tracks with the ArcGIS Maps SDK for Java. He has [written a full explanation in a very nice post on the Esri ArcGIS blog](https://www.esri.com/arcgis-blog/products/sdk-java/developers/how-to-use-the-arcgis-maps-sdk-for-java-in-a-raspberry-pi-for-recording-gps-tracks/).
-{{% /notice %}}
-
-### Wiring
-
-The GPS module used in this example: NEO-7M.
-
-| NEO-7M | Raspberry Pi |
-| :--- | :--- |
-| VCC | Power 5V (e.g. pin 2) |
-| GND | Ground (e.g. pin 6) |
-| RX | UART TX, GPIO 15 |
-| TX | UART RX, GPIO 16 |
-
-
-
-In the readme of the coding example, you can find the description how you can test the GPS module in the terminal
-with `gpsd.socket`.
-
-### Initialize the serial port
-
-First Pi4J needs to be initialized. Within this context we can then configure and open the serial port. As long as the
-serial port is open, we run a thread to handle the incoming data.
-
-``` java
-var console = new Console();
-var pi4j = Pi4J.newAutoContext();
-
-var serial = pi4j.create(Serial.newConfigBuilder(pi4j)
- .use_9600_N81()
- .dataBits_8()
- .parity(Parity.NONE)
- .stopBits(StopBits._1)
- .flowControl(FlowControl.NONE)
- .id("my-serial")
- .device(SERIAL_ADDRESS)
- .provider("pigpio-serial")
- .build());
-serial.open();
-
-// Wait till the serial port is open
-console.print("Waiting till serial port is open");
-while (!serial.isOpen()) {
- Thread.sleep(250);
-}
+An example is available in the [Pi4J JBang examples repository](https://github.com/Pi4J/pi4j-jbang/tree/main/serial). It consists of two applications:
-// Start a thread to handle the incoming data from the serial port
-SerialReader serialReader = new SerialReader(console, serial);
-Thread serialReaderThread = new Thread(serialReader, "SerialReader");
-serialReaderThread.setDaemon(true);
-serialReaderThread.start();
+* Arduino: sends the measurement of a light sensor as a string message over serial: `{"type":"light","value":82}`.
+* JavaFX: receives the string, parses it, and displays the value on a chart.
-while (serial.isOpen()) {
- Thread.sleep(500);
-}
+Because the JavaFX application doesn't use any Raspberry Pi-specific functionality, you can also run it on any other platform.
-serialReader.stopReading();
-```
-
-### Serial reader
-
-The reader itself implements a Runnable and waits till data is available from the serial port. As the GPS module sends
-its data as readable String lines seperated by a line separator, we only need to handle the bytes which are higher than
-32 (see the [ASCII code table](https://en.wikipedia.org/wiki/ASCII#Printable_characters)). All lower values are handled
-as line separators.
-
-``` java
-public class SerialReader implements Runnable {
-
- private final Console console;
- private final Serial serial;
-
- private boolean continueReading = true;
-
- public SerialReader(Console console, Serial serial) {
- this.console = console;
- this.serial = serial;
- }
-
- public void stopReading() {
- continueReading = false;
- }
-
- @Override
- public void run() {
- // We use a buffered reader to handle the data received from the serial port
- BufferedReader br = new BufferedReader(new InputStreamReader(serial.getInputStream()));
-
- try {
- // Data from the GPS is recieved in lines
- String line = "";
-
- // Read data until the flag is false
- while (continueReading) {
- // First we need to check if there is data available to read.
- // The read() command for pigio-serial is a NON-BLOCKING call,
- // in contrast to typical java input streams.
- var available = serial.available();
- if (available > 0) {
- for (int i = 0; i < available; i++) {
- byte b = (byte) br.read();
- if (b < 32) {
- // All non-string bytes are handled as line breaks
- if (!line.isEmpty()) {
- // Here we should add code to parse the data to a GPS data object
- console.println("Data: '" + line + "'");
- line = "";
- }
- } else {
- line += (char) b;
- }
- }
- } else {
- Thread.sleep(10);
- }
- }
- } catch (Exception e) {
- console.println("Error reading data from serial: " + e.getMessage());
- System.out.println(e.getStackTrace());
- }
- }
-}
-```
-
-### Running the application on Raspberry Pi
-
-You can get the full working example from GitHub and run on a Raspberry Pi after you correctly connected a GPS module.
-As you can see in the output, each data line (starting with `$GP...`) is logged.
-
-``` shell
-[main] INFO com.pi4j.util.Console - ************************************************************
-[main] INFO com.pi4j.util.Console - ************************************************************
-[main] INFO com.pi4j.util.Console -
-[main] INFO com.pi4j.util.Console - <-- The Pi4J Project -->
-[main] INFO com.pi4j.util.Console - Serial Example project
-[main] INFO com.pi4j.util.Console -
-[main] INFO com.pi4j.util.Console - ************************************************************
-[main] INFO com.pi4j.util.Console - ************************************************************
-[main] INFO com.pi4j.util.Console -
-[main] INFO com.pi4j.Pi4J - New auto context
-[main] INFO com.pi4j.Pi4J - New context builder
-[main] INFO com.pi4j.platform.impl.DefaultRuntimePlatforms - adding platform to managed platform map [id=raspberrypi; name=RaspberryPi Platform; priority=5; class=com.pi4j.plugin.raspberrypi.platform.RaspberryPiPlatform]
-...
-[main] INFO com.pi4j.util.Console - Waiting till serial port is open
-[main] INFO com.pi4j.util.Console -
-[main] INFO com.pi4j.util.Console - Serial port is open
-...
-[SerialReader] INFO com.pi4j.util.Console - Data: '$GPVTG,,T,,M,2.349,N,4.351,K,A*2C'
-[SerialReader] INFO com.pi4j.util.Console - Data: '$GPGGA,143723.00,5054.02265,N,00301.10531,E,1,04,10.46,86.2,M,45.9,M,,*5C'
-[SerialReader] INFO com.pi4j.util.Console - Data: '$GPGSA,A,3,09,16,05,07,,,,,,,,,17.19,10.46,13.64*33'
-[SerialReader] INFO com.pi4j.util.Console - Data: '$GPGSV,2,1,06,05,33,304,20,07,67,101,21,09,39,079,29,11,38,228,20*7E'
-[SerialReader] INFO com.pi4j.util.Console - Data: '$GPGSV,2,2,06,16,11,030,24,20,63,283,*73'
-[SerialReader] INFO com.pi4j.util.Console - Data: '$GPGLL,5054.02265,N,00301.10531,E,143723.00,A,A*6A'
-```
+{{< gallery >}}
+{{< figure link="/assets/documentation/serial/dmesg-arduino-connected.png" caption="" caption-position="center" caption-effect="fade" >}}
+{{< figure link="/assets/documentation/serial/arduino-wiring.jpg" caption="" caption-position="center" caption-effect="fade" >}}
+{{< figure link="/assets/documentation/serial/lightsensor-wiring.png" caption="" caption-effect="fade" >}}
+{{< figure link="/assets/documentation/serial/running-app-with-chart.png" caption="" caption-effect="fade" >}}
+{{< figure link="/assets/documentation/serial/serial-test-arduino-ide.png" caption="" caption-effect="fade" >}}
+{{< /gallery >}}
+{{< load-photoswipe >}}
\ No newline at end of file
diff --git a/content/documentation/providers/_index.md b/content/documentation/providers/_index.md
index bf02c61ee4..1144093929 100644
--- a/content/documentation/providers/_index.md
+++ b/content/documentation/providers/_index.md
@@ -18,6 +18,12 @@ expressly requested when creating the Context. [See Create Context](../create-c
Current supported providers:
+* [FFM](/documentation/providers/ffm/)
+ * Was introduced in Pi4J 4.0.0
+ * Pro
+ * ...
+ * Contra
+ * ...
* [GpioD](/documentation/providers/gpiod/)
* Was introduced in Pi4J 2.5.0
* Pro
diff --git a/content/documentation/providers/ffm.md b/content/documentation/providers/ffm.md
new file mode 100644
index 0000000000..4cb3df0baf
--- /dev/null
+++ b/content/documentation/providers/ffm.md
@@ -0,0 +1,112 @@
+---
+title: FFM Provider
+weight: 91
+tags: ["FFM"]
+---
+
+The FFM plugin provider was added in Pi4J 4.0.0 based on the Foreign Function & Memory (FFM) API
+
+Providers in the FFM plugin:
+
+* ffm-digital-input
+* ffm-digital-output
+* ffm-i2c
+* ffm-pwm
+* ffm-spi
+
+## Quick Start
+
+1. Ensure you are running JDK25+
+1. Add dependency to your maven/gradle
+ ```xml
+
+ The content on this page was generated based on the content from {{ $url }}. +
+