[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [ecf-dev] pi4j and OSGi (remote) services

Hi Wim,

I've done quite a lot of work with the gpio pin service (e.g. testing), and I wanted to make you and everyone aware of it.

1) the latest IGPIOPin API is available in the bundle:  bundles/org.eclipse.ecf.raspberrypi.gpio in repo [1].   This bundle will be needed on both the host and any consumer frameworks since it declares the IGPIOPin service interface.

2a) The host implementation (using pi4j) is in bundle:  bundles/org.eclipse.ecf.raspberrypi.gpio.pi4j.  You will probably want to look in the Activator class, since I added system properties to allow the programmer to
a) control which of the 20 pins to create services for (PINS);
b) which of the gpio pin services to export (PINS_EXPORT).  I'll document this soon in a tutorial, but I haven't had a chance to write a tutorial yet.

2b) The pi4j library comes in bundle form (i.e. with an OSGi manifest, etc), and naturally this has to be available in the target platform to that the o.e.e.raspberrypi.gpio.pi4j code can use it.   Note that the pi4j library itself depends upon the WiringPi native code library...see [3] for pi4j dependency docs and WiringPi download/install instructions.  Before you can use pi4j for anything described here you have to install a recent version of WiringPi.

3) I created a simple local test application in bundle:  test/bundles/org.eclipse.ecf.raspberrypi.test.gpio in [1].   All this test application does is when the bundle is started it creates a ServiceTracker to discover registered IGPIOPin services, and when a service gets added it sets the pin state to HIGH (true).   I've been using an LED with the setup described here [2], to test that the IGPIOPin service is working on pin 0.  Short story:  On my raspberry pi it is working great!   I'm using a model B2, and so I had to look at the B2 pi docs to figure out which gpio pin was pin0...and of course figure out which pin  was ground as well on the B2, but once I got that figured out it was working.

4) I created a test feature in test/features/org.eclipse.ecf.raspberrypi.test.gpio.feature project and also a product configuration.  When exported the product configuration creates a zip named raspberrypigpiotest.zip, and I built a version of this test application and placed in the feature project build directory.   I can run this on my raspberry pi (wired up to an LED on pin 0 as described above), by unzipping the raspberrypigpiotest.zip on the pi, cd into the  raspberrypigpiotest/ directory, switch user to *root* (necessary because pi4j requires root access to get to the pins), change the file mode of the gpiotesthost.sh startup script to 700 (executable), and then start the gpiotesthost.sh...e.g.:

root@raspberrypi:/home/pi/raspberrypitestgpio# ./gpiotesthost.sh
javaprops=-Declipse.ignoreApp=true -Dosgi.noShutdown=true
Debug options:
    file:/home/pi/raspberrypitestgpio/.options not found
Time to load bundles: 206
osgi> ss
"Framework is launched."

id      State       Bundle
0       ACTIVE      org.eclipse.osgi_3.10.0.v20140407-2102
1       ACTIVE      org.eclipse.ecf.raspberrypi.gpio_1.0.0.201407282024
2       ACTIVE      org.eclipse.ecf.raspberrypi.gpio.pi4j_1.0.0.201407282024
3       RESOLVED    org.eclipse.ecf.raspberrypi.test.gpio_1.0.0.201407282024
4       ACTIVE      org.eclipse.osgi.services_3.4.0.v20140312-2051
5       ACTIVE      org.eclipse.osgi.util_3.3.0.v20131023-1243
6       ACTIVE      pi4j-core_1.0.0.SNAPSHOT
7       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639
8       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215
9       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036
10      ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

1) all bundles are started except bundle 3 (the test consumer of IGPIOPin services);
2) *For the moment* there are no OSGi/ECF remote services bundles present and so remote service is not being used yet.

If bundle 3 is started from the osgi console, then the IGPIOPin service (for pin 0) is discovered by the service tracker, and the pin 0 state is set to high/true (this code is in the org.eclipse.ecf.raspberrypi.test.gpio bundle).   On my pi, with the LED hooked up to it, the LED lights up!

osgi> start 3
Adding GPIO Pin service.   id=0
  current pin state is LOW
  setting state to HIGH

and if bundle 3 is stopped, the light turns off

osgi> stop 3
Removing GPIO Pin service. id=0
  setting state to LOW

This testing has been working great, and so now I'm ready to do some other things over the next few days:

1) Add the ECF remote services/RSA impl to the test code, and export the IGPIOPin 0 as a remote service.
2) Install the test bundle into Eclipse as an example remote service consumer, and try manipulating pin 0 as a remote service... perhaps with some Eclipse UI (e.g. button) to do so.

Anyway, that's what's next on my list of things to do.

Feel free to ask any questions.  Like I said, as soon as I can I'll document this all in the form of another tutorial.


[1] https://github.com/ECF/RaspberryPI
[2] https://projects.drogon.net/raspberry-pi/gpio-examples/tux-crossing/gpio-examples-1-a-single-led/
[3] http://pi4j.com/dependency.html

On 7/28/2014 2:21 PM, Wim Jongman wrote:
I have added pi4j and ECF remote services to my polos server [1]. I intend to use this server during my talk if it gets accepted. If you follow the instructions in the readme then you can run it on the raspberry. I have it running on one of mine. You need to install java8 on your raspberry [2].

Tomorrow I will add Scott's work to this server and try to operate the pins.

On Mon, Jul 14, 2014 at 8:25 PM, Scott Lewis <slewis@xxxxxxxxxxxxx> wrote:
For everyone's additional info:

I've created, committed, pushed 3 projects now to the RaspberryPI repo:

1) A 'GPIO pin service type'  (IGPIOPin) API project, with just two interfaces:  IGPIOPin and IGPIOPinAsync.  In the future, this may very well have a GPIO controller service type added, but for now it's keep it simple.  This is in project bundles/org.eclipse.ecf.raspberrypi.gpio.
2) A pi4j-based implementation of this GPIO Pin service, in project bundles/org.eclipse.ecf.raspberrypi.gpio.pi4j.  When started, this bundle creates 20 IGPIOPin instances using pi4j PinImpl underneath, and registers these 20 instances with the OSGi service registry.
3) A very very simple test bundle, in project test/bundles/org.eclipse.ecf.raspberrypi.test.gpio.  All this bundle does (for now) is create a ServiceTracker and report to System.out any IGPIOPin instances registered, but I'll probably hook up a light or something to one of the GPIO pins and try out the pin.toggle() to make sure pi4j works as expected.

After I do some basic testing on an actual raspberry pi I intend to use remote services to export the IGPIOPin services and run some basic test code...probably using Eclipse as a remote service consumer.

Any comments appreciated.


On 7/10/2014 2:25 PM, Scott Lewis wrote:
For everyone's info:

I just created a new 'RaspberryPi' repo at ECF's github organization [1].  Just a couple of empty interfaces for the moment (IGPIOController IGPIOPin), but we can use this project to express and share service API designs as things evolve, and we can also add new bundle projects for (e.g.) the host impl, GPIO service consumers, apps, test code, etc.


[1] https://github.com/ECF/RaspberryPI

On 7/10/2014 10:52 AM, Wim Jongman wrote:
Sounds good to me. I will try this implementation.

However, I will be off the grid for the next three weeks.

On Thu, Jul 10, 2014 at 7:17 PM, Scott Lewis <slewis@xxxxxxxxxxxxx> wrote:
Hi Folks,

I've been thinking about this and wanted to communicate some thoughts about Raspberry Pi GPIO.

I'm now thinking that perhaps what we should have is at least two service types:

1) a 'IGPIOController' service, which would likely be a singleton service that exposed the basic semantics of provisioning/configuring GPIO pins, managing shutdown, etc...i.e. most of the non-Pin-specific things exposed by pi4j GpioController interface [1].   This service could be remoted, or perhaps it's not remoted.  I can imagine it either way, but to simplify things initially perhaps it's not remoted.

2) A set of 'IGPIOPin' services, each one representing a physical pin on a single raspberry pi GPIO device [2].   Each instance of this service would represent a single GPIOPin.   Then when the GPIOController 'provisions/configures' the GPIO device, instances of GPIOPin would be exported for remote access, and could then be discovered by consumers/clients (e.g. and injected by DS).   Service properties can/could be defined for the IGPIOPin service instances so that consumers could filter to get only the pins that are needed for a particular application.  I think the IGPIOPin service type (or possibly types/sub-types if necessary) could be kept quite simple and of course be made remote-friendly (parameters/return types).  Also, with java8 and ECF's asynchronous remote service [3] each of the IGPIOPin instances can/could be easily accessed asynchronously and/or synchronously as needed by the application, while keeping IGPIOPin as simple as possible.

The reason I think this might be a nice approach is that in looking at several of the pi4j examples, the interaction with the GPIO controller is sort of boilerplate, and most of the actual application use is with the pin.   By having IGPIOPin service instances, it may be simpler for most applications to use GPIO Pins without that extra boiler plate.

If others have pi4j examples, experience, or use cases it would be nice to hear about them.




[1] http://pi4j.com/apidocs/index.html
[2] http://pi4j.com/example/control.html
[3] https://wiki.eclipse.org/ECF/Asynchronous_Remote_Services

On 7/4/2014 1:14 PM, Scott Lewis wrote:
On 7/4/2014 12:17 PM, Wim Jongman wrote:

       // create gpio controller
        final GpioController gpio = GpioFactory.getInstance();
With OSGi services, this singleton impl is pretty much an anti-pattern, and is easily replaced with a ServiceFactory that would registered something like this:

There is really only one GPIO so I guess the singleton is a requirement. I guess there is some synchronization going and that all services must share the same controller.

My gut feeling says to make a GPIOControllerService that performs operations directly on the Pin instead of passing Pin instances around. At first glance the Pin instances seem overkill and will complicate the service structure.

Perhaps you are right, but my concern about putting everything on a GPIOControllerService could result in a complex API...for example it might require quite a few methods for simply controlling a single pin (e.g. in the pi4j example [1]).

One thought I've had:   What if there was a local only (not exported/remoted) GPIOControllerService, and as part of this service multiple pin-specific services were automatically create/provisioned, registered and then exported as remote services, with service properties/meta-data that identified the pin (pin #5) and associated a name with the physical pin (e.g. 'lightbulb').   Then clients could specify desired/required values for these pin identifiers in the (remote) service OSGi filter...e.g.


via DS or others.

Then the pin-specific service interface could be something very simple, like:

public IGPIOPin {

public Boolean toggle();
public Boolean getToggleState();


Or something similar.  

I don't know for sure whether this would work (haven't thought it through) but it might be a nice approach for OSGi services, and remote services.


[1] http://pi4j.com/example/control.html#

ecf-dev mailing list
To change your delivery options, retrieve your password, or unsubscribe from this list, visit

ecf-dev mailing list
To change your delivery options, retrieve your password, or unsubscribe from this list, visit

ecf-dev mailing list
To change your delivery options, retrieve your password, or unsubscribe from this list, visit

ecf-dev mailing list
To change your delivery options, retrieve your password, or unsubscribe from this list, visit

ecf-dev mailing list
To change your delivery options, retrieve your password, or unsubscribe from this list, visit

ecf-dev mailing list
To change your delivery options, retrieve your password, or unsubscribe from this list, visit