Task #1: Make a Processing Etch-A-Sketch
Using the code from the example: Send Multiple Values and Receive Multiple Values, and building the circuit of the two potentiometers, I could draw an Etch-A-Sketch by twisting the potentiometers. After the code for drawing circles worked, I modified circles into the line and add “previous x” and “previous y”, using “previous x=x” and “previous y=y” to keep the previous tracks of lines.
In this Etch-A-Sketch, one potentiometer controls the circle’s x-axis movement, and the other controls the circle’s y-axis movement. It’s convenient to draw straight lines, but difficult to draw curves because it is hard to control. So I just wrote a “Hello” with the mouse.
The videos:
The code: (Arduino part)
#include "SerialRecord.h"
// Change this number to send a different number of values
SerialRecord writer(2);
void setup() {
Serial.begin(9600);
}
void loop() {
int Value1 = analogRead(A0);
int Value2 = analogRead(A1);
writer[0] = Value1;
writer[1] = Value2;
writer.send();
// This delay slows down the loop, so that it runs less frequently. This
// prevents it from sending data faster than a Processing sketch that runs at
// 60 frames per second will process it. It also makes it easier to debug the
// sketch, because values are received at a slower rate.
delay(20);
}
(Processing part:)
import processing.serial.*;
import osteele.processing.SerialRecord.*;
float prex;
float prey;
Serial serialPort;
SerialRecord serialRecord;
void setup() {
size(500, 500);
String serialPortName = SerialUtils.findArduinoPort();
serialPort = new Serial(this, serialPortName, 9600);
// If the Arduino sketch sends a different number of values, modify the number
// `2` on the next line to match the number of values that it sends.
serialRecord = new SerialRecord(this, serialPort, 2);
size(640, 360);
background(102);
}
void draw() {
serialRecord.read();
int value1 = serialRecord.values[0];
int value2 = serialRecord.values[1];
float x = map(value1, 0, 1024, 0, width);
float y = map(value2, 0, 1024, 0, height);
circle(x, y, 20);
stroke(255);
//line(x, y, prex, prey);
prex=x;
prey=y;
}
Task #2:
My partner Jinnuo (Jim) Liu took charge of the processing part, which should make the ball “bounce” and send values when the ball reaches the edge of the screen. I wrote Arduino code and built the circuit with two servos. My thought is when the ball hits the edge and sends a value to Arduino, one servo will work (turn to 120 degrees and then turn back), and when the ball reaches another edge, another value will be sent to make another servo work. When we first combined our code and circuit, only one servo worked, then we changed some parts of the code. We put “else” between the servo turning to 120 degrees and turning to 60 degrees. After a few changes, the servo did work with the ball, but it seems like having a delay between them.
The code: (Arduino)
#include <Servo.h>
#include "SerialRecord.h"
Servo servo1;
Servo servo2;
SerialRecord reader(2);
void setup() {
Serial.begin(9600);
servo1.attach(9);
servo2.attach(10);
}
void loop() {
reader.read();
if (reader[0] == 1) {
servo1.write(120);
delay(100);
}else servo1.write(60);
if (reader[1] == 1) {
servo2.write(60);
delay(100);
}else servo2.write(120);
}
(Processing: )
import processing.serial.*;
import osteele.processing.SerialRecord.*;
Serial serialPort;
SerialRecord serialRecord;
int x=75;
int direction=20;
int radius=75;
void setup() {
fullScreen();
background(0);
String serialPortName = SerialUtils.findArduinoPort();
serialPort = new Serial(this, serialPortName, 9600);
serialRecord = new SerialRecord(this, serialPort, 2);
ellipseMode(CENTER);
}
void draw() {
fill(0);
rect(0, 0, width, height);
noStroke();
// display instructions
fill(255);
ellipse(x, height/2, 2*radius, 2*radius);
if (x<radius||x>width-radius) {
direction*=-1;
}
x=x+direction;
if (x<radius) {
serialRecord.values[0] = 1;
} else serialRecord.values[0] = 0;
if (x>width-radius)
{
serialRecord.values[1] = 1;
} else serialRecord.values[1] = 0;
serialRecord.send();
}
We struggled for a long time to find ways to reduce the delay between the ball hitting the edge and the servo turns. With the help of professors, we changed the code to decrease the frequency that Processing sent signals to Arduino. And used “if(reader. read())” instead of “reader. read()”. Also, we deleted the “else” in the Arduino code to directly let the servo turn back. Finally, the servos worked as expected.
The code:(Arduino)
#include <Servo.h>
#include "SerialRecord.h"
Servo servo1;
Servo servo2;
SerialRecord reader(2);
void setup() {
Serial.begin(9600);
servo1.attach(9);
servo2.attach(10);
}
void loop() {
if (reader.read()) {
if (reader[0] == 1) {
servo1.write(120);
delay(100);
servo1.write(60);
}
if (reader[1] == 1) {
servo2.write(60);
delay(100);
servo2.write(120);
}
}
}
(Processing:)
import processing.serial.*; import osteele.processing.SerialRecord.*; int pre1, pre2; Serial serialPort; SerialRecord serialRecord; int x=75; int direction=20; int radius=75; void setup() { fullScreen(); background(0); String serialPortName = SerialUtils.findArduinoPort(); serialPort = new Serial(this, serialPortName, 9600); serialRecord = new SerialRecord(this, serialPort, 2); ellipseMode(CENTER); } void draw() { fill(0); rect(0, 0, width, height); noStroke(); // display instructions fill(255); ellipse(x, height/2, 2*radius, 2*radius); if (x<radius||x>width-radius) { direction*=-1; } x=x+direction; if (x<radius) { serialRecord.values[0] = 1; } else serialRecord.values[0] = 0; if (x>width-radius) { serialRecord.values[1] = 1; } else serialRecord.values[1] = 0; if (serialRecord.values[0]!=pre1||serialRecord.values[1]!=pre2) { serialRecord.send(); } pre1=serialRecord.values[0]; pre2=serialRecord.values[1]; } The final video: