Recitation 8: Serial Communication by ChangZhen from Inmi’s Session

What’s directly sent is always string. Copy and paste the example code, fill numbers of pin, port, and such in it, and add the task we want. Never try to understand what each line means.

Ex 1

Input from Arduino and output to Processing. Draw ellipse according to Arduino potential meter readings.

Arduino:

void setup() {
Serial.begin(9600);

}

void loop() {
int sensor1 = analogRead(A0);
int sensor2 = analogRead(A1);
Serial.print(sensor1);
Serial.print(“,”);
Serial.println(sensor2);
}

Processing:

import processing.serial.*;

String myString = null;
Serial myPort; // utilize the library onto myPort

int NUM_OF_VALUES = 2;
int[] sensorValues;

void setup() {
size(512, 512);
background(255);
setupSerial();
}

void draw() {
updateSerial();
printArray(sensorValues);
background(255);
ellipse(width/2,height/2,sensorValues[0]/2,sensorValues[1]/2);
}

void setupSerial() {
printArray(Serial.list());
myPort = new Serial(this, Serial.list()[3], 9600); // myPort is specified to be linked to port 3 USB, but what does “this” mean?
/*myPort.clear(); // mean?
myString = myPort.readStringUntil( 10 ); // 10 = ‘\n’ in ASCII meaning new line
myString = null;*/
sensorValues = new int[NUM_OF_VALUES]; // sensorValues[] contains two num
}

void updateSerial() {
while (myPort.available() > 0) { // mean by “available”?
myString = myPort.readStringUntil(10);
if (myString != null) { // why possibly null?
String[] serialInArray = split(trim(myString), “,”); // split string “trim(myString)” to element in array serialInArray[] when it meets “,”; trim(myString)removes whitespace characters from the beginning and end of a string
if (serialInArray.length == NUM_OF_VALUES) { // length is num of elements
for (int i=0; i<serialInArray.length; i++) {
sensorValues[i] = int(serialInArray[i]); // store value from string as int
}
}
}
}
}

Ex 2

Input from Arduino and output to Processing. Etch A Sketch.

Arduino: the same.

Processing:

import processing.serial.*;

String myString = null;
Serial myPort;

int NUM_OF_VALUES = 2;
int[] sensorValues;

void setup() {
size(512, 512);
background(255);
setupSerial();
updateSerial();
}

void draw() {
int pX = sensorValues[0]; // put before updateSerial to store previous 
int pY = sensorValues[1];
updateSerial();
printArray(sensorValues);
line(pX/2,pY/2,sensorValues[0]/2,sensorValues[1]/2);
if(mousePressed) {background(255);}
}

void setupSerial() {
printArray(Serial.list());
myPort = new Serial(this, Serial.list()[3], 9600);
myPort.clear();
myString = myPort.readStringUntil( 10 ); // 10 = ‘\n’ Linefeed in ASCII
myString = null;
sensorValues = new int[NUM_OF_VALUES];
}

void updateSerial() {
while (myPort.available() > 0) {
myString = myPort.readStringUntil(10); // ASCII 10 meaning new line
if (myString != null) {
String[] serialInArray = split(trim(myString), “,”);
if (serialInArray.length == NUM_OF_VALUES) {
for (int i=0; i<serialInArray.length; i++) {
sensorValues[i] = int(serialInArray[i]);
}
}
}
}
}

Ex 3

Input from Processing and output to Arduino. Arduino makes sound whose pitch depends on the coordinates in Processing. Only green texts are changed from the example code.

Arduino:

#define NUM_OF_VALUES 2 /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/

int tempValue = 0;
int valueIndex = 0;

/* This is the array of values storing the data from Processing. */
int values[NUM_OF_VALUES];

void setup() {
Serial.begin(9600);
pinMode(A2, OUTPUT);
}

void loop() {
getSerialData();
int pitch = values[0]+values[1];
tone(A2,pitch);
}

//recieve serial data from Processing
void getSerialData() {
if (Serial.available()) {
char c = Serial.read();
//switch – case checks the value of the variable in the switch function
//in this case, the char c, then runs one of the cases that fit the value of the variable
//for more information, visit the reference page: https://www.arduino.cc/en/Reference/SwitchCase
switch (c) {
//if the char c from Processing is a number between 0 and 9
case ‘0’…’9′:
//save the value of char c to tempValue
//but simultaneously rearrange the existing values saved in tempValue
//for the digits received through char c to remain coherent
//if this does not make sense and would like to know more, send an email to me!
tempValue = tempValue * 10 + c – ‘0’;
break;
//if the char c from Processing is a comma
//indicating that the following values of char c is for the next element in the values array
case ‘,’:
values[valueIndex] = tempValue;
//reset tempValue value
tempValue = 0;
//increment valuesIndex by 1
valueIndex++;
break;
//if the char c from Processing is character ‘n’
//which signals that it is the end of data
case ‘n’:
//save the tempValue
//this will b the last element in the values array
values[valueIndex] = tempValue;
//reset tempValue and valueIndex values
//to clear out the values array for the next round of readings from Processing
tempValue = 0;
valueIndex = 0;
break;
//if the char c from Processing is character ‘e’
//it is signalling for the Arduino to send Processing the elements saved in the values array
//this case is triggered and processed by the echoSerialData function in the Processing sketch
case ‘e’: // to echo
for (int i = 0; i < NUM_OF_VALUES; i++) {
Serial.print(values[i]);
if (i < NUM_OF_VALUES – 1) {
Serial.print(‘,’);
}
else {
Serial.println();
}
}
break;
}
}
}

Processing:

import processing.serial.*;

int NUM_OF_VALUES = 2;

Serial myPort;
String myString;

// This is the array of values you might want to send to Arduino.
int values[] = new int[NUM_OF_VALUES];

void setup() {
size(500, 500);
background(0);

printArray(Serial.list());
myPort = new Serial(this, Serial.list()[3], 9600);

myPort.clear(); // throw out the first reading, in case start reading in the middle of a string from the sender
myString = myPort.readStringUntil(10); // 10 = ‘\n’ Linefeed in ASCII
myString = null;
}

void draw() {
noStroke();
fill(0, 30);
rect(0, 0, 500, 500);

strokeWeight(5);
stroke(255);
line(pmouseX, pmouseY, mouseX, mouseY);

values[0] = mouseX;
values[1] = mouseY;

sendSerialData();
echoSerialData(200);
}

void sendSerialData() {
String data = “”;
for (int i=0; i<values.length; i++) {
data += values[i];
//if i is less than the index number of the last element in the values array
if (i < values.length-1) {
data += “,”; // add splitter character “,” between each values element
}
//if it is the last element in the values array
else {
data += “n”; // add the end of data character “n”
}
}
//write to Arduino
myPort.write(data);
}

void echoSerialData(int frequency) {
//write character ‘e’ at the given frequency
//to request Arduino to send back the values array
if (frameCount % frequency == 0) myPort.write(‘e’);

String incomingBytes = “”;
while (myPort.available() > 0) {
//add on all the characters received from the Arduino to the incomingBytes string
incomingBytes += char(myPort.read());
}
//print what Arduino sent back to Processing
print(incomingBytes);
}

3

Leave a Reply