System.out.print(sys.read());
Run your Java Program to see if “echos” the input typed into the console pane in Eclipse.
You might be wondering why you’d use wrappers? This StackOverFlow response has a great explanation.
Now that your program can receive Input, we must be cautious before sending to the Arduino.
The LEDs can represent 0-9 , a-f
What if:
the user types “g”
the user types “ab”
the user types “a03443sadfasd”
the user types “” (I.e., just hits enter without typing anything)
Often user input must be “validated” or “sanitized” to remove undesirable values. Both validation and sanitization are about avoiding undesirable values in the input. The term validation usually refers to ensuring input is in a valid format and range and sanitization usually means that no “covert” input is included. Unsanitized input is a prime culprit in many forms of attacks on internet sites (See: Prevent Web Attacks Using Input Sanitization, or Keeping Web Users Safe By Sanitizing Input Data, or Bobby Tables (Bobby Tables Explained)).
Before writing code to validate input you first have to identify what constitutes valid vs. invalid input and then you have to decide how to handle the problem.
For example, we know that with just 4 LEDs the Arduino can only display 1 Nibble (1 hex digit) at a time. If the input is longer than 1 character it’s invalid, but do you…
Keep just the first letter or
Keep just the last letter or
Ignore everything or
Raise an error and ask for user input again
Whenever receiving user input try to predict what will happen if they don’t follow your guidelines and plan appropriate responses. Planning responses to invalid input can avoid many run-time errors.
Next, send valid input from the console to the Arduino, and then prompt the user for additional input (i.e., put the prompt to the user and the sending of the input to the Arduino in a loop). Be careful how you take a char
type and send only a byte
. They are not the same thing in Java.
Switching things up
Now that you’ve successfully sent data from Java to you Arduino, it’s time to send data back the other way from you Arduino to a Java program in your computer.
Simple printing
Startup debugging
You can only have one open connection to your Arduino at any given time, be it
uploading new code, Serial Monitor, or a custom Java app. It’s important
Make sure to close all your Java programs after running them.
Click the red square on the side of the Java Console
to stop the program.
Click the x
next to it to clear that program’s output and show any other running programs (if there are)
Repeat for all open programs.
Close Serial Monitor when you are not using it.
The first task for Arduino to Java communication is to have a Java program receive data sent by the Arduino.
We will start simple.
You may want to refer to the JavaDoc for the jSSC
library, particularly the SerialPort
class methods.
You will be modifying the SerialComm
class that you created earlier.
Make sure to give it a static void main()
method if it doesn’t already have one. You will no longer rely on the HexTx.java
.
This program will receive data from a serial port (your Arduino) and print it out. In order to do that, you will use additional features of the SerialPort
class that you were introduced to earlier in the studio.
You should author two new methods (in addition to main
) in your SerialComm
class: available()
and readByte()
.
The available()
method should return a boolean
that is true
if there is at least one byte available to be read from the serial port. The getInputBufferBytesCount()
method of SerialPort
is helpful here.
The readByte()
method should read a single byte from the serial port and return a byte
that contains the value read. The readBytes(int byteCount)
method of SerialPort
is helpful here, but watch out for its return type (an array of bytes, byte[]
, rather than a single byte
).
In the main
routine, first create a new
SerialComm
object.
Next, continuously check if a byte is available()
and read it if there is. Have your program infinitely do this.
Now, take the data you read and find a way to print it to the Java console. Note the return type of readByte()
. Though in our case it represents a char
, it is not of type char
, it is of type byte
. They are not the same thing in Java, a char
is a 2-byte type. This is a design choice. You will have to cast it to print it properly.
Using any of your previous Arduino sketches that send data to the Serial Monitor (e.g., heartbeat.ino
might be a good choice), exercise your Java program and ensure that you get the same text output on the Java console that you previously were getting when using the Serial Monitor built into the Arduino IDE.
Experiment by starting the Java program first, then the Arduino. You can do this by downloading the Arduino program, running it and testing via the Serial Monitor, closing the Serial Monitor, and pulling the plug on the USB cable to the Arduino. Start up the Java program, then plug in the Arduino, which will cause it to start again (the sketch is retained in memory that is not lost when the power is removed).
After you’ve tried that, change the startup order. What happens when? Why?
A debugging version
Recall from above that there was a debug option that could be used to examine outgoing bytes from Java to the Arduino. We wish to replicate this behavior for bytes going from the Arduino to Java.
Reimplement the readByte()
method you made earlier so that it conditionally (based upon the value of the debug
instance variable) prints incoming bytes to the console in hex. When debug
is true
, you will need to convert to hex before you print: for every byte that comes from the Arduino, the debugging output should be 6 characters: the string “[0x”, 2 characters that represent the data byte in hexadecimal, and the character ‘]’ (e.g., if the byte in the data stream is 5f
, the string sent to the console should be “[0x5f]
” (or “[0x5F]
” if you prefer). You can use String.format("%02x", byte value)
to format a byte
as a two-character String
in hexadecimal.
It should continue to return the value of the byte that was input from the serial port.
You should now be able to view the data in hex as it goes through the readByte()
method and be able to view the “true” ASCII value in the Java console.
Finishing up
Check out and get out.
Make sure to commit your workspace
In Eclipse’s package explorer, any files you have modified since your last commit are prefixed with a >
.
Right-click the outer-most folder (you want to commit everything within), and choose Team>Commit...
. Write a helpful message and press OK
.
You can verify that your changes went to the server by opening the repository URL in any web browser.
Get checked out. You don’t need a TA for this, instead each member of the group should separately take the quiz (also available through Canvas).
Repository structure for this lab:
communication/
HexTX.java
SerialComm.java
HexLEDs/
HexLEDs.ino
1-9 , a-f
displays an error message for invalid input and does not pass invalid input to the Arduino.
Writing to the Serial port
writeByte()
Reading from the Serial port
available()
readByte()