Con7968 let's get physical - io programming using pi4 j
1. I/O Programming with Java on the
Raspberry Pi with Pi4J
JavaOne 2013 - CON7968
Robert Savage, Software Architect, AMX LLC.
Let’s Get Physical:
2. Additional Resources
Blog Articles on Project:
http://www.savagehomeautomation.com/j1pi4j
Source Code For Demos
https://github.com/savagehomeautomation/pi4j-javaone-demos
3. Disclaimer!
UAYOR! / YMMV!
(use at your own risk / your mileage may vary)
The projects and sample code provided in this demonstration are intended as examples and may not cover all practical use
cases, local building codes, fire and/or security regulations depending on your implementation and location.
THIS SOFTWARE IS DISTRIBUTED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
DISCLAIMER:
Views expressed are solely the personal views and opinions of the presenter and do not represent the views of Oracle Corp., AMX, LLC or any other company.
4. Agenda / Topics
Raspberry Pi Overview
Pi4J Overview
Basic “Getting Started” Examples
Simple GPIO Example/Demo
GPIO Triggers Example/Demo
RS232 Serial Communication
Example / Demo
Components
Expansion
Putting It All Together
Roadmap
Q&A
5. Raspberry Pi
Single Board Computer
Linux Operating system
ARM Architecture
Low Cost
Low Power
6. Java on the Raspberry Pi
OpenJDK
Installation: http://www.savagehomeautomation.com/raspi-openjdk
Oracle Hotspot JVM for ARM/Linux (preferred)
JDK 7 Installation: http://www.savagehomeautomation.com/raspi-jdk7
JDK 8 Installation: http://www.savagehomeautomation.com/raspi-jdk8
Soft-float ABI
Hard-float ABI
7. What is Pi4J?
Open Source Project
Low Level I/O
Object-oriented API
Event Based
Raspberry Pi Platform (Linux/ARM)
Java / C (JNI + Native)
8. Pi4J : Supported I/O
GPIO General Purpose I/O
UART Serial / RS232
SPI Serial Peripheral Interface
I2C Inter-Integrated Circuit
PWM Pulse-Width-Modulation
9. Pi4J : GPIO Demo
Basic program using a simple
momentary button (input)
and LED (output).
GOAL:
Illuminate LED when the button
is pressed. Deactivate LED when
button is released.
14. Pi4J : GPIO Trigger Demo
Pi4J provides simple
automation triggers for common
GPIO event interactions.
( == less code)
GOAL:
Toggle LED state when the button
is pressed.
22. RS232Demo:SampleCode
// create an instance of the serial communications class
final Serial serial = SerialFactory.createInstance();
// open the default serial port provided on the P1 header
// (this is where our LED reader is connected)
serial.open(Serial.DEFAULT_COM_PORT, 2400); // 2400 BAUD, N, 8, 1
// create and register the serial data listener
serial.addListener(new SerialDataListener() {
@Override
public void dataReceived(SerialDataEvent event) {
// print out the data received to the console
System.out.println(event.getData());
}
});
// send "Hello World" message to sign
serial.writeln("<ID01><PA><CL>Hello World! -- ");
Thread.sleep(500);
serial.writeln("<ID01><RPA>");
Full source available at: https://github.com/savagehomeautomation/pi4j-javaone-demos/tree/master/pi4j-demo-3-rs232
24. Pi4J : Component API
The component APIs provides an abstraction layer from the
hardware I/O layer.
This allows hardware design/circuitry to change with *less* impact
to your implementation code.
For example, a RELAY could be controlled from GPIO, RS232,
SPI, or I2C. You program defines the RELAY impl up front based
on the hardware interface, but the rest of your program logic works
against the RELAY component interface and not the direct
hardware /communication IO interfaces.
25. Pi4J : Component API
Keypad
Light / LED
Dimmable Light
LCD
Power Controller
Relay
Momentary Switch
Toggle Switch
Analog Sensor
Distance Sensor
Motion Sensor
Temperature Sensor
28. ComponentDemo:SampleCode
// create GPIO controller
final GpioController gpio = GpioFactory.getInstance();
// momentary push-button switch; activates when button is pushed
final MomentarySwitch momentarySwitch = new GpioMomentarySwitchComponent(
gpio.provisionDigitalInputPin(RaspiPin.GPIO_06, PinPullResistance.PULL_UP),
PinState.HIGH, // "OFF" PIN STATE
PinState.LOW); // "ON" PIN STATE
// led; illuminates when momentary switch is pushed
final LED led = new GpioLEDComponent(
gpio.provisionDigitalOutputPin(RaspiPin.GPIO_07, PinState.LOW));
// create momentary switch event listener
momentarySwitch.addListener(new SwitchListener() {
@Override
public void onStateChange(SwitchStateChangeEvent event) {
if(event.getNewState() == SwitchState.ON){
led.on(); // turn ON LED
}
else{
led.off(); // turn OFF LED
}
}
});
Full source available at: https://github.com/savagehomeautomation/pi4j-javaone-demos/tree/master/pi4j-demo-4-components
Use at you own risk.Your mileage may vary.All opinions expressed in this session are that of my own and not affiliated with AMX or Oracle.
In this session we will cover a very brief overview of the Raspberry Pi and the Pi4J project.Next we will get "hands on" with writing Java code to perform simple I/O using Pi4J. Then we will cover Pi4J components and expansion capabilities.An finally we will wrap up with a project roadmap and Q&A.
First, how many in the audience have a Raspberry Pi?OK, how many have programmed Java on the Raspberry Pi?The Raspberry Pi is a single board computer running Linux on top of an ARM (ARM11 family, ARMv6 instruction set) chipset. It was targeted as an educational platform to get children and students interested in computer science and engineering and thus targeted as very low cost device.As a child of the 80’s I was introduced to the personal computing on Commodore VIC-20 / 64 / 128 and Tandy TRS-80. So the spirit of the Raspberry Pi project immediately struck a chord with me and I became interested in the project and the philosophy that inspired it. Perfect D.I.Y. Development Platform for embedded computing projects.Prior to the Raspberry Pi, development platforms for the embedded space were typically high cost and not generally available to the the masses.
The Raspberry Pi platform is a perfectly capable platform for running Java. I have included links to articles on my blog here for reference that cover step-by-step installation instructions for installing the JDK on a Raspberry Pi.With the release of the latest JDK7 builds, full hard-float ABI support is provided.
Pi4J is an open source project that I started to provide Java developers simple Java object-oriented interfaces for accessing and controlling the I/O capabilities of the Raspberry Pi platform.The primary motivations for me were that no existing Java library provided event based input and that existing APIs were not very OO-like. I also wanted to make the Raspberry Pi platform a more accessible development platform for Java progammers by abstracting away the low-level details for communication and event handling. Meaning .. do all the ugly JNI/native code integration under the covers so Java programmers don't have to.
The Pi4J project supports all the major I/O capabilities provided by the Raspberry Pi hardware including GPIO, UART (serial/RS232), SPI, I2C, and PWM.
We are going to start with an extremely simple sample project to outline the fundamentals of getting started with Pi4J. Effectively this is the “Hello World” for automation.We are going to use the GPIO capabilities of the Raspberry Pi to (A) sense input from a push-button momentary switch and (B) turn on and off an LED indicator lamp.
Here is the basic wiring diagram for the sample code. As you can see we have the momentary switch connected to GPIO pin 6 and the LED connected to GPIO pin 7. Before we proceed, we need to expand a little on GPIO and digital input/output and basic circuits.A GPIO can be either an input or an output pin. The state of the GPIO pin can be either HI or LOW. HI and LOW do not necessary translate to ON or OFF respectively. This is entirely dependent on the electrical circuit and desired behavior. To put this in another way .. HI and LOW are concrete states of a GPIO pin whereas “ON and “OFF” are abstract states of behavior based on the circuit and programming. On the Raspberry Pi platform “HI” is represented by a +3.3 VDC on the GPIO pin. “LOW” is represented by 0 VDC on the GPIO pin. Take a look at the LED part of the circuit. GPIO pin 7 is configured as an output pin and when we set the pin to the HI state +3.3 VDC will be available to the LED. The HI state opens a path for the electrons to flow (from ground) and thus causing the LED to illuminate. When the state of the GPIO pin is set to LOW, then 0 VDC is present which is the same as the ground connection and thus no movement of electrons and no illumination.Now lets move over to the switch part of the circuit. Here we have a momentary switch connected between ground and GPIO pin 6 and configured as an input pin. When the switch is pressed the circuit is completed between the two switch leads and when it is released the circuit is broken. (Normally-Open Switch). The note under the momentary switch in the diagram indicated that the GPIO pin is PULLED UP. This means that the GPIO pin 6 has been configured to provide a bias in the HI state. If a pull up or pull down is not configured the GPIO pin state can float when results in very unpredictable results. Pull resistance can be configured on the GPIO pin or electrically designed into the circuit using high value resistors. When the switch is pressed in this circuit the 0VDC on the ground lead is connected to GPIO pin 6 resulting in the pin going into the LOW state. So this is an example of the LOW state representing the “ON” condition of the moentary switch.
Ok, with the circuit design out of the way, let look at the desired program logic flow. We will start with provisioning (configuring) the GPIO pins that we want to interact with. Provisioning configures the GPIO pin as an INPUT or OUTPUT pin, pull resistance, default pin states, etc. Next we register a listener so that we can be notified of GPIO state changes for the momentary push button.When a receive a GPIO state change event from the momentary push-button, we will then turn “ON” or “OFF” the LED.When the button is pressed the LED should turn ON.When the button is released the LED should turn OFF.
Ok, so here is the Java pseudo-code for all the logic we just described.The momentary push button is configured as an input pin and the LED is configured as output will pull up resistance.The GPIO event handler on the button controls the LED GPIO pin based on state changes.
Time to put in this in action and see it work. <SWITCH TO IDE AND RUN SAMPLE 1>
Now that we have the basic principals of controlling and monitoring GPIO using Pi4J, we are going to example of some of the additional capabilities that Pi4J offers.Pi4J include GPIO triggers that provide automation based on event changes. This of triggers as “macros” for GPIO events. The advantage of GPIO triggers is just less boilerplate code to perform simple and common tasks based on GPIO events.In this demo we will change up the behavior slightly. Instead of turning the LED on and off with press and release, we will toggle the state on each button press. So when the button is pressed the LED state should toggle ON/OFF.
No changes here, the wiring is exactly the same as in demo 1.
In the logic diagram, notice how the logic of controlling the LED pin state has moved from the user program into the Pi4J framework. Instead of a GPIO event, we instead register a predefined trigger. When the GPIO state for the push button changes, the trigger logic is executed and performs its predetermined function.
Notice here that the code is a bit more compact. Again, we have removed the event listener and LED GPIO pin control code and replaced it with a simple toggle state trigger.
You may be thinking … “This isn’t rocket science.”I know, but this is about a library to make it easier and more enjoyable for Java programmers to work with GPIO on the Raspberry Pi. Eliminating boilerplate code is always good .. Right?(NOTE: Incidentally,Java 8 and Lambda expressions will also help eliminate this type of boiler plate while still implementing your own logic on the event.)Lets’ run this demo and you can see the trigger in action.<SWITCH TO IDE AND RUN SAMPLE 2>
Time to move beyond the GPIO and use the Raspberry Pi’s UART to communicate via RS232/serial to external devices/hardware.In this demo we will use an LED message reader sign and send instructions to the sign via the Raspberry Pi’s UART.
In the wiring diagram, note that the Raspberry Pi’s UART pins (TX/RX) are not directly connected to the periphery device; in this case the LED message reader. Instead we must use an RS232 level shifter to shift the serial pin voltages from the TTL voltage levels on the Raspberry Pi to RS232 compatible voltages.
In the logic diagram, we start by configuring and opening the serial port. Next we register a listener and print and received data out to the console. Finally, we send a “Hello World” message in the LED message reader’s protocol to display on the sign.
Here is what the code looks like to - create a serial instance - configure and open the serial port - register a serial data listener - send a “Hello World” display message
Lets’ run this demo and you can see the code in action.<SWITCH TO IDE AND RUN SAMPLE 3>
Q&A
I truly hoped you enjoyed this session and are able to walk away having learned something new. I would appreciate it if you would fill out your session evaluations.