Sunday, August 21, 2016

Intel Edison Digital IO as Input with Java

In my previous tutorial, I’ve shown you how to configure digital IO as output. Now, I’ve just want to show you how to configure it as input.
Following Arduino pin mux and mode settings table (table 3) from Intel Edison Kit for Arduino Hardware Guide, we can set digital IO as input. As an example I’ll show you how to configure pin 12 as a signal input. Here are the step:
  1. Set pin 214 to low
  2. export pin 260, 228 and 42
  3. Set pin 260 as input (low)
  4. Set pin 228 to high for pullup enable or low to disable
  5. Set mode 0 for pin 42 as digital IO
  6. Set pin 214 to high

Arduino kit have two level signal for GPIO (3.3v and 5v). You can select using jumper J9 (IOREF), by default it sets to 5v. Make sure you select the right level to avoid damage on your board.


Start remote your Intel Edison and logon using SSH tools and try it:
echo low > /sys/class/gpio/gpio214/direction
echo –n “260” > /sys/class/gpio/export
echo –n “228” > /sys/class/gpio/export
echo –n “40” > /sys/class/gpio/export
echo low > /sys/class/gpio/gpio260/direction
echo low > /sys/class/gpio/gpio228/direction
echo mode0 > /sys/kernel/debug/gpio_debug/gpio40/current_pinmux
echo high > /sys/class/gpio/gpio214/direction

To read signal input value type:
cat /sys/class/gpio/gpio42/value

For configure and reading in java we need to add gpio reading function (the rest function you’ll find in Intel Edison Digital IO as Output with Java tutorial). Here is the function:

private static int gpio_read(int iopin) {
    try {
        InputStream ioData = new FileInputStream(_GPIO_IO_VALUE + Integer.toString(iopin) + "/value");
        InputStreamReader ioDataRead = new InputStreamReader(ioData);
           
        return (ioDataRead.read() ^ 48); // 48 = 0x30 in ascii table for filtering signal input 1 or 0
    }
    catch (Exception ex) {
        System.out.println("GPIO Read Error: " + ex.toString());
        return -1;
    }         
}

Down below is the complete example by using GPIO pin 13 as signal input for GPIO pin 12, to see the result link GPIO pin 13 with pin 12 using jumper cable:

package gpiotest;
import java.io.*;
public class Gpiotest {
    final static String _GPIO_EXPORT = "/sys/class/gpio/export";
    final static String _GPIO_UNEXPORT = "/sys/class/gpio/unexport";
    final static String _GPIO_IO_VALUE = "/sys/class/gpio/gpio";
    final static String _GPIO_MODE = "/sys/kernel/debug/gpio_debug/gpio";
    final static int _SHIELD_PIN12 = 42;
    final static int _SHIELD_PIN13 = 40;
   
    public static void main(String[] args) {
        // TODO code application logic here
        int iOutValue = 0;

        try {
            gpio_write(214, 0);
            // set IO pin 13 as output
            gpio_export(261);
            gpio_export(229);
            gpio_export(_SHIELD_PIN13);
            gpio_write(261, 1); // output
            gpio_write(229, 1); // pull up enable
            gpio_digital(_SHIELD_PIN13);
           
            // set IO pin 12 as input
            gpio_export(260);
            gpio_export(228);
            gpio_export(_SHIELD_PIN12);
            gpio_write(260, 0); // output
            gpio_write(228, 0); // pull up disable
            gpio_digital(_SHIELD_PIN12);

            gpio_write(214, 1);
       
            while (true) {
                if (iOutValue == 0) {
                    gpio_write(_SHIELD_PIN13, iOutValue);
                    iOutValue = 1;
                }
                else {
                    gpio_write(_SHIELD_PIN13, iOutValue);
                    iOutValue = 0;
                }
               
                System.out.println("Read IO12: " + Integer.toString(gpio_read(_SHIELD_PIN12)));
               
                Thread.sleep(1000);
            }
        }
        catch (Exception ex) {
            System.out.println("Main App Error: " + ex.toString());
        }
       
    }
   
    private static void gpio_export(int iopin) {
        try {
            OutputStream ioExport = new FileOutputStream(_GPIO_EXPORT);
            OutputStreamWriter ioExportWrite = new OutputStreamWriter(ioExport);
            ioExportWrite.write(Integer.toString(iopin));
            ioExportWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Export Error: " + ex.toString());
        }  
    }
   
    private static void gpio_unexport(int iopin) {
        try {
            OutputStream ioExport = new FileOutputStream(_GPIO_UNEXPORT);
            OutputStreamWriter ioExportWrite = new OutputStreamWriter(ioExport);
            ioExportWrite.write(Integer.toString(iopin));
            ioExportWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Unexport Error: " + ex.toString());
        }  
    }
   
    private static void gpio_write(int iopin, int value) {
        try {
            OutputStream ioDirection = new FileOutputStream(_GPIO_IO_VALUE + Integer.toString(iopin) + "/direction");
            OutputStreamWriter ioDirectionWrite = new OutputStreamWriter(ioDirection);
            if (value == 0) {
                ioDirectionWrite.write("low");
            }
            else {
                ioDirectionWrite.write("high");
            }
            ioDirectionWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Direction Error: " + ex.toString());
        }  
    }

    private static void gpio_digital(int iopin) {
        try {
            OutputStream ioMode = new FileOutputStream(_GPIO_MODE + Integer.toString(iopin) + "/current_pinmux");
            OutputStreamWriter ioModeWrite = new OutputStreamWriter(ioMode);
            ioModeWrite.write("mode0");
            ioModeWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Mode Error: " + ex.toString());
        }  
    }
   
    private static int gpio_read(int iopin) {
        try {
            InputStream ioData = new FileInputStream(_GPIO_IO_VALUE + Integer.toString(iopin) + "/value");
            InputStreamReader ioDataRead = new InputStreamReader(ioData);
           
            return (ioDataRead.read() ^ 48); // 48 = 0x30 in ascii table for filtering signal input 1 or 0
        }
        catch (Exception ex) {
            System.out.println("GPIO Read Error: " + ex.toString());
            return -1;
        }         
    }
}



Thursday, August 18, 2016

Intel Edison Digital IO as Output with Java

Arduino IDE is very simple and fast development tools to create application based on Arduino in Intel Edison. Anyway, I was wondering if we can use java language to build application in Intel Edison rather than Arduino IDE, because when I start the Edison it already have openjdk.

Before we start, lets take a look at "Intel Edison Kit for Arduino Hardware Guide" we will find Arduino pin table as seen below. These table explain which GPIO address in linux substitute to Arduino Uno GPIO pin. There are two SoC pin modes you can configure: 0 as GPIO and 1 as specific pin usage.

As an example we set digital IO pin 13 as output, because Intel Edison Arduino Kit already have Led connected to pin 13 the same as Arduino Uno.
If, we look at the table above there is a note before we configure digital IO we need to set pin 214 (TRI_STATE_ALL) to low, after complete we have to set pin 214 to high again. Here are the step by step:
  1. Set pin 214 to low
  2. export pin 261, 229 and 40
  3. Set pin 261 as output enabled (high)
  4. Set pin 229 to high for pullup enable or low to disable
  5. Set mode 0 for pin 40 as digital IO
  6. Set pin 214 to high
  7. To set GPIO 13 high, set pin 40 value to high
  8. To set GPIO 13 low, set pin 40 value to low  

How do we configure it in linux? Now, connect and logon to your Intel Edison remotely with SSH tools (putty). At prompt type:
echo low > /sys/class/gpio/gpio214/direction
# prepare io pin to be use
echo –n “261” > /sys/class/gpio/export
echo –n “229” > /sys/class/gpio/export
echo –n “40” > /sys/class/gpio/export
echo high > /sys/class/gpio/gpio261/direction
echo high > /sys/class/gpio/gpio229/direction
echo mode0 > /sys/kernel/debug/gpio_debug/gpio40/current_pinmux
echo high > /sys/class/gpio/gpio214/direction
# set output value for gpio pin 13 to high
echo high > /sys/class/gpio/gpio40/direction
# set output value for gpio pin 13 to low
echo low > /sys/class/gpio/gpio40/direction

Don’t forget, when you’ve done using gpio just remove configuration by unexport all used pin as an example to remove pin 40:
echo –n “40” > /sys/class/gpio/unexport

If we not remove, when we start the same pin and export it, it will show warning message “Device or resource busy”. But, you can still using it. By default pin 214 already export when we start Intel Edison, so you don’t need to export it.

Now, how do we run it from java? If you look at those script you’ll find 4 function; export, unexport, direction/write and mode. In here we describe it as

1. GPIO configuration constants
// const declaration for using GPIO
final static String _GPIO_EXPORT = "/sys/class/gpio/export"; // prepare pin export
final static String _GPIO_UNEXPORT = "/sys/class/gpio/unexport"; // prepare remove pin
final static String _GPIO_IO_VALUE = "/sys/class/gpio/gpio"; // prepare io pin value/direction
final static String _GPIO_MODE = "/sys/kernel/debug/gpio_debug/gpio"; // prepare pin mode

2. Function for export GPIO pin
// this function is use for export io pin
// example: echo –n “40” > /sys/class/gpio/export
private static void gpio_export(int iopin) {
        try {
            OutputStream ioExport = new FileOutputStream(_GPIO_EXPORT);
            OutputStreamWriter ioExportWrite = new OutputStreamWriter(ioExport);
            ioExportWrite.write(Integer.toString(iopin));
            ioExportWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Export Error: " + ex.toString());
        }  
    }

3. Function for write value to GPIO pin (direction)
    private static void gpio_write(int iopin, int value) {
        try {
            OutputStream ioDirection = new FileOutputStream(_GPIO_IO_VALUE + Integer.toString(iopin) + "/direction");
            OutputStreamWriter ioDirectionWrite = new OutputStreamWriter(ioDirection);
            if (value == 0) {
                ioDirectionWrite.write("low"); // set output to high state
            }
            else {
                ioDirectionWrite.write("high"); // set output to low state
            }
            ioDirectionWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Direction Error: " + ex.toString());
        }  
    }

4. Function for set GPIO pin mode
    private static void gpio_digital(int iopin) {
        try {
            OutputStream ioMode = new FileOutputStream(_GPIO_MODE + Integer.toString(iopin) + "/current_pinmux");
            OutputStreamWriter ioModeWrite = new OutputStreamWriter(ioMode);
            ioModeWrite.write("mode0");
            ioModeWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Mode Error: " + ex.toString());
        }  
    }

You have at least 3 function for running digital IO pin as output. For unexport the GPIO from linux you just use the same function as gpio_export except you need to use _GPIO_UNEXPORT const. Here are the complete example for configure GPIO pin 13 (just create gpiotest project from you Netbeans):

package gpiotest;
import java.io.*;
public class Gpiotest {
   
    final static String _GPIO_EXPORT = "/sys/class/gpio/export";
    final static String _GPIO_UNEXPORT = "/sys/class/gpio/unexport";
    final static String _GPIO_IO_VALUE = "/sys/class/gpio/gpio";
    final static String _GPIO_MODE = "/sys/kernel/debug/gpio_debug/gpio";
    final static int _SHIELD_PIN13 = 40;
   
    public static void main(String[] args) {
        // TODO code application logic here
        int iOutValue = 0;

        try {
            gpio_write(214, 0);
            // set IO Pin 13 as output
            gpio_export(261);
            gpio_export(229);
            gpio_export(_SHIELD_PIN13);
            gpio_write(261, 1); // output
            gpio_write(229, 1); // pull up enable
            gpio_digital(_SHIELD_PIN13);
           
            gpio_write(214, 1);
       
            while (true) {
                if (iOutValue == 0) {
                    gpio_write(_SHIELD_PIN13, iOutValue);
                    iOutValue = 1;
                }
                else {
                    gpio_write(_SHIELD_PIN13, iOutValue);
                    iOutValue = 0;
                }
               
                Thread.sleep(1000);
            }
        }
        catch (Exception ex) {
            System.out.println("Main App Error: " + ex.toString());
        }
       
    }
   
    private static void gpio_export(int iopin) {
        try {
            OutputStream ioExport = new FileOutputStream(_GPIO_EXPORT);
            OutputStreamWriter ioExportWrite = new OutputStreamWriter(ioExport);
            ioExportWrite.write(Integer.toString(iopin));
            ioExportWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Export Error: " + ex.toString());
        }  
    }

    private static void gpio_write(int iopin, int value) {
        try {
            OutputStream ioDirection = new FileOutputStream(_GPIO_IO_VALUE + Integer.toString(iopin) + "/direction");
            OutputStreamWriter ioDirectionWrite = new OutputStreamWriter(ioDirection);
            if (value == 0) {
                ioDirectionWrite.write("low");
            }
            else {
                ioDirectionWrite.write("high");
            }
            ioDirectionWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Direction Error: " + ex.toString());
        }  
    }

    private static void gpio_digital(int iopin) {
        try {
            OutputStream ioMode = new FileOutputStream(_GPIO_MODE + Integer.toString(iopin) + "/current_pinmux");
            OutputStreamWriter ioModeWrite = new OutputStreamWriter(ioMode);
            ioModeWrite.write("mode0");
            ioModeWrite.close();
        }
        catch (Exception ex) {
            System.out.println("GPIO Mode Error: " + ex.toString());
        }  
    }
}

If you having problem to run and code java remotely to your Intel Edison, you may look at my “Intel Edison with Netbeans” tutorial. 

Intel Edison with Netbeans

Basically, Intel Edison using Yocto Linux and it bundling with OpenJDK8. You can check by type “java –version” after you logon to Edison with SSH tools.
In this tutorial, I would like to show you how to integrate Netbeans with your Intel Edison device. First, you must know the Java Runtime location, for your reference you may find in /usr/lib/jvm/java-8-openjdk/jre/.

Now, lets start:
1.      Create new project in your NetBeans


2.      Select categories java and project java application

3.      For test connection, just type helloWorld in the project name the most famous starter for learning programming and select your project location.

4.      Once you complete step 3, then press “Finish”. Now, start fill up your code by adding “System.out.println(“Hello World!!!)” as it seen in the picture below

5.      Try to run it. This application will run on your local machine
6.      To make it run on your remote machine you need to configure your project properties, by right click mouse (for right hand person) on your project name as seen in the picture below

7.      In dialog project properties, select categories -> Run and press “New…” button. Create New Configuration dialog box will pop up, then type your configuration name, to end it press “OK” button.

8.      Next, press “Manage Platforms…” button. When you inside this dialog box, press “Add Platform…” button.

9.      Select platform type “Remote Java Standard Edition” then press “Next” button.

10.   Type your Platform Name, Host, Username and Password. Make sure you already configure your SSH using “configure_edison” command in your device. Then type your Remote JRE Path -> /usr/lib/jvm/java-8-openjdk/jre/ by default your Working Directory on your remote machine is in /home/root/NetBeansProjects/ as seen below.
11.   Once, your press “Finish” button, Netbeans will validate your configuration.


12.   Now, select “Runtime Platform” as seen in the picture below and press “OK” button to complete.
13.   Now, try to run again. You will see, Netbeans will run your application on remote machine as seen below
To see this application actually running on your machine, you can check your working directory on your machine as you write it on step 10 “Working Dir” as you can see below

Now, you can start develop your application on Intel Edison with Netbeans.
Have fun



Friday, August 12, 2016

Accessing Intel Edison UART1 on Arduino Kit

Intel Edison came with two add on model, one is mini breakout board and the other is Arduino compatible kit. The benefit with Arduino kit are:
1.      Lots of existing Arduino Uno shield compatible can be use
2.      IO signal can be select between 3.3v and 5v. While in mini breakout board IO signal is 1.8v to use this you need level shifter and its quiet difficult for beginner who wants to learn Intel Edison.
*See Intel Edison Kit for Arduino Hardware Guide
If you look at the picture, Intel Edison have two serial port, UART1 connect IO socket (red box) and UART2 is use for debugging. With Yocto Linux coming from Intel Edison UART1 is recognize as /dev/ttyMFD1 and UART2 as /dev/ttyMFD2. It’s easy to use UART1 with Arduino IDE for Intel Edison you just use:
void setup() {
Serial1.begin(baudrate)
}
void loop() {
               Serial1.println(“Hello World of Edison!!!”);
}

What if we want to access it through linux directly without Arduino IDE?
I made this note, because I’m having trouble connecting my serial device when using Intel Edison for the first time. And for an example I use Netbeans java with JSSC (Java Simple Serial Connector) to access UART1.  
Now, look at the GPIO linux table in the Hardware Guide


In table 3 we will see the address of GPIO, Mode and Control. Here the scheme to configure UART1_RxD and TxD:
1.      Prepare all GPIO address before we use it
2.      TRI_STATE_ALL: set GPIO Linux 214 = LOW
3.      UART1_RxD: set Mode for address 130 = 1, Output enable = LOW and Pullup enable = IN
4.      UART1_TxD: set Mode for address 130 = 1, Output enable = HIGH and Pullup enable = OUT
5.      TRI_STATE_ALL: set GPIO Linux 214 = HIGH
Ok, now start your SSH remote tools (putty) and logon to your Intel Edison.

Now start type:



# Prepare all GPIO address, if you find error when you running it means this IO already use or created.
echo –n “214” > /sys/class/gpio/export
echo –n “130” > /sys/class/gpio/export
echo –n “248” > /sys/class/gpio/export
echo –n “216” > /sys/class/gpio/export
echo –n “131” > /sys/class/gpio/export
echo –n “249” > /sys/class/gpio/export
echo –n “217” > /sys/class/gpio/export
# set TRI_STATE_ALL to LOW
echo low > /sys/class/gpio/gpio214/direction
# set RxD
echo low > /sys/class/gpio/gpio248/direction
echo in > /sys/class/gpio/gpio216/direction
echo mode1 > /sys/kernel/debug/gpio_debug/gpio130/current_pinmux
echo in > /sys/class/gpio/gpio130/direction
# set TxD
echo high > /sys/class/gpio/gpio249/direction
echo out > /sys/class/gpio/gpio217/direction
echo mode1 > /sys/kernel/debug/gpio_debug/gpio131/current_pinmux
echo out > /sys/class/gpio/gpio131/direction
# set TRI_STATE_ALL to HIGH
echo high > /sys/class/gpio/gpio214/direction
Now, you’re ready to use UART1 or /dev/ttyMFD1 in linux without Arduino IDE. Before using it, you need to configure the baudrate of UART1 by typing “sty –F /dev/ttyMFD1 9600” it shows you the baudrate set to 9600.
Open another putty session with serial port. Make sure, you’ve connected your USB to Serial adapter to your computer and set the same baudrate (9600). You will have two putty session, one is connect remotely to your Edison board (I’m using WiFi) and the other connect to USB Serial adapter.
In Edison remote session, start testing by typing
echo “Hello World of Edison !!!” > /dev/ttyMFD1
To test receiving message from your computer to Edison, just type “cat /dev/ttyMFD1” on you remote edison session. Now, start type message in your computer COMx session.
Next, I’ll show you how can use it in you java application.
1. Start your Netbeans, If you don’t know how to connect Netbeans with your Edison you can see my Intel Edison with Netbeans tutorial.
2. Create new project “EdisonSerial”
3. Set your run remotely to your Intel Edison configuration in Netbeans
4. Add jSSC library
5. Here are the sample code
package edisonserial;

import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;

public class Edisonserial {
    static SerialPort oSerialPort;
    public static void main(String[] args) {
        oSerialPort = new SerialPort("/dev/ttyMFD1");
        openSerialPort();
        sendMessage("Hello World of Edison from Netbeans!!!");
        closeSerialPort();
    }
   
    private static void openSerialPort() {
        try {
            oSerialPort.openPort();          
            oSerialPort.setParams(
                    oSerialPort.BAUDRATE_9600,
                    oSerialPort.DATABITS_8,
                    oSerialPort.STOPBITS_1,
                    oSerialPort.PARITY_NONE);
        }
        catch (SerialPortException ex) {
            closeSerialPort();
            System.out.println(ex);
        }      
    }
   
    private static void closeSerialPort() {
        try {
            oSerialPort.closePort();
        }
        catch (SerialPortException ex) {
            System.out.println(ex);
        }
    }
   
    private static void sendMessage(String msgValue) {
        try {
            oSerialPort.writeString(msgValue);
        }
        catch (SerialPortException ex) {
            System.out.println(ex);
        }
    }
}
6. Run this application, you will see your message send to your COMx-Putty session.
Hope, my note can be useful.