-
Notifications
You must be signed in to change notification settings - Fork 2
4. seven steps to an Raspberry Pi application
You can learn here:
- how to install an elbfisch runtime environment on a raspberry pi
- how the gpio of the raspberry can be accessed using elbfisch vioss (versatile input/output subsystem)
- how elbfisch modules can synchronize on process events.
HINT: A brief description of more elbfisch features you can find here
HINT: A brief lecture you can find here
1) Prepare your Raspberry Pi:
- install Raspbian (Debian Buster) (get it here)
- for installation of a Oracle Java 1.8 follow these instructions:
1) install software-properties-common
sudo apt-get install software-properties-common
When prompted to confirm the installation type, tyeyfor yes.
2) To ensure we get the correct source line on Debian execute
sudo add-apt-repository "deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main"
3) Then we have to do a system update
sudo apt-get update
4) Now we can install the Oracle JDK
sudo apt-get install oracle-java8-installer
Again, you’ll be prompted to typeyto confirm the install. You’ll also be required to accept the Oracle Binary Code license terms. Use the arrow key to select “Yes”, then press “Enter” to accept the license.
2) change directory to /usr/local and create a new directory named application
root@raspberrypi:/#cd /usr/localroot@raspberrypi:/#mkdir application3) Download the Raspberry Elbfisch example application from Github and compile it as shown here .
4) copy all except the src directory to the application folder on your raspberry pi.

5) change directory to /usr/local/application
root@raspberrypi:/usr/local#cd ./application6) shortcircuit pin’s 4 and 5 of your Raspberry Pi.

7) start the the shell script
root@raspberrypi:/usr/local/application# ./launch.shand look what you get on your console :
16:51:03,898 [INFO:JPac] STARTING
16:51:03,921 [INFO:JPac] awaiting start up signal ...
16:51:04,899 [INFO:main] startCycling requested
16:51:04,908 [INFO:main] startCycling() acknowledged
16:51:04,930 [INFO:JPac] starting up org.jpac.vioss.raspi.gpio.IOHandler(raspigpio:)
16:51:04,984 [INFO:JPac] running in LazyBound mode ...
16:51:05,019 [INFO:MainModule.ReadbackPinModule] started ...
16:51:05,042 [INFO:MainModule.TogglePinModule] started ...
16:51:05,092 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = false)
16:51:06,095 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = true)
16:51:07,100 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = false)
16:51:08,103 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = true)
16:51:09,108 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = false)
16:51:10,113 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = true)
16:51:11,118 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = false)
16:51:12,122 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = true)
16:51:13,127 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = false)
16:51:14,031 [INFO:MainModule.TogglePinModule] delaying toggle ...
16:51:14,133 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = true)
16:51:16,143 [INFO:MainModule.ReadbackPinModule] !!!!!!!!!!!!!! toggle time exceeded !!!!!!!!!!!!!!!!!!!!!
16:51:16,146 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = true)
16:51:17,146 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = false)
16:51:18,149 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = true)
16:51:19,152 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = false)
16:51:20,157 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = true)
16:51:21,161 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = false)
16:51:22,165 [INFO:MainModule.ReadbackPinModule] pin #5: LogicalInput(MainModule.ReadbackPinModule.RaspiInputPin05 = true)
If you get something like shown above: Congratulation, your raspberry application works.
You can stop it by pressing CTRL-C:
^C16:51:22,949 [INFO:ShutdownHook] shutdown requested. Informing jPac ...
16:51:22,967 [INFO:JPac] storing histogramm informationen to ./data/histogramm.csv
16:51:22,989 [INFO:JPac] shutting down modules ...
16:51:22,996 [ERROR:MainModule.ReadbackPinModule] shutting down ...
16:51:23,002 [INFO:JPac] ... shutting down modules done
16:51:23,005 [INFO:JPac] shutting down ...org.jpac.vioss.raspi.gpio.IOHandler(raspigpio:)
16:51:23,010 [INFO:JPac] cycle mode : LazyBound
16:51:23,014 [INFO:JPac] cycle time : 100000000 ns
16:51:23,017 [INFO:JPac] min remaining cycle time : 89637242 ns (89%)
16:51:23,019 [INFO:JPac] max remaining cycle time : 99249017 ns (99%)
16:51:23,022 [INFO:JPac] SHUTDOWN COMPLETE
16:51:23,110 [INFO:ShutdownHook] shutdown complete
Let’s take a closer look at our s(a)imple elbfisch application.
It consists of 4 Java classes:

- Sample is the formal main program which is used to instantiate the elbfisch modules
- MainModule is the main module of this elbfisch application. It instantiates the following modules.
- TogglePinModule simply toggles gpio pin#4 of our raspberry pi once a second
- ReadbackPinModule simply waits for gpio pin#5 to toggle and generates an apropriate log message
All elbfisch modules run on separate threads.
Let’s begin with the elbfisch module TogglePinModule.
/**
* PROJECT : Elbfisch - java process automation controller (jPac)
* MODULE : TogglePinModule.java
* VERSION : -
* DATE : -
* PURPOSE :
* AUTHOR : Bernd Schuster, MSK Gesellschaft fuer Automatisierung mbH, Schenefeld
* REMARKS : -
* CHANGES : CH#n <Kuerzel> <datum> <Beschreibung>
*
* This file is part of the jPac process automation controller.
* jPac is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jPac is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the jPac If not, see <http://www.gnu.org/licenses/>.
*/
package raspberry;
import java.net.URI;
import java.net.URISyntaxException;
import org.jpac.AbstractModule;
import org.jpac.InconsistencyException;
import org.jpac.InputInterlockException;
import org.jpac.Module;
import org.jpac.OutputInterlockException;
import org.jpac.PeriodOfTime;
import org.jpac.ProcessException;
import org.jpac.SignalAlreadyExistsException;
import org.jpac.WrongUseException;
import org.jpac.vioss.raspi.gpio.LogicalOutput;
/**
*
* @author berndschuster
*/
public class TogglePinModule extends Module{
private LogicalOutput pin4;
public TogglePinModule(AbstractModule containingModule, String identifier) throws SignalAlreadyExistsException, InconsistencyException, WrongUseException, URISyntaxException{
super(containingModule, identifier);
pin4 = new LogicalOutput(this, "RaspiOutputPin04", new URI("raspigpio:/4"));
}
@Override
protected void work() throws ProcessException {
PeriodOfTime toggleTime = new PeriodOfTime(1 * sec);//instantiate a period of time event (1 s)
PeriodOfTime extendedToggleTime = new PeriodOfTime(3 * sec);//instantiate a period of time event (1 s)
int cycleCounter = 0;
Log.info("started ...");
pin4.set(false);
do{
if (++cycleCounter % 10 != 0){
toggleTime.await();//wait for 1 second
}
else{
Log.info("delaying toggle ...");
extendedToggleTime.await();
}
pin4.set(!pin4.is(true));
//Log.info("toggled " + pin4);
}
while(true);
}
@Override
protected void preCheckInterlocks() throws InputInterlockException {
}
@Override
protected void postCheckInterlocks() throws OutputInterlockException {
}
@Override
protected void inEveryCycleDo() throws ProcessException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
In it’s constructor it instantiates an LogicalOutput instance named pin4:
It is addressed by the uri “raspigpio:/4” which is used by elbfisch vioss (versatile input/output subsystem) to locate it.
pin4 = new LogicalOutput(this, "RaspiOutputPin04", new URI("raspigpio:/4"));The main activity is done inside the work() method. It first instantiates the process event PeriodOfTime which can be used by an elbfisch module to delay a certain activity for given amount of time (here 1 second). Then it runs into a loop in which it simply toggles the pin every second.
pin4.set(!pin4.is(true));(Every ten’th second the toggle is delayed for another 2 seconds (extendedToggleTime).)
The elbfisch module ReadBackPinModule simply waits for gpio pin#5 to toggle and log’s this event.
/**
* PROJECT : Elbfisch - java process automation controller (jPac)
* MODULE : ReadBackPinModule.java
* VERSION : -
* DATE : -
* PURPOSE :
* AUTHOR : Bernd Schuster, MSK Gesellschaft fuer Automatisierung mbH, Schenefeld
* REMARKS : -
* CHANGES : CH#n <Kuerzel> <datum> <Beschreibung>
*
* This file is part of the jPac process automation controller.
* jPac is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jPac is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the jPac If not, see <http://www.gnu.org/licenses/>.
*/
package raspberry;
import java.net.URI;
import java.net.URISyntaxException;
import org.jpac.AbstractModule;
import org.jpac.EventTimedoutException;
import org.jpac.InconsistencyException;
import org.jpac.InputInterlockException;
import org.jpac.Module;
import org.jpac.NextCycle;
import org.jpac.OutputInterlockException;
import org.jpac.PeriodOfTime;
import org.jpac.ProcessException;
import org.jpac.ShutdownRequestException;
import org.jpac.SignalAlreadyExistsException;
import org.jpac.WrongUseException;
import org.jpac.vioss.raspi.gpio.LogicalInput;
import org.jpac.vioss.raspi.gpio.LogicalOutput;
/**
*
* @author berndschuster
*/
public class ReadBackPinModule extends Module{
private LogicalInput pin5;
public ReadBackPinModule(AbstractModule containingModule, String identifier) throws WrongUseException, URISyntaxException, SignalAlreadyExistsException, InconsistencyException{
super(containingModule, identifier);
pin5 = new LogicalInput(this, "RaspiInputPin05", new URI("raspigpio:/5"));
}
@Override
protected void work() throws ProcessException {
Log.info("started ...");
try{
pin5.becomesValid().await();//wait, until the signal pin5 becomes valid
do{
try{
Log.info("pin #5: " + pin5);
pin5.toggles().await(2 * sec);//wait, until pin5 changes it's state
}
catch(EventTimedoutException exc){
Log.info("!!!!!!!!!!!!!! toggle time exceeded !!!!!!!!!!!!!!!!!!!!!");
}
}
while(true);
}
catch(ShutdownRequestException exc){
Log.error("shutting down ... ");
}
}
@Override
protected void preCheckInterlocks() throws InputInterlockException {
}
@Override
protected void postCheckInterlocks() throws OutputInterlockException {
}
@Override
protected void inEveryCycleDo() throws ProcessException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
In it’s constructor it instantiates the LogicalInput instance named pin5:
It is addressed by the uri “raspigpio:/5”.
pin5 = new LogicalInput(this, "RaspiInputPin05", new URI("raspigpio:/5"));The main activity is again done inside the work() method. It first wait’s, until the vioss has
read in the pin the first time
pin5.becomesValid().await();and afterwards, in a loop, it wait’s for pin#5 to toggle
pin5.toggles().await(2 * sec);If the toggle does not occur within 2 second’s a EventTimedoutException is thrown.
As pin#4 and pin#5 are shortcircuited, every time the TogglePinModule changes the state of pin#4 the ReadBackPinModule is invoked by the above mentioned toggles event.
Try out, what happens, if you break the shortcircuit
The MainModule in this application is trivial. It instantiates the two modules mentioned above and, in its work() method, it simply waits for an event, which can not ocurr (ImpossibleEvent())
Have a brief look at it:
/**
* PROJECT : Elbfisch - java process automation controller (jPac)
* MODULE : MainModule.java
* VERSION : -
* DATE : -
* PURPOSE :
* AUTHOR : Bernd Schuster, MSK Gesellschaft fuer Automatisierung mbH, Schenefeld
* REMARKS : -
* CHANGES : CH#n <Kuerzel> <datum> <Beschreibung>
*
* This file is part of the jPac process automation controller.
* jPac is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jPac is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the jPac If not, see <http://www.gnu.org/licenses/>.
*/
package raspberry;
import java.net.URI;
import java.net.URISyntaxException;
import org.jpac.ImpossibleEvent;
import org.jpac.InconsistencyException;
import org.jpac.InputInterlockException;
import org.jpac.Module;
import org.jpac.OutputInterlockException;
import org.jpac.ProcessException;
import org.jpac.SignalAlreadyExistsException;
import org.jpac.WrongUseException;
import org.jpac.vioss.modbus.LogicalInput;
import org.jpac.vioss.modbus.LogicalOutput;
/**
*
* @author berndschuster
*/
public class MainModule extends Module{
public MainModule() throws SignalAlreadyExistsException, InconsistencyException, WrongUseException, URISyntaxException{
super(null,"MainModule");
}
@Override
protected void work() throws ProcessException {
new ImpossibleEvent().await();
}
@Override
public void start(){
try{
//invoke my containing modules
new TogglePinModule(this,"TogglePinModule").start();
new ReadBackPinModule(this,"ReadbackPinModule").start();
//then start myself
super.start();
}
catch(Exception exc){
Log.error("Error: ", exc);
}
}
@Override
protected void preCheckInterlocks() throws InputInterlockException {
}
@Override
protected void postCheckInterlocks() throws OutputInterlockException {
}
@Override
protected void inEveryCycleDo() throws ProcessException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
The Sample class serves as the main program by simply instantiating the MainModule and starting it:
/**
* PROJECT : Elbfisch - java process automation controller (jPac)
* MODULE : Sample.java
* VERSION : -
* DATE : -
* PURPOSE :
* AUTHOR : Bernd Schuster, MSK Gesellschaft fuer Automatisierung mbH, Schenefeld
* REMARKS : -
* CHANGES : CH#n <Kuerzel> <datum> <Beschreibung>
*
* This file is part of the jPac process automation controller.
* jPac is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jPac is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the jPac If not, see <http://www.gnu.org/licenses/>.
*/
package raspberry;
import org.jpac.Module;
/**
*
* @author berndschuster
*/
public class Sample {
/**
* @param args the command line arguments
*/
public static void main(String[] args){
boolean handles = false;
try{
Module mod = new MainModule();
mod.start();
Thread.sleep(2000);
while(mod.isAlive()){Thread.sleep(100);};
}
catch(Exception exc){
exc.printStackTrace();
}
}
}