Monday, September 30, 2013

Java Program to Read GPS Data from a Sparkfun Copernicus II GPS & Store it in a MySQL Database on a Raspberry Pi

The following is a very minimal example of how to read GPS data from a Sparkfun Copernicus II GPS board and save the readings to a MySQL database table on the Raspberry.

Prerequisites


  1. 09/25/2013 version of Raspbian Linux (includes Java 7)
  2. Make sure the serial port is available as described in "Freeing UART on the Pi." 
  3. Install the Java RXTX library:  sudo apt-get install librxtx-java
  4. Create soft link to comm port:  sudo ln -s /dev/ttyAMA0 /dev/ttyS80 The RXTX library can't find /dev/ttyAMA0.  You will need to re-create this symbolic link whenever you reboot the Raspberry Pi. 
  5. Install MySQL on the Raspberry Pi: apt-get install mysql-server-5.5 
  6. Get the platform-independent version of the MySQL Connector/J JDBC driver. Place the  mysql-connector-java-5.1.26-bin.jar (ver. number may vary) in the /usr/share/java/ directory. 
  7. The database table (gps) consists of two DOUBLE columns: n_lat, w_long, and a DATETIME column (that is also the primary key). 

Connections


Copernicus II Raspberry Pi
VCC           3.3V 
GND           GND 
TX-B          GPIO15
RX-B          GPIO14

Java Code


import gnu.io.*;
import java.io.*;
import java.util.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;

public class gps {
    static Connection conn = null;
    static PreparedStatement stmt = null;
    // Change gpsdb to name of your DB. Also change
    // DB user name & password
    static String url = "jdbc:mysql://localhost/gpsdb?" +
                "user=bberkland&password=Test1234";
    static String insertSQL = "INSERT INTO gps(n_lat, w_long, date_time) " +
        "VALUES (?, ?, now())";
    static String port = "/dev/ttyS80";
    static InputStream inStream;
    static OutputStream outStream;
    static String gpsData = "";

    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            conn = DriverManager.getConnection(url);
            CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(port);
            SerialPort serialPort = (SerialPort) portId.open("GPS", 5000);
            // Change serial port speed as needed
            serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
            inStream = serialPort.getInputStream();
            outStream = serialPort.getOutputStream();
            // Send NMEA command to set Copernicus II to 
            // output $GPGLL message every second.
            String nmeaString = "$PTNLSNM,0002,01*55\r\n";
            byte[] nmeaCmd = nmeaString.getBytes();
            String gpsData = "";
            outStream.write(nmeaCmd, 0, nmeaCmd.length);
            while(true) {
                if(inStream.available() > 0) {
                    int b = inStream.read();
                    if(b != 13) {
                        gpsData += (char)b;
                    }
                    else {
                        System.out.println(gpsData);
                        String[] datum = gpsData.split(",");
                        gpsData = "";
                        if(datum.length < 8 || datum[1] == null) {
                                continue;
                        }
                        stmt = conn.prepareStatement(insertSQL);
                        stmt.setDouble(1, Double.parseDouble(datum[1]));
                        stmt.setDouble(2, Double.parseDouble(datum[3]));
                        stmt.execute();
                    }
                }
            }
        } catch (Exception ex) {
                ex.printStackTrace();
        } finally {
            try {
                stmt.close();
                conn.close();
            } catch (Exception exc){
                exc.printStackTrace();
            }
        }
    }
}

Compiling & Running the Code


javac -cp /usr/share/java/RXTXcomm.jar:/usr/share/java/mysql-connector-java-5.1.26-bin.jar gps.java

java -Djava.library.path=/usr/lib/jni/ -cp /usr/share/java/RXTXcomm.jar:/usr/share/java/mysql-connector-java-5.1.26-bin.jar:. gps



Saturday, September 28, 2013

Sample Java Code to Read GPS Data from a Sparkfun Copernicus II DIP Module on a Raspberry Pi

The 09/25/2013 version of Raspbian Linux includes Java 7.  This example provides very basic Java code that reads GPS data via a serial port and prints the results to the console. My intention is not to provide an example of good object-oriented programming or thorough coverage of the RXTX library.  This post is about a minimum example of Java serial communication on the Raspberry Pi.

I found this post by Johannes Eickhold very helpful.

I used nano in a terminal window on the Raspberry Pi to edit the code.

Prerequisites


  1. As noted above, this example assumes you have the 09/25/2013 (or later) version of Raspbian.  
  2. Make sure the serial port is available as described in "Freeing UART on the Pi." 
  3. Install the Java RXTX library:  apt-get install librxtx-java 
  4. Create soft link to comm port:  ln -s /dev/ttyAMA0 /dev/ttyS80 The RXTX library can't find /dev/ttyAMA0.  You will need to re-create this symbolic link whenever you reboot the Raspberry Pi. 


Connections


Copernicus II Raspberry Pi
VCC           3.3V 
GND           GND 
TX-B          GPIO15
RX-B          GPIO14


Java Code

  

import gnu.io.*;
import java.io.*;
import java.util.*;

public class gps {
    private static InputStream inStream;
    public static void main(String[] args) {
        try {
            CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("/dev/ttyS80");
            SerialPort serialPort = (SerialPort) portId.open("GPS application", 5000);
            // Change baud rate if not 115200
            serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8, 
                 SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
            inStream = serialPort.getInputStream();
            String reading ="";
            while(true) {
                if(inStream.available() > 0) {
                    int b = inStream.read();
                    System.out.print((char)b);
                }
            }
        } catch (Exception ex) {
                ex.printStackTrace();
        }
    }
}

Compiling & Running


When compiling, be sure to include the RXTX JAR file in the classpath.   

javac -cp /usr/share/java/RXTXcomm.jar gps.java

When you run the program, you will need to include the RXTX JAR file in the classpath and also tell the Java runtime where to find the .so library files for RXTX:

java -Djava.library.path=/usr/lib/jni/ -cp /usr/share/java/RXTXcomm.jar:. gps

(The command above assume your current working directory contains the gps.class file.)