How’s the lad?
Introduction
For decades, software developers have started their journey in a new programming language by writing a simple "Hello, World!" application. In the world of electronics and physical computing, the equivalent tradition is even more visual: making an LED blink.
While it may seem like a simple exercise, blinking an LED introduces some of the most fundamental concepts in embedded development. It demonstrates how software can interact with the physical world by controlling electronic components through the Raspberry Pi's GPIO (General Purpose Input/Output) pins.
For Java developers, this is where Pi4J shines. Pi4J provides a modern and intuitive API that allows Java applications to communicate directly with Raspberry Pi hardware, making it possible to build IoT, automation, robotics, and monitoring projects without leaving the Java ecosystem.
In this tutorial, we'll build our first Pi4J application and use it to control an LED connected to a Raspberry Pi. Along the way, you'll learn the basics of GPIO programming, understand how digital outputs work, and see how straightforward hardware control can be when using Java.
By the end of this guide, you will be able to:
- Understand the role of GPIO pins on a Raspberry Pi
- Control hardware components from a Java application
- Create and configure a Pi4J project
- Turn a GPIO pin on and off programmatically
- Build your first physical computing project using Java and Pi4J
What You'll Need
Before we start writing code, let's gather the components required for this project.
Hardware
- Raspberry Pi
- LED
- 220Ω or 330Ω resistor
- Breadboard
- Jumper wires
Software
- Java Development Kit (JDK)
- Maven or Gradle
- Pi4J properly configured on your Raspberry Pi
The circuit used in this tutorial is intentionally simple, making it perfect for learning the fundamentals of GPIO programming.
Before writing any code, it's helpful to understand the concept that makes Raspberry Pi hardware control possible: GPIO.
What Is GPIO?
GPIO stands for General Purpose Input/Output.
These programmable pins allow software running on the Raspberry Pi to interact with external hardware components such as:
- LEDs
- Buttons
- Sensors
- Relays
- Motors
Each GPIO pin can be configured for different purposes depending on the application.
Input vs Output
GPIO pins generally operate in one of two modes:
Input
An input pin reads signals coming from external devices.
Examples:
- Detecting a button press
- Reading a sensor value
- Monitoring a switch state
Output
An output pin sends signals to external devices.
Examples:
- Turning on an LED
- Activating a relay
- Driving a buzzer
In this tutorial, GPIO 17 will be configured as an output pin.
HIGH and LOW States
A digital GPIO output has two possible states:
By switching between HIGH and LOW, we can control the LED directly from our Java application.
Creating a Blink Effect
Blinking an LED is simply a matter of repeatedly:
- Setting the GPIO pin HIGH
- Waiting for a short period
- Setting the GPIO pin LOW
- Waiting again
- Repeating the process
When the application calls led.high(), Pi4J communicates with the underlying Raspberry Pi GPIO subsystem and sets the selected pin to 3.3V. Calling led.low() returns the pin to 0V, turning the LED off.
This simple pattern forms the foundation for many more advanced hardware projects.
GPIO Numbering Explained
One of the most common sources of confusion for beginners is the different numbering schemes used when referring to Raspberry Pi pins. Before connecting any hardware, it's important to understand the distinction between a pin's physical location and its GPIO identifier.
Physical Pins vs GPIO Numbers
The Raspberry Pi header contains 40 physical pins arranged in two rows. These pins are numbered sequentially from 1 to 40 based on their physical position on the board.
However, not all of these pins are GPIO pins. Some provide power (3.3V or 5V), while others provide ground (GND).
GPIO pins are identified using BCM (Broadcom) GPIO numbers, which refer to the numbering used internally by the Raspberry Pi's processor.
For example:
In this tutorial, we connect our LED to Physical Pin 11, which corresponds to GPIO 17.
Why This Matters
When reading tutorials or examples online, you may encounter references such as:
create(17)
This does not refer to Physical Pin 17 on the header.
Instead, it refers to GPIO 17 (BCM numbering), which is physically located on Pin 11.
Mixing up these numbering schemes is one of the most common causes of wiring mistakes and can lead to circuits that simply do not work as expected.
A Practical Example
For this project:
- The LED is connected to GPIO 17
- GPIO 17 is located on Physical Pin 11
- The LED's cathode is connected to a GND pin
A common beginner mistake is to connect the LED to Physical Pin 17 because the code references GPIO 17. Physical Pin 17 is actually a 3.3V power pin, not GPIO 17.
BCM Numbering in Pi4J
Pi4J uses the Raspberry Pi's GPIO identifiers rather than the physical header positions. When creating a digital output like this:
var led = pi4j.dout().create(17);
Pi4J configures GPIO 17, not Physical Pin 17.
For this reason, it is highly recommended to keep a Raspberry Pi GPIO pinout diagram nearby while building projects. Once you become familiar with the relationship between physical pins and BCM GPIO numbers, wiring circuits becomes much easier and less error-prone.
Understanding the Circuit
Although our circuit contains only a few components, understanding their purpose is important before we begin programming.
GPIO Connection
In this example, we'll use GPIO 17 as a digital output.
The wiring is straightforward:
- Connect GPIO 17 to the resistor.
- Connect the resistor to the LED anode (+).
- Connect the LED cathode (-) to a GND pin.
When GPIO 17 is set HIGH, the LED will turn on. When it is set LOW, the LED will turn off.
GPIO Safety Tip
Raspberry Pi GPIO pins operate at 3.3V and are not 5V tolerant. Applying more than 3.3V to a GPIO pin can permanently damage the board. Always double-check your wiring before powering the circuit.
Creating the Java Project
With the hardware connected, we're ready to create our first Pi4J application.
Project Structure
This example uses Maven, although Pi4J works equally well with Gradle.
A minimal project structure looks like this:
blink-led/
├── pom.xml
└── src/
└── main/
└── java/
└── com/example/
└── BlinkLed.java
Adding Pi4J Dependencies
Add the required Pi4J dependencies to your pom.xml:
<dependencies>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-core</artifactId>
<version>YOUR_PI4J_VERSION</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-plugin-raspberrypi</artifactId>
<version>YOUR_PI4J_VERSION</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-plugin-pigpio</artifactId>
<version>YOUR_PI4J_VERSION</version>
</dependency>
</dependencies>
Writing the Application
Create a new class named BlinkLed.java and add the following code:
public class BlinkLed {
public static void main(String[] args) throws Exception {
var pi4j = Pi4J.newAutoContext();
var led = pi4j.dout().create(17);
while (true) {
led.high();
Thread.sleep(500);
led.low();
Thread.sleep(500);
}
}
}
Understanding the Code
Creating the Pi4J Context
var pi4j = Pi4J.newAutoContext();
The context initializes Pi4J and loads the required providers for interacting with Raspberry Pi hardware.
Configuring the GPIO Pin
var led = pi4j.dout().create(17);
This creates a digital output attached to GPIO 17.
Turning the LED On
led.high();
Setting the pin HIGH outputs 3.3V and illuminates the LED.
Turning the LED Off
led.low();
Setting the pin LOW removes the voltage and turns the LED off.
Creating a Delay
Thread.sleep(500);
The application pauses for 500 milliseconds.
Repeating the Process
while (true)
The loop continuously alternates between HIGH and LOW states, creating the blinking effect.
Clean Shutdown (Pi4J Best Practice)
Properly shutting down the Pi4J context releases GPIO resources and ensures the application exits cleanly.
Runtime.getRuntime().addShutdownHook(
new Thread(() -> pi4j.shutdown())
);
Running the Application
Compile the project using Maven:
mvn clean package
Then execute the generated JAR:
java -jar target/blink-led.jar
If everything is connected correctly, the LED should begin blinking at half-second intervals.
Troubleshooting
The LED Does Not Turn On
Check the following:
- LED polarity is correct
- GPIO 17 is being used
- All jumper wires are firmly connected
- The resistor is properly placed in the circuit
Permission Errors
If Pi4J cannot access the GPIO hardware:
- Verify your Pi4J installation
- Ensure the required providers are installed
- Confirm the application is running with appropriate permissions
Dependency Issues
If Maven cannot resolve dependencies:
mvn dependency:tree
Verify that all Pi4J artifacts are available and successfully downloaded.
Stay tuned for upcoming Raspberry Pi and Pi4J projects.
You can find the project on GitHub: Pi4J LED Playground
Links
Remember to use the hashtag #JavaOnRaspberryPi on Twitter to show the world Raspberry Pi with Java.






Top comments (0)