In this lab, you will build either a simple game or an audio player that is controlled from the Arduino. Technically, you will use serial communication between Arduino and P5JS to achieve this.
In this lab, you will use serial communication to send multiple values between Arduino and another software program. P5JS is suggested but you are welcome to use Unity, MaxMSP, Processing, or another program that can work with Arduino. Regardless of the platform you choose, you must create something interactive with both inputs from the Arduino that has either visual or auditory output (or both) based on sensor data.
Starting with the Arduino, I created a simple sketch that read the values from the Force-sensitive resistor and photocell and wrote these values to the serial monitor. I then used the p5.serialcontrol to connect the sensors to the p5.js web editor. In the web editor, I read the values from the serial monitor and split them into an array. I then used the array values to control the power of the throw and control when to throw the ball. Then I used simple shapes to draw out a character, ball, and target to complete the game.
int pressure;
int light;
void setup() {
Serial.begin(9600);
}
void loop() {
pressure = analogRead(A6);
delay(1);
light = analogRead(A0);
delay(1);
Serial.print(pressure);
Serial.print(",");
Serial.println(light);
}
var serial;
var portName = '/dev/tty.usbmodem143401';
var power = 0;
var shoot = 0;
var count = 0;
var next = true;
var score = 0;
var y = 300;
var x = 90;
var targetx = 700;
var targety = 300;
function setup() {
createCanvas(700, 400);
serial = new p5.SerialPort();
serial.list();
serial.open('/dev/tty.usbmodem1101');
serial.on('connected', serverConnected);
serial.on('list', gotList);
serial.on('data', gotData);
serial.on('error', gotError);
serial.on('open', gotOpen);
serial.on('close', gotClose);
serial.open(portName);
}
function serverConnected() {
print("Connected to Server");
}
function gotList(thelist) {
print("List of Serial Ports:");
for (let i = 0; i < thelist.length; i++) {
print(i + " " + thelist[i]);
}
}
function gotOpen() {
print("Serial Port is Open");
}
function gotClose(){
print("Serial Port is Closed");
latestData = "Serial Port is Closed";
}
function gotError(theerror) {
print(theerror);
}
function gotData() {
var data = serial.readLine();
if(data.length > 0) {
console.log(data);
var sensors = split(data, ",");
if(sensors.length > 1) {
power = sensors[0]/4;
shoot = sensors[1];
}
}
}
function draw() {
background("#1B9A89");
fill("#5DA252");
noStroke();
rect(50, 280, 40, 70);
fill("#FFFDE2");
noStroke();
ellipse(70, 260, 50, 50);
if (shoot < 300) {
let initialVelocity = power / 4;
y = 300 - initialVelocity * count + 1/2 * 9.8 * count * count;
x = 90 + initialVelocity * count;
fill("#5DADE2");
noStroke();
ellipse(x, y, 30, 30);
count++;
} else {
fill("#5DADE2");
noStroke();
ellipse(90, 300, 30, 30);
count = 0;
}
fill("#FFFF00");
noStroke();
rect(120, 290, 50 + power, 20);
fill("#FFFF00");
noStroke();
triangle(160 + power, 285, 160 + power, 315, 190 + power, 300);
if (collision(x, y, 30, targetx, targety, 50) == true) {
// next = true
score++;
targetx = 200 + Math.floor(Math.random() * 500)
}
fill("#FF0000");
noStroke();
ellipse(targetx, targety, 50, 50);
fill("#000000");
textSize(14);
text('Use the pressure sensor to increase the power or your throw. Then cover the photoresistor to throw the ball.\nHit the red target as many times as you can!', 20, 40);
fill("#000000");
textSize(32);
text(`Score: ${score}`, 40, 100);
}
// https://stackoverflow.com/questions/8331243/circle-collision-in-javascript
function collision(p1x, p1y, r1, p2x, p2y, r2) {
var a;
var x;
var y;
a = r1 + r2;
x = p1x - p2x;
y = p1y - p2y;
if (a > Math.sqrt((x*x) + (y*y))) {
return true;
} else {
return false;
}
}