In this part of the lab, you'll work with sample code that shows how to send messages from Java to your Arduino using serial communication. The Java program transmits (TX) data across the serial bus; the Arduino receives (RX) it and responds by changing the status of an LED.
In the steps below, text highlighted in yellow denote values you will need to change to update your setup.
Take the following code and place in a file named SimpleSerialTX.java.
/*
* Adapted from Yu Hin Hau's code
* https://billwaa.wordpress.com/2012/05/18/engineering-arduino-to-java-communication-2/
*
* Simple example of Java and Arduino Communication
* Sends messages using the serial bus.
* If sent message is: 0 -> LED off, 1 -> LED on, 2 -> LED blink once.
*/
import java.util.Scanner;
import jssc.SerialPort;
import jssc.SerialPortList;
import jssc.SerialPortException;
public class SimpleSerialTX
{
/**** SETTINGS -- change to match your setup! *******/
// change the following to match the serial port you use for the Arduino
final static String SERIAL_PORT_ADDRESS = "/dev/tty.usbmodem1421";
// change to match the baud rate you're using from Arduino
final static int BAUD_RATE = 19200;
/**** END SETTINGS *********************************/
//Declare Special Symbol Used in Serial Data Stream from Arduino
final static String start_char = "@";
final static String end_char = "#";
final static String sep_char = ":";
private static SerialPort serialPort;
private static Scanner reader;
public static void main(String[] args)
{
//Initialize Port
serialPort = new SerialPort( SERIAL_PORT_ADDRESS );
//Create Scanner to read from Console
reader = new Scanner(System.in);
try
{
System.out.println( "about to open port" );
//Open Serial Port and set Parameters
serialPort.openPort();
serialPort.setParams( BAUD_RATE, 8, 1, 0);
// begin main loop
while ( true )
{
// wait for the user to enter a command, then send across the serial port
readFromConsole();
}
}
catch (SerialPortException ex)
{
System.out.println(ex);
}
}
/**
* Prompt and wait for the user to enter a command.
* TX (transmit) that command through the serial port.
**/
public static void readFromConsole()
{
System.out.print("Operation (0 = Off / 1 = On / 2 = Blink / q = Quit ): ");
try
{
// if there is something to read from the command line
if(reader.hasNext())
{
/* Remember that through Serial, we are sending bytes through,
* therefore, we must convert the char input we got
* into byte form. In another word, the value reprsented in
* the system encoding, aka ASCII code. 0 is 48, 1 is 49,
* 2 is 50... luckily, we can type cast in Java. Mess around
* with this program to see the different ASCII representation
* for each of your character input!
*/
// read input from the command line
String input = reader.next();
// get the first character (ignore the rest)
char firstChar = input.charAt( 0 );
// // convert it to an array of chars
// char inputArray[] = input.toCharArray();
// if it's a 'q', quit
if ( firstChar == 'q')
{
// close the port
serialPort.closePort();
// end the program
System.exit( 0 );
}
else
{
// convert to byte by casting
// and send the data across the port
serialPort.writeByte((byte)firstChar);
System.out.println((byte)firstChar + " <= sent!");
}
}
}
catch (SerialPortException ex)
{
System.out.println(ex);
}
}
}
First, you will need to update the values of the constants to match your setup. Notice the settings area at the top of the class file.
The SERIAL_PORT_ADDRESS should match the port you select in the Arduino application.
The BAUD_RATE must match that of the Arduino sketch (you should not have to change this).
Next, you will compile your code. This class relies on the JSSC (Java Simple Serial Connector) library, which is included in the Arduino environment (versions 1.5.6+). Therefore, in order to compile your java class, you'll need to include this library in the class path.
First, determine the path of the library; it is actually stored as a JAR within your Arduino application. To see the actual file, right click your Arduino application in the Finder and select Show Package Contents. Within the resulting directory structure, navigate to Contents -> Resources -> Java. Within this directory, you should see a file name jssc****.jar, where the **** indicates the version number. Right-click that file and select Get Info. In the resulting window, look for the path to the file (next to "Where").
You will need to use this path along with the -cp flag when compiling your java program. For example, using the above path, I would compile my code with the command:
javac -cp /Applications/Arduino1.6.0.app/Contents/Resources/Java/jssc-2.8.0.jar *.java
Confirm that your code compiled -- you should see a SimpleSerialTX.class class file.
Copy and upload the following Arduino sketch. It waits to receive (RX) messages from the Serial bus and changes the status of the onboard LED accordingly. (0 -> LED off, 1 -> LED on, 2 -> LED blink once)
/*
* Adapted from Yu Hin Hau's code
* https://billwaa.wordpress.com/2012/05/18/engineering-arduino-to-java-communication-2/
*
* Simple example of Java and Arduino Communication
* Receives messages using the serial bus.
* If received message is: 0 -> LED off, 1 -> LED on, 2 -> LED blink once.
*/
// settings
int BAUD_RATE = 19200;
int LED = 13;
//Define special symbols
char start_char = '@';
char end_char = '#';
char sep_char = ':';
// rx data
char operation = 0; // to hold received data
void setup()
{
// for communication
Serial.begin(BAUD_RATE);
// for LED output
pinMode(LED, OUTPUT);
}
/**
* At each loop iteration,
* see if there is a message to receive (rx) and store it to use as the next operation.
**/
void loop()
{
// try to receive a message
if ( receiveMessage() )
{
// if so, use it to control the LED
doOp();
}
}
/**
* See if there is a message to receive. If so, store it in
* operation variable.
**/
boolean receiveMessage()
{
// check if there is a message
boolean msgWaiting = (Serial.available() > 0) ? true : false;
// if there is one, read it and store in operation
if ( msgWaiting )
operation = Serial.read();
// return true if we got a message
return msgWaiting;
}
/*Remember that the data we sent
* from the Java client are bytes casted as chars;
* therefore, the values that get sent
* through are ASCII numerical codes.
* We use this data to convert / compare it back with
* a char type value.
* 0 -> LED off, 1 -> LED on, 2 -> LED blink once
*/
void doOp()
{
//LED Off
if(operation == '0')
digitalWrite(LED, LOW);
//LED On
else if(operation == '1')
digitalWrite(LED, HIGH);
//LED Blink
else if(operation == '2')
{
digitalWrite(LED, HIGH);
delay(500);
digitalWrite(LED, LOW);
delay(500);
}
}
Notice the BAUD_RATE value matches the constant from the Java file -- it is important that they agree on the communication rate!
Upload your sketch to the Arduino.
Do not open the Serial monitor, as it will interfere with the java program's ability to access the bus.
Now, it's time to test out sending messages from Java. Remember that the Java program relies on the JSSC library. Therefore, you need to again include the JAR in the classpath; in addition, you will need to include the directory with the class file of your java program. Here, we assume the current directory, denoted by the dot (.), and append it to the path by using the OS-dependent path separator ( : for *nix systems, including Mac OS X).
Run your java program with the java command and -cp flag, as in
java -cp /Applications/Arduino1.6.0.app/Contents/Resources/Java/jssc-2.8.0.jar:. SimpleSerialTX
Test it out by sending messages as indicated. You should see your onboard LED respond!