In this post I’ll show how to establish a serial communication (over USB) between the BeagleBoard and Arduino using a Java program. The Program will send commands from BB-XM to toggle a LED on the Arduino.
Hardware components:
- Beagleboard-XM Rev C
- Arduino Uno
- LED connected between the GND and pin 13
- USB cable Type A Plug to B Plug
Arduino Set Up
Before begin interfacing BeagleBoard with Arduino, you must have the Arduino IDE installed and configured. Once it is done, upload the following sketch from your PC:
void setup(){ Serial.begin(9600); pinMode(13, OUTPUT); } void loop (){ if (Serial.available()) { //read serial as ascii integer int ser = Serial.read(); //The ascii equivalent of numbers 0-9 are 48-57 if(ser >= 48 && ser <= 57) { int xTimes = ser - 48; Serial.print("Blink LED x"); Serial.println(xTimes,DEC); TooglePin(13,xTimes); } } } void TooglePin(int pin,int n){ for (int i = 0; i < n; i++) { digitalWrite(pin, HIGH); delay(1000); digitalWrite(pin, LOW); delay(1000); } }
This sketch will basically set Arduino to read incoming serial data as ascii
integer, if it’s between 0-9 then the pin 13 (LED) is toogled xTimes (incoming command).
BeagleBoard Set Up
For the Software Angstrom Linux will be used, the default kernel has support for tty ACM devices (Arduino) if not you can use opkg to install the kernel module:
opkg install kernel-module-cdc-acm
when Arduino is attached to the Beagleboard, something like that should be displayed:
[ 7963.286163] usb 2-2.4: new full speed USB device using ehci-omap and address 16 [ 7963.417602] usb 2-2.4: New USB device found, idVendor=2341, idProduct=0043 [ 7963.425354] usb 2-2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=220 [ 7963.433959] usb 2-2.4: Manufacturer: Arduino (www.arduino.cc) [ 7963.439788] usb 2-2.4: SerialNumber: 7493430303035111E150 [ 7963.459197] cdc_acm 2-2.4:1.0: ttyACM0: USB ACM device
Not so well known but the full Java Standard Edition can run on the BeagleBoard, luckily it is available in the Angstrom package feed.
you need to install for that the openjdk-6 java runtime environment on the BeagleBoard:
opkg install openjdk-6-jre
For Java serial communication the RxTx library is needed:
opkg install librxtx-java librxtx-jni
Now the BeagleBoard is ready to talk to Arduino using Java:
SerialComm.java
import gnu.io.CommPort; import gnu.io.CommPortIdentifier; import gnu.io.SerialPort; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class SerialComm { /** Milliseconds to block while waiting for port open */ private static final int TIME_OUT = 2000; /** Default bits per second for COM port. */ private static final int DATA_RATE = 9600; public SerialComm() { super(); } void connect ( String portName ) throws Exception { CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); if ( portIdentifier.isCurrentlyOwned() ) { System.out.println("Error: Port is currently in use"); } else { CommPort commPort = portIdentifier.open(this.getClass().getName(),TIME_OUT); if ( commPort instanceof SerialPort ) { SerialPort serialPort = (SerialPort) commPort; serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); InputStream in = serialPort.getInputStream(); OutputStream out = serialPort.getOutputStream(); (new Thread(new SerialReader(in))).start(); (new Thread(new SerialWriter(out))).start(); } else { System.out.println("Error: Only serial ports are handled by this example."); } } } /** */ public static class SerialReader implements Runnable { InputStream in; public SerialReader ( InputStream in ) { this.in = in; } public void run () { byte[] buffer = new byte[1024]; int len = -1; try { while ( ( len = this.in.read(buffer)) > -1 ) { System.out.print(new String(buffer,0,len)); } } catch ( IOException e ) { e.printStackTrace(); } } } /** */ public static class SerialWriter implements Runnable { OutputStream out; public SerialWriter ( OutputStream out ) { this.out = out; } public void run () { try { int c = 0; while ( ( c = System.in.read()) > -1 ) { this.out.write(c); } } catch ( IOException e ) { e.printStackTrace(); } } } public static void main ( String[] args ) { try { (new SerialComm()).connect(args[0]); } catch ( Exception e ) { // TODO Auto-generated catch block e.printStackTrace(); } } }
This simple code open a serial connection and then interact with it (receiving and sending data).
To be compiled on a Host PC (with an installed JDK) using:
javac SerialComm.java
The compiled classes need to be transferred on the BeagleBoard file system then can be started with:
root@beagleboard:~# java -cp .:/usr/share/java/RXTXcomm.jar \ -Djava.library.path=/lib:/usr/lib/jni \ -Dgnu.io.rxtx.SerialPorts=/dev/ttyACM0 \ SerialComm /dev/ttyACM0
The Java program need to be supplied with the Serial port name /dev/ttyACM0 as an argument. Now you can blink the LED from the Beagle by simply writing on the console numbers between 0-9 :
Hi,
Thanks for your post. My java app cannot find /dev/ttyACM0 port. The command:
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(“/dev/ttyACM0”);
gives me a NoSuchPortException .
I already used this lib to communicate with other port /dev/ttyUSB0 and i didn’t have any kind of problems.
I can access to serial trough arduino so the code in Arduino is working well and the serial port too.
Do you have any clue for a solution?
Thanks
Eduardo
Hi Eduardo,
First of all check if you have the ttyACM0 node (in the console or by using dmesg) when you plug in the Arduino to BB.
If not then you must install kernel-module-cdc-acm as described above.
When running your Java application make sure that the flag -Dgnu.io.rxtx.SerialPorts=/dev/ttyACM0 is set, it’s a bug in libtxrx and ACM ports must be explicitly declared.
I hope it helps.
Ayoub
Would this method work for communicating through a USB hub to two Arduinos and a PC laptop?
– Ricardo
hello Ricardo,
yes of course, you will just use /dev/ttyACM0 and /dev/ttyACM1 ports to communicate with the two Arduinos.
Thank you so much Ayoub. One problem solved, a zillion left to go.
My project at this state is to have an autonomous free-roaming robot that uses two Arduinos for motor/stepper controls and sensor reading that pass data to the Beaglebone for analysis, and oversight while the Beaglebone then (wirelessly) passes on significant data to a laptop for recording and possible further analysis.
The plan is to also allow the Beaglebone to step in when necessary and if required to swap sketches on the Arduinos as required by environmental exigencies.
I envision using the Beaglebone as the ‘conductor/composer’ and the Arduinos as the ‘orchestra’.
Good morning,
thank you for this interesting topic.
Do you know any mean to communicate directly to the Arduino through the USB port, withouth the need of a Serial port?
Thanks a lot
Hi,
Arduino has only a builtin USB port and an FTDI Chip allowing Serial communication over USB.
Arduino Software Stack as far as I know has no support to communicate directly using USB protocol.
Hi,
I’m having trouble getting SerialComm to execute on the beagle board. I keep getting that SerialComm can’t be found. Where am I supposed to of put the .java file at? I have tired both commands, the on provided and the one in the youtube video.
Thanks for you help
the file must be compiled !
Thank you, I mistaken the .java. for the .class file
hello Zaki,
i have beagleboard and arduino pro mini and i have all the required modules but i have no node in /dev/ttyUSB0 nor /dev/ttyACM0
thanks for help
did you installed the cdc-acm kernel module as indicated in the Article ?
it’s already installed i activated it with “modprobe cdc_acm” command
can you also check if it’s correctly loaded ?
lsmod and kernel messages from dmesg output ?
yes i check it with lsmod it’s loaded correctly:
Module Size Used by
ftdi_sio 30256 0
usbserial 28092 1 ftdi_sio
bufferclass_ti 4596 0
omaplfb 8749 0
pvrsrvkm 126503 2 bufferclass_ti,omaplfb
sdmak 3743 0
lpm_omap3530 6605 0
dsplinkk 125793 1 lpm_omap3530
rfcomm 33484 0
ipv6 249183 12
hidp 11193 0
l2cap 30104 4 rfcomm,hidp
bluetooth 49221 3 rfcomm,hidp,l2cap
rfkill 15030 2 bluetooth
and dmesg output:
[ 60.281524] usbcore: registered new interface driver usbserial
[ 60.290863] USB Serial support registered for generic
[ 60.306732] usbcore: registered new interface driver usbserial_generic
[ 60.313751] usbserial: USB Serial Driver core
[ 60.367584] USB Serial support registered for FTDI USB Serial Device
[ 60.382843] usbcore: registered new interface driver ftdi_sio
[ 60.388641] ftdi_sio: v1.5.0:USB FTDI Serial Converters Driver
but it output nothing when i plug in the ftdi adapter
the cdc_acm don’t work with my arduino uno since it use ftdi adapter
I see so maybe you need to activate the ftdi usb-serial driver ?
Hi,
Thanks for your post it is very useful.
I can write on TX but I have some troubles when I want to read data on RX.
I use exactly your program and on my BeagleBone I connect the Tx pin to the RX pin. So if I understand your program, when I write a data on TX I should see the same on RX and so on the console.
But I have no answer on the RX port and when I execute the “in.read(buffer)” function it seems to stop the Reader Thread. Do you have any idea on how to fix my problem?
Thanks for your help.
Anthony
I would love to see a project using the new BeagleBone Black, i2c TMP102 temperature sensor (sparkfun.com) and RXTX
Hello I am trying to compile the java file on the beaglebone but I get this error : error: package gnu.io does not exist import gnu.io.CommPort; package gnu.io does not exist
import gnu.io.CommPortIdentifier; Can someone help me out? thank you
I think I found a solution , to compile on beaglebone paste this : javac -verbose -classpath .:/usr/share/java/RXTXcomm.jar SerialComm.java.
thanks allots .. . . its working fine . . . .