Page 1 of 1

java.io.IOException: Invalid argument

Posted: Wed Dec 19, 2012 9:08 pm
by atael
Hello,
I have written a small piece of Java code, well I borrowed it from a blog and I just can't get it to work. Note that I am a novice developer and even more novice Embedded developer.

Code: Select all

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package atael;
 
import java.io.FileWriter;
import java.io.IOException;
 
/**
 *
 * @author atael
 */
public class PiGPIO {
 
    static final String GPIO_OUT = "out";
    static final String GPIO_ON = "1";
    static final String GPIO_OFF = "0";
    static final String GPIO_CH00="0";
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            
            /*** Init GPIO port for output ***/
            
            // Open file handles to GPIO port unexport and export controls
            FileWriter unexportFile = new FileWriter("/sys/class/gpio/unexport");
            FileWriter exportFile = new FileWriter("/sys/class/gpio/export");
 
            // Reset the port
            unexportFile.write(GPIO_CH00);
            unexportFile.flush();
            
            // Set the port for use
            exportFile.write(GPIO_CH00);   
            exportFile.flush();
 
            // Open file handle to port input/output control
            FileWriter directionFile =
                    new FileWriter("/sys/class/gpio/gpio"+GPIO_CH00+"/direction");
            
            // Set port for output
            directionFile.write(GPIO_OUT);
            directionFile.flush();
            
            /*** Send commands to GPIO port ***/
            
            // Open file handle to issue commands to GPIO port
            FileWriter commandFile = new FileWriter("/sys/class/gpio/gpio"+GPIO_CH00+
                    "/value");
            
            // Loop forever
            while (true) {
                
                // Set GPIO port ON
                commandFile.write(GPIO_ON);
                commandFile.flush();
        
                // Wait for a while
                java.lang.Thread.sleep(200);
        
                // Set GPIO port OFF
                commandFile.write(GPIO_OFF);
                commandFile.flush();
                
                // Wait for a while
                java.lang.Thread.sleep(200);
            }
 
        } catch (IOException | InterruptedException exception) {
            exception.printStackTrace();
        }
    }
}
It complies nicely and I transfer it to my RaspBerry Pi. When I try to execute my application like this:

Code: Select all

[email protected]:~# java -jar /home/pi/atael.jar
I get the following error:

Code: Select all

java.io.IOException: Invalid argument
        at java.io.FileOutputStream.writeBytes(Native Method)
        at java.io.FileOutputStream.write(FileOutputStream.java:318)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
        at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
        at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
        at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
        at atael.PiGPIO.main(PiGPIO.java:35)
I am using the following version of Java SE:

Code: Select all

[email protected]:~# java -version
java version "1.7.0_10"
Java(TM) SE Embedded Runtime Environment (build 1.7.0_10-b18, headless)
Java HotSpot(TM) Embedded Client VM (build 23.6-b04, mixed mode)
Any idea what I am doing wrong? Line 35 is:

Code: Select all

unexportFile.flush();
--Andy

Re: java.io.IOException: Invalid argument

Posted: Wed Dec 19, 2012 11:20 pm
by chriswhocodes
Hi Andy,

FileWriter is for writing character streams and I would expect GPIO to work in bytes?

See http://docs.oracle.com/javase/1.4.2/doc ... riter.html for the javadoc which mentions

FileWriter is meant for writing streams of characters. For writing streams of raw bytes, consider using a FileOutputStream.

Looking at this other GPIO code here: https://github.com/jkransen/framboos/bl ... ioPin.java the author is using FileOutputStream.write(byte[] bytes) method to send data to GPIO.

Try using FileOutputStream and I think you will get it working.

Re: java.io.IOException: Invalid argument

Posted: Fri Dec 28, 2012 5:45 am
by obrienmi8
Andy,
Hi,
In the blog by Hinkmond Wong about using low level file IO to control the GPIO pins. It seems that you have used an older version of his code - he recently corrected it to avoid the "Invalid argument" exception by first checking for the unexport file - you should add the following fragment to your version as the first write.
Running this code either as a FileWriter or FileOutputStream works fine both ways as both are OutputStream(s).
At Oracle we made every effort to publish articles as much as possible to help out the open source development community - a link to the original article always helps when we update/fix technical issues.
Thank you to Raspberry PI evangelist Hinkmond.
https://blogs.oracle.com/hinkmond/entry ... dded_gpio3

note: gpioChannel is undefined and should be replaced by GPIO_CH00 - see corrected version below.

Code: Select all

                File exportFileCheck = new File("/sys/class/gpio/gpio"+GPIO_CH01);
                if (exportFileCheck.exists()) {
                    unexportFile.write(GPIO_CH01);
                    unexportFile.flush();
                }
The version with the code above will work fine on a REV A or REV B board (remember pin 0 is now pin 2 - I see a flashing LED at 3.3v

http://elinux.org/RPi_Low-level_periphe ... .28GPIO.29

/michael
http://eclipsejpa.blogspot.ca/2012/11/j ... uster.html

Re: java.io.IOException: Invalid argument

Posted: Fri Dec 28, 2012 8:12 am
by savageautomate
If all you are trying to do is interact with the Raspberry Pi's GPIO ports from your own Java code, then you may want to try something like the Pi4J Project instead. This is an abstraction library that makes it much easier to work with the GPIO pins and states and you don't have to attempt to do all the lower level file access stuff.

More info and examples at:
http://pi4j.com/

Re: java.io.IOException: Invalid argument

Posted: Fri Dec 28, 2012 2:34 pm
by obrienmi8
Robert,
Yes, I agree, frameworks will be essential. I plan on finalizing use of either PI4J by Robert Savage and Chris Waltzl

http://pi4j.com/

Gordons' WiringPI

https://projects.drogon.net/raspberry-pi/wiringpi/

or Framboos by Jeroen Kransen

https://github.com/jkransen/framboos/tr ... a/framboos

But in the tradition of open source, before using a framework for the integration layer it is good to know about the mechanics of the low level file based peripheral control of the GPIO - when debugging issues with or away from the frameworks in the future.

thank you
/michael
http://eclipsejpa.blogspot.com

Re: java.io.IOException: Invalid argument

Posted: Fri Dec 28, 2012 3:36 pm
by savageautomate
Hi Micheal,

I fully agree with your comment about understanding the mechanics of a framework, but the OP mentioned that they were a "novice developer" so starting with a framework to get up and running may prove more fruitful and then go back and learn how it works under the covers after accomplishing a working program

Pi4J and Framboos are both great options for Java programmers. Pi4J is of course my favorite since I started the project :-) Pi4J does provide an eventing model for GPIO pin state change events based on interrupts (not polling).

WiringPi is a native C library, so if you want to use that directly you will have to create the JNI bindings. Pi4J is fully based on WiringPi. Even if you don't want to use the Pi4J API and prefer to use the WiringPi API, the Pi4J core JAR includes all the JNI bindings that wrap the WiringPi library.
https://github.com/Pi4J/pi4j/tree/maste ... j/wiringpi
https://github.com/Pi4J/pi4j/tree/maste ... ain/native

Re: java.io.IOException: Invalid argument

Posted: Sat Jan 12, 2013 2:57 pm
by atael
Thank y'all for all the suggestions and after following Hinkmonds fixes it works like a charm.

The only reason for not using a framework is that I am trying to understand how to control the Pi on a very low level (I am a experienced Java developer but a novice at the interfaces Pi gives me). When I get a feeling for it I'll look into a framework and pi4j looks excellent.

--Andy