This site is currently read-only as we are migrating to Oracle Forums for an improved community experience. You will not be able to initiate activity until January 30th, when you will be able to use this site as normal.

    Forum Stats

  • 3,889,823 Users
  • 2,269,775 Discussions
  • 7,916,823 Comments

Discussions

Software servo control from JAVA ME on Raspberry PI with /dev/servoblaster

WillemD
WillemD Member Posts: 15
edited Feb 25, 2015 7:57AM in Java ME Embedded
Long post:
I am using JAVA ME on Raspberry PI to drive various motors and sensors of a robot, all works fine, but also wanted to do servocontrol from software. Apparently I cannot do that directly by controlling puls length from software on an OS like the Raspberry PI, too inaccurate. So I tried to switch to servoblaster usage which uses DMA access to control pulse length.This works fine when called from python or from a command line, but now I want to call it from within a JAVA ME program.
For this I need to write simple settings to /dev/servoblaster.
After startup ls -l /dev/servoblaster shows:
prw-rw-rw- 1 root root 0 Feb 8 16:55 /dev/servoblaster
I tried to use the following code, with some print statements in between, to open servoblaster so I then can send values to it to drive the servos:

Path servoPath = FileSystems.getDefault().getPath("/dev","servoblaster");
System.out.println("path defined "+servoPath.toString());
outStream = Files.newOutputStream(servoPath,WRITE);
System.out.println("outstream created");

Also I have tried an alternative method in JAVA ME 8 with the following code. Both options are from the MOOC course on JAVA ME.
connection = (FileConnection)
Connector.open("file:///rootfs/dev/servoblaster", Connector.WRITE);
System.out.println("connection opened");
fileWriter = new PrintStream(connection.openOutputStream());
System.out.println("filewriter started");

In both cases the statements fail on the 3rd line, i.e. the opening of the OutputStream. I get an error message on the raspberry Pi:

[CRITICAL] [SECURITY] iso=2:Permission check failed: java.io.FilePermission "/dev/servoblaster" "write"
TRACE: <at java.security.AccessControlException: >, startApp threw an Exception
Although I did set the following permissions
java.io.FilePermission "/*" "write"
and
javax.microedition.io.Connector.file.write
javax.microedition.io.Connector.file.read

My conclusion so far is that this fails because JAVA ME8 does not support a PipedOutputStream
My other option would be to escape to the command line,echo the settings to /dev/servoblaster and then return to the JAVA ME program
but I found that JAVA ME also does not support the runtime exec command so I cannot do that.
So my only option now seems to be to switch to JAVA SE. I tried servoblaster from JAVA SE and that works fine, I just open it and send data to it, servo reacts, no problem. But then I still need to control the other motors and sensors.
I then tried to install the open jdk.dio libraries on the PI so I can still use what I have done so far, but the installation instructions are unclear to me and don't work.

So now I am moving away from JAVA ME and moving to JAVA SE with PI4J, unless someone here can help me out.
Thanks,
Willem

Best Answer

«1

Answers

  • Andrey.P-Oracle
    Andrey.P-Oracle Member Posts: 157
    edited Feb 10, 2015 6:14AM

    Hi Willem,

    It's sad to hear that you decided to abandon Java ME. I could only wish you've asked as soon as you've met the problems without waiting for them to stack up and frustration to increase. May I suggest you to fix the permission for nio.File and check whether this makes your code working? As a fact "/*" means all files in the root directory, but that's not recursive! This is clearly articulated the FilePermission javadoc. So you either have to use "/dev/*" or "/-" (recursive version) or just "<<ALL FILES>>"

    I'll let DIO guys to comment about installation of the library

    Thanks,

    Andrey

    WillemD
  • WillemD
    WillemD Member Posts: 15
    edited Feb 10, 2015 7:44AM

    Ah... that's something I did not realize or try. I will certainly give it a try tonight. I have only just started to convert to SE and PI4J and can still come back to JAVA ME :-)  It seems this is clearly a better place to ask these kind of ME questions, I asked on the PI forums before.

    The connector.file.write permission should still have worked in the second method, i.e. not affected by my error ?

    Thanks

    Willem

  • Sergey.N-Oracle
    Sergey.N-Oracle Member Posts: 99
    edited Feb 10, 2015 7:56AM

    Hi Willem,

    to run DIO on SE (i assume you've compiled the binaries, and they in the same folder as your app) you can try following

    java -Djava.library.path=dio.so -cp dio.jar,your_app.jar your_app_main_class

    /Sergey

  • WillemD
    WillemD Member Posts: 15
    edited Feb 10, 2015 8:22AM

    I managed to add the DIO libraries to my project in netbeans but my problem was on the Raspberry side, to avoid the error message when compiling my project using Netbeans on the remote Raspberry in SE but still relying on jdk.dio.

    The jdk.dio instructions list the following commands to install:

    hg clone http://hg.openjdk.java.net/dio/dev

    cd dev

    export PI_TOOLS=<path to raspberry pi toolchain>

    export JAVA_HOME=<path to JDK8>

    make

    And already on the hg command I get an error message that it does not know the command. I assumed I had to type those commands on the Raspberry?

    Forgive me, my last UNIX experience is from 20 years ago :-( and I am new to Raspberry, JAVA, Netbeans. Some more details on the installation would certainly be helpfull. I liked working with JAVA ME so far, following the MOOCourse and applying that learning to my robot.

  • Andrey.P-Oracle
    Andrey.P-Oracle Member Posts: 157
    edited Feb 10, 2015 10:39AM

    Hi Willem,

    Your Connector.file permissions are good and actually should have given you access through Connector.open even with your error in FilePermission. So if you still have problem of just curious could you please paste here the respective lines from your .jad file with all the permissions, it might happen that there is some problem which is not obvious from the text description

    Regarding DIO for SE. AFAIK you should be able to compile it on RPi itself. In this case you should have there:

    1. mercurial, to get the source code. And that's what "hg" is about and that's what apparently you're missing

    2. the gcc toolchain

    3, JDK8, either from Oracle or OpenJDK

    Regards,

    Andrey

  • Sergey.N-Oracle
    Sergey.N-Oracle Member Posts: 99
    edited Feb 10, 2015 12:07PM

    Hi Willem,

    both mercurial and gcc can be installed with "apt-get install". Oracle JDK has to be downloaded manually

    /Sergey

  • Andrey.P-Oracle
    Andrey.P-Oracle Member Posts: 157
    edited Feb 10, 2015 2:01PM

    If you have Raspbian on your RPi you should already have Oracle JDK already installed. It's there by default unless you removed it or have very old Raspbian image

    Andrey

  • WillemD
    WillemD Member Posts: 15
    edited Feb 10, 2015 2:42PM

    Hi Andrey,

    I tried both option, so /- and <<ALL FILES>> and I now seem to get one step further, no access error on that line but a null pointer exception on the next line that creates the writer. here is part of the error trail including my own print messages:

    new servos

    start

    path defined /dev/servoblaster

    file name servoblaster

    outstream created

    TRACE: <at java.lang.NullPointerException>, startApp threw an Exception

    - com/sun/cldc/i18n/Helper.getStreamWriter(), bci=8

    - com/sun/cldc/i18n/Helper.getStreamWriter(), bci=11

    - java/io/OutputStreamWriter.<init>(), bci=6

    The code is until that point is:

    public class Servos {

        OutputStream outStream;
        Writer outWriter;

        public Servos() {
        }

        public void start() {

            Path servoPath = FileSystems.getDefault().getPath("/dev", "servoblaster");
            System.out.println("path defined " + servoPath.toString());
            System.out.println("file name " + servoPath.getFileName());
            try {
                outStream = Files.newOutputStream(servoPath, WRITE);
            } catch (IOException ex) {
                Logger.getLogger(Servos.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("outstream created");
            outWriter = new OutputStreamWriter(outStream);
            System.out.println("outwriter createde");

    also when I try to print outStream.tostring() I get the null pointer exception.,

    The JAD file contains:

    MIDlet-Name: SearchAndRescueRobotV1

    MIDlet-Permission-1: jdk.dio.gpio.GPIOPinPermission "*:*"

    MIDlet-Permission-2: jdk.dio.DeviceMgmtPermission "*:*" "open"

    MIDlet-Permission-3: java.io.FilePermission "<<ALL FILES>>" "write"

    MIDlet-Permissions:

    javax.microedition.io.Connector.file.write,

    javax.microedition.io.Connector.file.read

    MIDlet-Vendor: wd

    MIDlet-Version: 1.0

    MicroEdition-Configuration: CLDC-1.8

    MicroEdition-Profile: MEEP-8.0

  • Andrey.P-Oracle
    Andrey.P-Oracle Member Posts: 157
    edited Feb 11, 2015 4:43AM

    Hi Willem,

    Apparently your outStream is null, that's why you get NPE from OutputStreamWriter constructor. So it looks like you've got an exception from Files.newOutputStream but for some reason it's not in the log. Could you please add ex.printStackTrace() into your catch block so we can check what's going on

    Thanks,

    Andrey

    WillemD
  • WillemD
    WillemD Member Posts: 15
    edited Feb 11, 2015 2:03PM

    When I include that statement I also get error messages on the OutStream creation, as follows:

    java.io.IOException

    - com/oracle/cldc/file/FileSystemImpl.throwIOException(), bci=4

    - com/oracle/cldc/file/FileChannelImpl.<init>(), bci=215

    - java/nio/channels/FileChannel.open(), bci=7

    - java/nio/channels/FileChannel.open(), bci=23

    - java/nio/file/Files.newByteChannel(), bci=3

    - java/nio/file/Files.newOutputStream(), bci=100

This discussion has been closed.