kramann.info
© Guido Kramann

Login: Passwort:










kramann.info
© Guido Kramann

Login: Passwort:




GPIO in Java Processing verfügbar machen über eine Library

(EN google-translate)

(PL google-translate)

Das Kapitel zu GPIO weiter brigend, soll nun eine Library für Processing geschrieben werden, die es ermöglicht mittels Java-Methoden die digitalen Ein- und Ausgänge des Jetson Nano zu steuern.

Als Beispiel wird gezeigt, wie Pin 13 als digitaler Eingang gesteuert werden kann. Weiterhin gilt: PIN13 == GPIO_14 und PIN14 == GND.

Anschluss einer LED  mit 2200Ohm Vorwiderstand an PIN13 == GPIO_14 und PIN14 == GND.

Bild 0-1: Anschluss einer LED mit 2200Ohm Vorwiderstand an PIN13 == GPIO_14 und PIN14 == GND.

Anschluss einer LED mit 2200Ohm Vorwiderstand an PIN13 == GPIO_14 und PIN14 == GND.

Bild 0-2: Anschluss einer LED mit 2200Ohm Vorwiderstand an PIN13 == GPIO_14 und PIN14 == GND.

Anschlußplan zu den GPIO: https://www.jetsonhacks.com/nvidia-jetson-nano-j41-header-pinout/

Vorab wurde bereits über Terminal-Befehle Pin 13 aktiviert und deaktiviert:

  • Direkter Test, eine LED zu steuern über verfügbare vorkompilierte Steuerbefehle:
sudo su
echo 14 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio14/direction
echo 1 > /sys/class/gpio/gpio14/value
echo 0 > /sys/class/gpio/gpio14/value

Code 0-1: Direkter Test, eine LED zu steuern über verfügbare vorkompilierte Steuerbefehle

Quelle zu diesem (hier angepassten) Beispiel ist: https://maker.pro/nvidia-jetson/tutorial/how-to-use-gpio-pins-on-jetson-nano-developer-kit

Um die Umsetzung einfach zu halten, werden in der eigenen C-Funktion lediglich die obigen Terminal-Befehle mittels system(..)-Befehlen abgearbeitet.



Damit eine .jar - Library-Datei erstellt werden kann, muß sich LedOn.java und LedOff.java einem Package zugehören.


Das Package soll "jetson" heißen. Somit müssen alle Java-Quelltexte zu diesem Projekt in einen Unterordner mit dem Namen "jetson" kopiert werden und die Zugehörigkeit zum Package im Kopf der jeweiligen Klasse vermerkt werden:

Die mit erstellten und verwendete dynamischen Bibliotheken sollen jetson_ledon.so und jetson_ledoff.so heißen. Da diese über die Angabe eines absoluten Pfades vom Java-Programm geladen werden müssen, werden sie in einen Ordner kopiert, der in jedem Linux-System vorhanden ist und für Zusatzprogramme verwendet wird, namtentlich /opt.

package jetson;

public class LedOn
{
    static 
    {
        System.load("/opt/jetson_ledon.so");
    }
    public static native void ledon();
}

Code 0-2: LedOn.java

package jetson;

public class LedOff
{
    static 
    {
        System.load("/opt/jetson_ledoff.so");
    }
    public static native void ledoff();
}

Code 0-3: LedOff.java

Im Oberordner von jetson werden zunächst beide Java-Klassen kompiliert mit den Befehlen:

  • javac jetson/LedOn.java
  • javac jetson/LedOff.java

Danach werden die C-Header-Dateien aus den Informationen aus beiden Klassen generiert mit:

  • javah -jni -o ./jetson/ledon.h jetson.LedOn
  • javah -jni -o ./jetson/ledoff.h jetson.LedOff
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jetson_LedOn */

#ifndef _Included_jetson_LedOn
#define _Included_jetson_LedOn
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jetson_LedOn
 * Method:    ledon
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jetson_LedOn_ledon
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

Code 0-4: ledon.h -- automatisch mit javah erstellte C-Header-Datei.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jetson_LedOff */

#ifndef _Included_jetson_LedOff
#define _Included_jetson_LedOff
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jetson_LedOff
 * Method:    ledoff
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jetson_LedOff_ledoff
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

Code 0-5: ledoff.h -- automatisch mit javah erstellte C-Header-Datei.

Mit Hilfe der in den Header-Dateien zu finden Informationen können nun die zugehörigen C-Programme geschrieben werden:

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
JNIEXPORT void JNICALL Java_jetson_LedOn_ledon(JNIEnv *env, jclass clazz)
{
    system("echo 14 > /sys/class/gpio/export");
    system("echo out > /sys/class/gpio/gpio14/direction");
    system("echo 1 > /sys/class/gpio/gpio14/value");
}

Code 0-6: ledon.c

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
JNIEXPORT void JNICALL Java_jetson_LedOff_ledoff(JNIEnv *env, jclass clazz)
{
    system("echo 14 > /sys/class/gpio/export");
    system("echo out > /sys/class/gpio/gpio14/direction");
    system("echo 0 > /sys/class/gpio/gpio14/value");
}

Code 0-7: ledoff.c

Aus den .c und .h-Dateien im Ordner jetson können nun die dynamischen Bibliotheken generiert werden. Dass muß man mit cd in den Ordner jetson gehen und die entstandenen Dateien dann nach /opt kopieren und ausführbar machen:

  • cd jetson
  • gcc -o jetson_ledon.so -shared -Wl,-soname,jetson_ledon.so -I/usr/lib/jvm/java-8-openjdk-arm64/include/ -I/usr/lib/jvm/java-8-openjdk-arm64/include/linux/ ledon.c -lc
  • gcc -o jetson_ledoff.so -shared -Wl,-soname,jetson_ledoff.so -I/usr/lib/jvm/java-8-openjdk-arm64/include/ -I/usr/lib/jvm/java-8-openjdk-arm64/include/linux/ ledoff.c -lc
  • sudo cp ./jetson_ledon.so /opt
  • sudo cp ./jetson_ledoff.so /opt
  • sudo chmod +x /opt/jetson_ledon.so
  • sudo chmod +x /opt/jetson_ledoff.so

Um schließlich die Java-Befehle in Processing verfügbar zu machen, wird eine Library erzeugt. Zunächst wird dazu ein neuer Ordner angelegt, in den man wiederum nur den Unterordner "jetson" erzeugt und da hinein die kompilierten Java-Dateien legt, also LedOn.class und LedOff.class. In dem jetson übergeordneten Ordner führt man dann den folgenden Befehl aus, um die Library-Datei jetson.jar zu erzeugen:

  • jar cvf jetson.jar *

Folgende Ordnerstruktur muß dann angelegt und nach sketchbook/libraries kopiert werden:

jetson/
  /examples
  /library/jetson.jar
  /reference
  /source
  library.properties   

Code 0-8: Library-Ordnerstruktur für Processing

in die Textdatei "library.properties" kann folgendes geschrieben werden:

name=jetson
category=Hardware
authors=[Guido Kramann](http://www.kramann.info)
url=http://www.kramann.info
sentence=jetson provides dynamic libraries to control GPIOs and GPUs.
version=1
prettyVersion=v1.0.0
lastUpdated=0
minRevision=0
maxRevision=0

Code 0-9: library.properties

Nachdem diese Ordnerstruktur in sketchbook/libraries liegt, kann nun Processing gestartet werden:

  • /home/fhbstud/processing-4.0b6-linux-arm64/processing-4.0b6/processing

In Processing kann dann ein Test-Sketch angelegt werden:

import jetson.*;

public void setup()
{
        int y = Call.mult(4,5);
        System.out.println("4*5="+y);
        
        frameRate(1);
}

int x=0;
public void draw()
{
     if(x%2==0)
         LedOn.ledon();
     else
         LedOff.ledoff();
     x++;
}

Code 0-10: ~/sketchbook/Jetson_Test002/Jetson_Test002.pde

Nach dem Start schaltet dieses Programm die LED bei Pin 13 sekündlich an, bzw. aus.

jni006_LED_on_off.zip -- Ordner zur Programmentwicklung
jetson.zip -- Processing-Library (in ~/sketchbook/libraries entpacken und Processing (neu) starten).
Jetson_Test002.zip -- Sketch-Ordner mit dem Testprogramm.