Read and send the serial data(Thank to tom & dan)

The goal of this section is to understand how the microcontroller formats data when you send it serially. You'll only use one analog sensor for it. Program the following into the module:

       int analogPin = 0;
       int analogValue = 0; // outgoing ADC value
void setup()
         {
         // start serial port at 9600 bps:
         Serial.begin(9600);
         }
void loop()
         {
         // read analog input, divide by 4 to
         make the range 0-255:
         analogValue = analogRead(analogPin); 
         analogValue = analogValue / 4;
         Serial.println(analogValue, DEC);
         // pause for 10 milliseconds:
         delay(10); 
         }
When you open the Serial Monitor, you should
see a number between 0 and 255 scrolling down the
debugger pane. That's because the DEC modifier to Serial.println()
formats the value it prints
as an ASCII-encoded DECimal value. Also, the Serial Monitor assumes
it should show you the ASCII
character corresponding to each byte it receives.
Try changing the Serial.println like so:
Serial.println(analogValue, BYTE);

Now you get a range of garbage characters. What's going on? The BYTE modifier doesn't format the bytes. It sends out the raw binary value of the byte. The Serial Monitor receives that binary value and assumes it should show you the ASCII character corresponding to that value again. The garbage characters are characters correspinding to the ASCII values the Monitor is receiving.

For example, imagine the sensor's value is 128. Divided by four, it becomes 32.

Serial.println(analogValue, DEC) results in "32"
Serial.println(analogValue, BYTE) results in " ", the space character, which has the ASCII value 32.
Here's the tricky part: Serial.println(analogValue, DEC) actually sent FOUR bytes! It sent a byte to represent the 3, a byte to represent the 2, a byte to tell the Monitor to move the cursor down a line(newline), and a byte to move the cursor all the way to the left (carriage return). The raw binary values of those four bytes are 51 (ASCII for "3"), 50 (ASCII for "2"), 10 (ASCII for "newline), and 13 (ASCII for "carriage return"). Check the ASCII table and you'll see for yourself.

Send the data in many formats

Try this program and view the results in the Serial Monitor:

int analogPin = 0;
         int analogValue = 0; // integer to print
void setup() {
         // open serial communications at 9600 bps
         Serial.begin(9600);
         }
void loop() {
         // read the analog inoput, divide by 4:
         analogValue = analogRead(analogPin) /4;
 // print in many formats:
         Serial.print(analogValue, BYTE); 
// Print the raw binary value analogValue
         Serial.print('\t'); // print a tab
         Serial.print(analogValue, BIN); 
// print the ASCII encoded binary analogValue
         Serial.print('\t'); // print a tab
         Serial.print(analogValue, DEC); 
// print the ASCII encoded decimal analogValue
         Serial.print('\t'); // print a tab
         Serial.print(analogValue, HEX); 
// print the ASCII encoded hexadecimal analogValue
         Serial.print('\t'); // print a tab
         Serial.print(analogValue, OCT); 
// print the ASCII encoded octal analogValue
         Serial.println(); // print a linefeed and carriage return
 delay(10);
         }


You should get output like this:
â 11100010 226 E2 342
á 11100001 225 E1 341
á 11100001 225 E1 341
á 11100001 225 E1 341
à 11100000 224 E0 340
à 11100000 224 E0 340
ß 11011111 223 DF 337
ß 11011111 223 DF 337
ß 11011111 223 DF 337
It's printing the raw binary value, then the ASCII-encoded binary value, then the ASCII-encoded decimal, hexadecimal, and octal values. You may never need all of these differnt formats, but you'll likely need at least the decimal and the raw binary versions at some point.

Send the values for all three sensors

Now send the values for all three sensors as binary values, like so:

int firstSensor = 0; // first analog sensor
         int secondSensor = 0; // second analog sensor
         int thirdSensor = 0; // digital sensor
         int inByte = 0; // incoming serial byte
void setup()
         {
         // start serial port at 9600 bps:
         Serial.begin(9600);
         pinMode(thirdSensor, INPUT);
         }
void loop()
         {
         // if we get a valid byte, read analog ins:
         if (Serial.available() > 0) {
         // get incoming byte:
         inByte = Serial.read();
         // read first analog input, divide by 4 to make the range 0-255:
         firstSensor = analogRead(0)/4;
         // delay 10ms to let the ADC recover:
         delay(10);
         // read second analog input, divide by 4 to make the range 0-255:
         secondSensor = analogRead(1)/4;
         // read switch, multiply by 255
         // so that you're sending 0 or 255:
         thirdSensor = 255 * digitalRead(2);
         // send sensor values:
         Serial.print(firstSensor, BYTE);
         Serial.print(secondSensor, BYTE);
         Serial.print(thirdSensor, BYTE); 
         }
         }


This isn't going to do anything in the Serial Monitor, because it's waiting for a byte from the computer before it sends. To make this work, you'll need a serial monitor that allows you to send bytes as well as to receive them.

OSX: To configure Terminal for serial communication in OSX, open the program and type ls /dev/tty.* This will give you a list of available serial ports. The names of the serial port in OSX are more unique than the names that Windows uses. Pick your serial port and type screen portname datarate. For example, to open the serial pot on an Arduino board at 9600 bits per second, you might type screen /dev/tty.usbserial-5B1 9600. The screen will cleared, and any bytes you type will be sent out the serial port you opened. They won't show up on the screen, however. Any bytes received in the serial port will be displayed in the window. To close the serial port, type control-A followed by control-\.

NOTE: only one program can control a serial port at a time. When you're not using a given program, remember to close the serial port. You won't be able to re-program the Arduino module if you don't, because the serial terminal program will have control of the serial port.

Once you've got the serial port open in your terminal program, type any character. You should get three bytes back, representing the three bytes sent out by the microcontroller. They won't be readable as numbers, though. If you want to see them as numbers, change BYTE above to DEC in each print statement.

What's happening here is that the computer is calling for a set of sensor readings by sending out a byte. The Arduino doesn't do anything unless it's received a byte (if (Serial.available() > 0)). When it gets a byte, it reads all three sensors and sends them. This method of communication between computers is called a call-and-response method, or handshaking. It's a good way to make sure you get only the data you need, and no more. In the next step, you'll write a Processing program to read those bytes.

Write a program to read those bytes

For this step, you'll need a programming environment that runs on the personal computer itslf, not on the microcontroller. Any environment that can open and close a serial port will do. For example, Java, Processing, Director, RealBASIC, Visual BASIC, and Max/MSP can all access the serial ports. JavaScript and Flash/Actionscript cannot, as of this writing.

The example below is in Processing. It listens for incoming serial bytes until it gets three of them. Then it sets the foreground color, x position, and y position of a ball on the screen using those values. When there's no incoming bytes available, it sends a byte out to call for more bytes. Read through it line by line, including comments, for the details. Then run it with your Arduino module attached to the serial port it's listening to.

import processing.serial.*;
int bgcolor; // Background color
         int fgcolor; // Fill color
         Serial port; // The serial port
         int[] serialInArray = new int[3]; // Where we'll put what we receive
         int serialCount = 0; // A count of how many bytes we receive
         int xpos, ypos; // Starting position of the ball
         boolean firstContact = false; // Whether we've heard from the microcontroller
void setup() {
         size(256, 256); // Stage size
         noStroke(); // No border on the next thing drawn
 // Set the starting position of the ball (middle of the stage)
         xpos = width/2;
         ypos = height/2;
 // Print a list of the serial ports, for debugging purposes:
         println(Serial.list());
 // I know that the first port in the serial list on my mac
         // is always my Keyspan adaptor, so I open Serial.list()[0].
         // On Windows machines, this generally opens COM1.
         // Open whatever port is the one you're using.
         port = new Serial(this, Serial.list()[0], 9600);
         port.write(65); // Send a capital A to start the microcontroller sending
         }
void draw() {
         background(bgcolor);
         fill(fgcolor);
         // Draw the shape
         ellipse(xpos, ypos, 20, 20);
 // If no serial data has beeen received, send again until we get some.
         // (in case you tend to start Processing before you start your 
         // external device):
         if (firstContact == false) {
         delay(300);
         port.write(65);
         }
         }
void serialEvent(Serial port) {
         // if this is the first byte received, 
         // take note of that fact:
         if (firstContact == false) {
         firstContact = true; 
         }
         // Add the latest byte from the serial port to array:
         serialInArray[serialCount] = port.read();
         serialCount++;
 // If we have 3 bytes:
         if (serialCount > 2 ) {
         xpos = serialInArray[0];
         ypos = serialInArray[1];
         fgcolor = serialInArray[2];
 // print the values (for debugging purposes only):
         println(xpos + "\t" + ypos + "\t" + fgcolor);
 // Send a capital A to request new sensor readings:
         port.write(65);
         // Reset serialCount:
         serialCount = 0;
         }
         }

If you did everything right, the ball should move in response to the analog sensors, and appear or disappear when you press the button.

Get creative

You just duplicated the basic functionality of a mouse; that is, a device with two analog sensors that affect X and Y, and a digital sensor (mouse button). What applications can you think of that could use a better physical interface for a mouse? Create a prototype in Arduino and Processing, or whatever programming environment you choose. Come up with a physical interface that makes it clear what actions map to what movements and actions. Figure out which actions can and should be possible at the same time (e.g. moving x and y to make a diagonal path). Think about what actions should be exclusive, if any (e.g. pressing two mouse buttons at once?). Present a working software and hardware model of your idea

Physical computing interaction Design

Processing + Arduino

Sensor & components

Essential Viewing

Lectures