Lab 4-Serial Game or Audio Controller

Part 1: The Arduino side

The first part of the lab was to establish connection between Arduino and P5 using the web editor with serial port library. First I started by testing out the connection by using the code we were given in class, that code gives you a simple message that tells you if you have connected to the port or not. We also have to make sure that we include the file serialport.js into our projects because that is part of what allows us to connect into ports.

/*
This P5 sketch is a template for getting started with Serial Communication.
The SerialEvent callback is where incoming data is received
By Arielle Hein, adapted from ITP Phys Comp Serial Labs
Edited March 12 2019
*/
var serial; //variable to hold an instance of the serial port library
var portName = 'YOUR-PORT'; //fill in with YOUR port
function setup() {
createCanvas(400, 300);
serial = new p5.SerialPort(); //a new instance of serial port library
//set up events for serial communication
serial.on('connected', serverConnected);
serial.on('open', portOpen);
serial.on('data', serialEvent);
serial.on('error', serialError);
serial.on('close', portClose);
//open our serial port
serial.open(portName);
//let's figure out what port we're on – useful for determining your port
// serial.on('list', printList); //set a callback function for the serialport list event
// serial.list(); //list the serial ports
}
function draw() {
background('dodgerblue');
}
//all my callback functions are down here:
//these are useful for giving feedback
function serverConnected(){
console.log('connected to the server');
}
function portOpen(){
console.log('the serial port opened!');
}
//THIS IS WHERE WE RECEIVE DATA!!!!!!
//make sure you're reading data based on how you're sending from arduino
function serialEvent(){
//receive serial data here
}
function serialError(err){
console.log('something went wrong with the port. ' + err);
}
function portClose(){
console.log('the port was closed');
}
// get the list of ports:
function printList(portList) {
// portList is an array of serial port names
for (var i = 0; i < portList.length; i++) {
// Display the list the console:
print(i + " " + portList[i]);
}
}
view raw sketch.js hosted with ❤ by GitHub

This is the serialport.js

https://raw.githubusercontent.com/vanevery/p5.serialport/master/lib/p5.serialport.js

After I establish connection I started with getting an input from the Arduino to change something on the P5 screen, as well as light up one LED when the potentiometer was turned. When I got that working I moved on to having to potentiometers changing elements of the P5 screen. On the P5 side I used the code that was provided by our Professor and worked on the Arduino side myself.

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(6, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int sensorValue = analogRead(A0);
int sensorValue2 = analogRead(A1);
int val = analogRead(0);
int val2 = analogRead(1);
int mappedval = map(val, 0, 1023, 0, 255);
int mappedval2 = map(val2, 0, 1023, 0, 255);
Serial.write(mappedval);
Serial.write(mappedval2);
Serial.print(mappedval1);
Serial.print(",");
Serial.println(mappedval2);
analogWrite(6, mappedval);
delay(1);
}
view raw Lab4_input2.ino hosted with ❤ by GitHub

The code was simple to make I took part of my code from last lab and added code so that there would be serial communication between p5 and the Arduino. Below is a video of the two potentiometers working and the light turning on as the dot color changes.

Part 2: The P5 Side

The second part to this lab was getting connection between P5 and the Arduino but focusing on getting P5 to make something on the Arduino light up. I started by looking at the P5 code that was in the Github repo in order to get a sense of what the code in Arduino should look like. I had to google a couple of things to get a full understanding of what it was doing but in the end I got the right code to work and get an input from P5.

const int ledPin = 5; // the pin that the LED is attached to
int incomingByte; // a variable to read incoming serial data into
void setup() {
Serial.begin(9600); // initialize serial communication
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output
}
void loop() {
//RECEIVE ASCII
if (Serial.available() > 0) { // see if there's incoming serial data
incomingByte = Serial.read(); // read it
if (incomingByte == 'H') { // if it's a capital H (ASCII 72),
digitalWrite(ledPin, HIGH); // turn on the LED
}
if (incomingByte == 'L') { // if it's an L (ASCII 76)
digitalWrite(ledPin, LOW); // turn off the LED
}
}
}
view raw Lab4_P5.ino hosted with ❤ by GitHub

Part 3: Simple Interactive Game

For the last part of the lab we had to create a interactive game that had inputs and outputs. I made a Space Shooter game where I implemented a potentiometer to move the player in the x direction and then a FSR sensor to shoot the enemy’s. I also added two LEDS to the FSR sensor as a output when your shooting they turn on, and if you hold down the sensor the LEDS stay on. The link below is the full game code and all the images.

https://github.com/Mch117/SerialGame

I did a simple circuit that connects one potentiometer and one FRS to Analog inputs 0 and 1. I had the LEDS connected to pin 6.

The fallowing code is the Arduino code I used to make sure my sensors were working and to write serial inputs into P5.

int LEDpin = 6;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDpin, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int sensorVal = analogRead(A0);
int sensor = analogRead(A1);
// int mappedval = map(sensorVal, 0, 1023, 0, 255);
//int pressure = map(sensor, 0, 1023, 0, 6);
//Serial.write(mappedval);
//Serial.write(pressure);
Serial.print(sensorVal);
Serial.print(",");
Serial.println(sensor);
if(sensor > 1)
{
digitalWrite(LEDpin, HIGH);
}
else
{
digitalWrite(LEDpin, LOW);
}
delay(1);
}

There wasn’t a lot that I had to change in my game code to make it usable with Arduino, I had to add the Serial port connection and add a map code so the sensors took the input and where usable. The fallowing three lines is the code that adds the ability to move the player and shoot with the sensors.

var newValue = map(sensor1, 0, 1023, 0, width -40);
player.x = newValue;

var button = map(sensor2, 0, 1023, 0, 6);

The fallowing video is the game working with the sensors.

var serial; //variable to hold an instance of the serial port library
var portName = 'COM4'; //fill in with YOUR port
var inData; //a variable to store incoming data
var sensor1, sensor2; //variables for each of my incoming sensor values – name these whatever you want
function setup() {
serial = new p5.SerialPort(); //a new instance of serial port library
//set up events for serial communication
serial.on('connected', serverConnected);
serial.on('open', portOpen);
serial.on('data', serialEvent);
serial.on('error', serialError);
//open our serial port
serial.open(portName);
createCanvas(canvasWidth, canvasHeight);
noCursor();
}
/////////////////////////////////////////////// Game Part
var canvasWidth = 600;
var canvasHeight = 400;
var score = 0;
//player
var player = {
color : "#FFF",
x : 280,
width : 40,
y : 355,
height: 40,
draw : function(){
image(img_player, this.x, this.y, this.width, this.height);
},
}
//bullet
var bullets = [];
function Bullet(I){
I.active = true;
I.x = player.x + player.width/2;
I.y = player.y + player.height/2;
I.width = 3;
I.height = 6;
I.yVelocity = 5;
I.inBounds = function(){
return I.x >= 0 && I.y >= 0 && I.x < canvasWidth – I.width && I.y < canvasHeight – I.height;
}
I.update = function(){
I.active = I.active && I.inBounds();
I.y -= I.yVelocity;
}
I.draw = function(){
image(img_bullet, I.x, I.y, I.width, I.height);
}
return I;
}
//enemies
var enemies = [];
function Enemy(I){
I.active = true;
I.x = Math.random() * canvasWidth;
I.y = 0;
I.width = 30;
I.height = 30;
I.yVelocity = 2;
I.inBounds = function(){
return I.x >= 0 && I.y >= 0 && I.x < canvasWidth – I.width && I.y < canvasHeight – I.height;
}
I.draw = function(){
image(img_enemy, I.x, I.y, I.width, I.height);
}
I.update= function(){
I.active = I.active && I.inBounds();
I.y += I.yVelocity;
}
return I;
}
//collision function
function collision(enemy, bullet){
return bullet.x + bullet.width >= enemy.x && bullet.x < enemy.x + enemy.width &&
bullet.y + bullet.height >= enemy.y && bullet.y < enemy.y + enemy.height;
}
//canvas functions
var img_enemy, img_player, img_bullet;
var sound_enemy_dead, sound_player_dead, sound_bullet, sound_game_start;
function preload(){
//load images
img_enemy = loadImage("images/enemy.png");
img_player = loadImage("images/player.png");
img_bullet = loadImage("images/bullet.png");
//load sounds
sound_enemy_dead = loadSound("sounds/enemy_dead.wav"); //Creative Commons 0 License – https://freesound.org/people/qubodup/sounds/332056/
sound_bullet = loadSound("sounds/bullet.wav"); //Creative Commons 0 License – https://freesound.org/people/cabled_mess/sounds/350924/
sound_player_dead = loadSound("sounds/player_dead.wav"); //Creative Commons 0 License – https://freesound.org/people/n_audioman/sounds/276362/
sound_game_start = loadSound("sounds/game_start.wav") //Creative Commons 0 License – https://freesound.org/people/GameAudio/sounds/220209/
//adjust sounds volumes if necessary
sound_bullet.setVolume(0.2);
}
//Sensor Value Input from Arduino
//var sensor1; // variables for each of my incoming sensor values
//var sensor2;
function draw(){
fill(255);
clear();
background("#000");
text("score : " + score, 10, 10);
fill(player.color);
var newValue = map(sensor1, 0, 1023, 0, width -40);
player.x = newValue;
var button = map(sensor2, 0, 1023, 0, 6);
/*
//Movement of player ////////////////////////////////////
if(newValue){
if(player.x-5 >= 0)
player.x -= 5;
else
player.x = 0;
}
if(keyIsDown(RIGHT_ARROW)){
if(player.x + 5 <= canvasWidth-player.width)
player.x += 5;
else
player.x = canvasWidth – player.width;
}*/
if(button){
bullets.push(Bullet({}));
sound_bullet.play();
print("I am shooting");
}
player.draw();
bullets = bullets.filter(function(bullet){
return bullet.active;
});
bullets.forEach(function(bullet){
bullet.update();
bullet.draw();
});
if(Math.random()<0.05){
enemies.push(Enemy({}));
}
enemies = enemies.filter(function(enemy){
return enemy.active;
});
enemies.forEach(function(enemy){
enemy.update();
enemy.draw();
});
bullets.forEach(function(bullet){
enemies.forEach(function(enemy){
if(collision(enemy, bullet)){
enemy.active = false;
bullet.active = false;
score++;
sound_enemy_dead.play();
}
});
});
enemies.forEach(function(enemy){
if(collision(enemy, player)){
enemy.active = false;
noLoop();
sound_player_dead.play();
textSize(40);
text("GAME OVER", 180, 200);
}
});
}
///////////////////////////////////////////Serial stuff
//all my callback functions here:
//callback functions are useful for giving feedback
function serverConnected(){
console.log('connected to the server');
}
function portOpen(){
console.log('the serial port opened!');
}
//THIS IS WHERE WE ACTUALLY RECEIVE DATA!!!!!!
//make sure you're reading data based on how you're sending from arduino
function serialEvent(){
//THIS READS BINARY – serial.read reads from the serial port, Number() sets the data type to a number
// inData = Number(serial.read()); //reads data as a number not a string
//THIS READS ASCII
inData = serial.readLine(); //read until a carriage return
//best practice is to make sure you're not reading null data
if(inData.length > 0){
//split the values apart at the comma
var numbers = split(inData, ',');
//var numbers = inData;
//set variables as numbers
sensor1 = Number(numbers[0]);
sensor2 = Number(numbers[1]);
console.log(sensor1 + ", " + sensor2);
}
}
function serialError(err){
console.log('something went wrong with the port. ' + err);
}
// get the list of ports:
function printList(portList) {
// portList is an array of serial port names
for (var i = 0; i < portList.length; i++) {
// Display the list the console:
print(i + " " + portList[i]);
}
}
view raw Game.js hosted with ❤ by GitHub

Leave a comment