Tuesday, March 11, 2014

Raspberry Pi. Read data from USB Serial Port using Java and Python.


Hello,

Recently I bought my first Raspberry Pi, and as a first project I decided to implement a wireless package filter.. Here I'm going to show how to read the USB (serial port) using Linux on a Raspberri Pi.

Using Python

First, you have to install the basic packages to read serial port

pi@raspberrypi ~ $ sudo apt-get install python-serial

In my case I am using FTDI wireless USB device, connected to the port /dev/ttyUSB0. You can check the state of your USB stick and the kernel modules associted to it using the command:

pi@raspberrypi ~ $ dmesg
...
[    5.822444] usbcore: registered new interface driver usbserial
[    5.988161] usbcore: registered new interface driver usbserial_generic
[    6.169752] usbserial: USB Serial support registered for generic
[    6.594175] usbcore: registered new interface driver ftdi_sio
[    6.683308] bcm2708-i2s bcm2708-i2s.0: Failed to create debugfs directory
[    6.870064] usbserial: USB Serial support registered for FTDI USB Serial Device
[    7.198032] ftdi_sio 1-1.2:1.0: FTDI USB Serial Device converter detected
[    7.336725] usb 1-1.2: Detected FT232RL
[    7.533758] usb 1-1.2: Number of endpoints 2
[    7.639343] usb 1-1.2: Endpoint 1 MaxPacketSize 64
[    7.729645] usb 1-1.2: Endpoint 2 MaxPacketSize 64
[    7.808760] usb 1-1.2: Setting MaxPacketSize 64
[    7.879211] usb 1-1.2: FTDI USB Serial Device converter now attached to ttyUSB0
...


The loaded modules for my devices are shown with the command:

pi@raspberrypi ~ $ lsmod
Module                  Size       Used by

...
ftdi_sio               29846       0
usbserial              26929       1 ftdi_sio
...


You can get more information about your USB devices as follow:

pi@raspberrypi ~ $ lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial 


Once we know that the device is connected and has beed detected we can start coding. In my case the parameters to fetch the device are: 9600 8N1.

import serial
import sys

# configure the serial connections (the parameters differs on the device you are connecting to)
ser = serial.Serial(
    port='/dev/ttyUSB0',
    baudrate=9600,
    parity=serial.PARITY_ODD,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
)
 
# Print the bytes feched 
while True:
    n = ser.inWaiting()

    if n>0:

            ch=ser.read(size=1)
            print("%02x" % ord(ch),  end='')

This is a very basic code that read data from /dev/ttyUSB0 and print it hexadecimal pair format.

Now you can include your code to detect different telegrams or patterns, por example using:

            if '0x68' == hex(ord(ch)):
                    data="blablabla"

Using Java

If we want to do the same using Java, we need to install first the RXTX library (and of course Java SDK)

pi@raspberrypi ~ $ sudo apt-get install librxtx-java
Then you need to update your local varibles: CLASSPATH and LD_LIBRARY_PATH, for example as follow:

pi@raspberrypi ~ $ export CLASSPATH=$CLASSPATH:/usr/share/java/RXTXcomm.jar
pi@raspberrypi ~ $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/jni


Now you are ready to code. A basic example is here presented:

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.IOException;
import java.io.InputStream;

public class TestSerialComm {
    private CommPortIdentifier portIdentifier;
    private SerialPort serialPort;
    private InputStream in;

    public static final boolean DEV_MODE = true;
   
    void connect( String portName ) throws Exception {
        this.portIdentifier = CommPortIdentifier.getPortIdentifier( portName );

        if( portIdentifier.isCurrentlyOwned() ) {
       
          System.out.println( "Error: Port is currently in use" );
         
        } else {
       
            if(DEV_MODE) System.out.println("Starting...");
           
            int timeout = 2000;
            CommPort commPort = portIdentifier.open( this.getClass().getName(), timeout );

            if( commPort instanceof SerialPort ) {
                this.serialPort = ( SerialPort )commPort;
                serialPort.setSerialPortParams( 9600 ,
                                            SerialPort.DATABITS_8,
                                            SerialPort.STOPBITS_1,
                                            SerialPort.FLOWCONTROL_NONE );

                this.in = serialPort.getInputStream();

            } else {
                System.out.println( "Error: Only serial ports are handled by this example." );
            }
        }
    }

    public void fetchTelegrams() throws Exception {
        int b = -1;

        if(DEV_MODE) System.out.println("Inside loop...");

        while (true) {

            // Read new byte
            b = this.in.read();        


            // Negative value means no-data
            while(b<0 br="" nbsp="">                             b = this.in.read();


            // We have data
            System.out.print(this.hexify(b));             

             // Your code is here
             // ....
        }

    }
   
    /*
     * Convert received byte (int form) to HEX couples.
     */
    public String hexify(int input){
        String output = Integer.toHexString(input).toUpperCase();
        if(output.length() == 1)
            output = "0"+output;
        return output;
    }

    public static void main( String[] args ) {
        try {
            TestSerialComm test = new TestSerialComm();
            test.connect( "/dev/ttyUSB0" );
                                       
            // Infinity loop
            test.fetchTelegrams();
            System.exit(0);
               
        } catch( Exception e ) {
          e.printStackTrace();
        }
    }
}


To compile this example, you can for example do this:

pi@raspberrypi ~/java $ javac TestSerialComm.java
pi@raspberrypi ~/java $ java TestSerialComm
Starting...
Running...

74495041919473055087219194730...

I hope help!!


No comments:

Post a Comment