Intro to Computer Engineering

Assignment 4 - Dot Dot Dot, Dash Dash Dash, Dot Dot Dot

Click here to access the Canvas page with the repository for this assignment.

========

Finishing SerialComm

Before you can begin this assignment, you need to finish implementing the SerialComm class that we began in Studio.

Receiving data

We will once again be using the SerialPort class methods, this time to receive data. You may want to refer to the JavaDoc for the jSSC library.

Author two new methods 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). When debug is true, you will need to print the byte you just read. Don’t forget 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. Note this is not the same debug formatting as writeByte().

PLEASE REFER TO THE SerialComm GUIDE REGULARLY!

The idea

In this assignment you’ll use the combined power of Java and Arduino’s communications. Java will send user input data to the Arduino, and the Arduino will process those bytes and display their contents in Morse code. Morse code is an example of a substitution cipher (like the hex to binary substitution in the studio) because individual letters are replaced by a specific, fixed Morse code. Finally, the Arduino will send the Morse code back to Java to be displayed in the console.

By the end of this assignment you should have a better understanding of how data streams work and how they can be used. In addition, you will practice: iterating through arrays, working with ASCII characters, and transmitting data from and receiving data in both Arduino and Java.

========

The background

The Java side of the communication

We will be using the Java SerialComm class, which you created during the last studio. If you don’t yet have a functionally complete SerialComm class (that supports debug of both outgoing and incoming bytes), you will want to finish that first.

The Arduino

Serial stream

The primary functions for interacting with Arduino’s incoming Serial data are Serial.available() and Serial.read(). The Serial object operations are also built on top of Stream objects.

Serial.available() returns the number of bytes currently available to the Serial.read() function. Serial.read() reads the next byte from the stream.

Additional Functions

You will also use morseEncode(char symbol), which has already been written for you. morseEncode() will return a String that contains data corresponding to the Morse code for a given symbol. Since Morse code doesn’t have codes for lowercase letters, you will author a toUpper() function that will convert lowercase characters to uppercase. This will enable the morseEncode() function (which already calls toUpper(), meaning you don’t have to edit morseEncode()) to translate the alphanumeric characters inputted to morse code. toUpper() should have the following parameters:

// Argument: Any character
// Return Value: Either:
//    1) If the character is a letter, 
//       the upper case equivalent.  
//    2) If the character is not a letter, 
//       the original value.
char toUpper(char c) {
    ...
}

The easiest way to complete toUpper() is to use the properties of ASCII values. If you look closely at the ASCII Table you’ll notice that a lower case letter can be converted to an upper case letter by changing just one bit, so you may want to review bitwise operations. Since the letters are numeric and in lexicographic order they can also be compared via the normal relational operators, like:

char c;
...
// Does this character come "at or after" 
// the character for 0? (The character 1 would 
/  come after 0, etc.)
if(c>='0') { 

Using these properties of ASCII (being able to do comparisons, lexicographic ordering, and being able to manipulate bits) you can complete toUpper() with just a few lines of code.

Including files

There are three files in the MorseCoder/ directory:

Header files are an important part of code organization in C. They’re usually paired with a source file (Often with a “.c”, “.cc”, or “.cpp” extension). This separation helps for several reasons: it speeds up compile time, keeps code organized, and it can prevent errors due to order of declarations. Most importantly, the header is usually used to specify a public interface to functions whereas the corresponding source file provides private declarations. Often when you just need to use a function and don’t care about how it works you can simply refer to the header file.

Often a library of related functionality is contained in one source file (.cpp file) that may be used in many different projects. The MorseCodes files are a library that can be used to encode and decode Morse code.

========

The Arduino Assignment

Getting the Arduino to recognize input from the Serial Monitor

  1. Start by making the sketch in MorseCoder.ino read in characters from the Serial Monitor and echo them back, as in the studio.

  2. Complete the toUpper() function and test it. Use it to ensure all the echoed characters are in upper case. For example, if the following is entered:
        Don't shout at me! 

    It would be echoed back as:

        DON'T SHOUT AT ME!
  3. Use the morseEncode() function to echo back the Morse code of the characters instead of the characters themselves. morseEncode() will use your toUpper() function, so there’s no need for you to call toUpper() yourself. Read the comments in MorseCodes.h for details of how you need to call morseEncode(). You will have to process each character of the Morse code separately. For example, the morseEncode() function will return a String.

  4. Use the Serial Port to send the newly-translated Morse code from your Arduino back to your Java program running on your PC. The entire received message should be on one line, so make sure to use Serial.print() rather than Serial.println(). Please include one space ' ' between each letter of a word. So, “HI” would be sent as:
     .... ..
     H    I
     

    Additionally, use three consecutive spaces ' ' to indicate the end of a word. “HI MOM” would then be:

     .... ..   -- --- --
     H    I    M  O   M
     
  5. The reason your entire message should be one line is that we will be using the newline character '\n' to indicate the end of a transmitted message. It acts as a way for both Java and the Arduino to know that the current message is over. It acts as a very simple example of a communication protocol which we will discuss in more detail in the coming weeks. For now, just know that it is important that both programs know when a transmission is over, so whenever your Arduino program receives a newline character '\n', make sure to transmit it back to Java. This can be accomplished by calling Serial.println() with nothing in it or Serial.print("\n").

========

The PC Assignment

Your final task is to author a Java program that performs very close to the same function as the Serial Monitor.

  1. Import your SerialComm.java into the communication directory, replacing the stub that is currently there.
  2. PCToMorseCode.java should have the following abilities:
    • Inside the provided main method uncomment the provided SerialComm object and use it to interact with the Arduino.
    • It will need to prompt the user for a line to encode.
    • It will read an entire line at a time from the console.
    • It will send each character to the Arduino via the serial port.
    • It will need to send the newline character '\n' after it has finished sending all characters from the user message to indicate that it has finished transmitting the message.
    • It will then receive data coming back from the Arduino and should print it to the console.
    • It should continue receiving data back from the Arduino until it has finished receiving the encoded version of the message it just sent. It will know that it has finished receiving the message once it receives the '\n' character.
    • Once it has received the '\n' character indicating that it is done receiving the encoded message, it should prompt the user for another message to encode. (There are not timing guarantees about when the newline character will return, so you cannot use Thread.sleep() to wait a certain amount of time. In fact, you cannot use it for this assignment.)
    • The debug in SerialComm should be set to true so that you can see the bytes as they go into and out of the Java program (to/from the Arduino).

========

The check-in

Verify that you have completed the following files:

- `MorseCoder/`
	- `MorseCoder.ino`
	- `MorseCodes.cpp`
	- `MorseCodes.h`
- `communication/`
 		- `PCToMorseCode.java`
	- `SerialComm.java`
  1. Commit all your code. Do not ask to be checked out by a TA until after you have made certain that your work is committed. Failing to do this may result in you losing points on your assignment.

  2. Follow the checklist below to see if you have everything done before demo your assignment to a TA.

    • Your sketch is able to read input from Java or the Serial Monitor
    • toUpper() works as it should
    • Serial.read() should only be invoked when data is available()
    • Your sketch correctly iterates over the string returned by moreseEncode()
    • Your sketh sends each '.' '-' and ' ' to your Java program over the Serial port
    • Your sketch sends one space between every letter and three spaces between every word
    • Your Java program reads lines of characters and sends them through the serial port
    • Your Java program uses debug to display the outgoing and incoming data
    • All of your files are committed
  3. Check out with a TA.

========

The rubric

Note: the formal rubric is on Canvas, this is just the highlights.

Generated at 2024-11-09 20:48:16 +0000.
Page written by Julia Vogl, Bill Siever, Jeremy Goldstein, & Evan Simkowitz.