Object Lab 4: Serial Communication

This may take the cake for the most frustrating lab yet. I thought I knew how to code in JavaScript, but no, p5.js was out to prove me wrong. I could get approximately nothing to do what I wanted. So, I suppose let’s start at the start, and go forward from there.

The first part of the lab asked us to make sure that the arduino was able to take information from two analog inputs and send it (via serial) to p5.js. This whole process is a little non-intuitive for me because you have to actually use serial.print within the arduino to send it to p5.js, but you can’t open the serial monitor. (Serial can only be used by one application at a time, so either the p5.serial.control app or the arduino serial monitor.) Then, you have to use console.log within p5.js to make sure that you are receiving correctly. The proper format is to separate the values from the two potentiometers by a comma, then have a line break at the end of each reading (450, 220 /n). P5 can read this in (as a string), then stores it in an array. Below is the schematic for my circuit and a video of my p5 console printing out the values the arduino sent via serial.

IMG-1567

The next step was getting p5 to talk back to the arduino, which is pretty simple. From the p5 side, it is as easy as serial.write(); In arduino, I included an if statement to make sure that there was actually data coming in from the serial communication. If there is and it is greater than 0, the light on pin 9 flashes. Here is a video of the light flashing when I push the key “R”. The write is included in my keypressed function, which only looks for the key R, so the light only flashes when R is pressed.

Finally, I needed to use p5 to make a game. I thought of several ideas and made some sketches before finally settling on the idea of a maze game. I wanted the user to navigate a ball through a maze to the finish. Easy, right?

No. Not easy at all. Turns out that adding physics in p5 was going to take a LOT of lines of code. So basically, making the ball (controlled by the potentiometers) bounce off the walls of the maze was way too much. So, I changed my mind and decided to make a drawing game, where the user drew a path using the ball to a final destination. After several hours of work, I got to the point where I could get p5 to eternally draw a rectangle that followed the ball around. Not at all the point. The issue here is that the draw loop is on eternal repeat, so it updates the position of the rectangle every time you move the sensors. I couldn’t figure out a place to put a boolean statement that made it so that the rectangle was only drawn when the key was pressed and STAYED in that location. Very frustrating. Then, I decided I would make a game where all of the rectangles would change into different colors when you clicked on them, and the point of the game would be to make all the rectangles the same color. (P.S. by clicked, I mean hovered over them and hit the “R” key.) Well, the fill command changes the colors of all the rectangles, not just one, so they all change color simultaneously, making the game really easy. I figured out how to make each rectangle a different color using an array of colors and a for loop, but then the nightmare that was trying to figure out which color it is so you could change it on keypress defeated me. Then, I finally landed on the current game (which sucks, but you know what, I’ll take what I get).  The point of the game is to find the rectangle that makes all the other rectangles disappear. They all change color together, but they all turn different colors. Here is a video of my rather lame game:

And here is the code that makes it run from p5:


/*
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 = '/dev/cu.usbmodemFA131'; //fill in with YOUR port
var sensor1;
var sensor2;
var pot1;
var pot2;
var placeR = 0;
var placeR2 = 0;
var counter = 1;
var circlesize = 50;
var drawRect = false;
function setup() {
createCanvas(600, 600);
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('purple');
var circlesize = 50;
//make circle follow potentiometers
pot1 = map(sensor2, 0, 255, 0+circlesize/2, width-circlesize/2);
pot2 = map(sensor1, 0, 255, height-circlesize/2, 0+circlesize/2);
ellipse(pot1, pot2, circlesize);
//make many rectangles that all change color
rect(0, 0, 50, 50);
rect(100, 100, 50, 50);
rect(200, 200, 50, 50);
rect(300, 300, 50, 50);
rect(135, 450, 50, 50);
rect(200, 300, 50, 50);
rect(300, 400, 50, 50);
rect(500, 200, 50, 50);
if(placeR < 170 && placeR > 130 && placeR2<480 && placeR2 >440){
fill("black");
}
if(placeR < 230 && placeR > 180 && placeR2<330 && placeR2 >280){
fill("green");
}
if(placeR<330 && placeR >280 && placeR2<430 && placeR2 >380){
fill("blue");
}
if(placeR<530 && placeR >480 && placeR2<230 && placeR2 >180){
noStroke();
fill("purple");
}
if(placeR < 140 && placeR > 80 && placeR2<140 && placeR2 >80){
fill("orange");
}
if(placeR < 230 && placeR > 180 && placeR2<230 && placeR2 >180){
fill("white");
}
if(placeR < 330 && placeR > 280 && placeR2<330 && placeR2 >280){
fill("pink");
}
if(placeR < 80 && placeR > 0 && placeR2<80 && placeR2 >0){
fill("grey");
}
}
function getLocation(){
placeR = pot1;
placeR2 = pot2;
}
//This is a function that sends the key stroke to the Arduino
function keyPressed(){
drawRect = false;
if(key=='R'){
serial.write(key);
console.log(key);
fill("red");
placeR = pot1;
placeR2 = pot2;
drawRect = true;
counter++;
console.log(pot1);
console.log(pot2);
}
}
//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
var inString = serial.readLine();
//print(inString);
if(inString != ""){
var stringArray = split(inString, ",");
sensor1 = Number(stringArray[0]);
sensor2 = Number(stringArray[1]);
}
}
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

labFour.js

hosted with ❤ by GitHub

And from arduino:


int pot = 0; //potentiometer variable
int pot2 = 0;
int incoming = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // initialize serial
}
void loop() {
// put your main code here, to run repeatedly:
pot = analogRead(A0);
pot2 = analogRead(A1);
int lightVals = map(pot, 0, 1023, 0, 255);
int light2Vals = map(pot2, 0, 1023, 0, 255);
Serial.print(lightVals);
Serial.print(",");
Serial.println(light2Vals);
delay(1);
analogWrite(9, lightVals);
analogWrite(10, light2Vals);
if(Serial.available()>0){
incoming = Serial.read();
if(incoming>0){
analogWrite(9,255);
}
}
}

view raw

labFour.ino

hosted with ❤ by GitHub

I think p5 isn’t my very favorite coding language. Between the epic lagginess of my computer and the eternally looping draw function, this was a struggle. Very fun premise, but I think given more time and a different library, I could probably do better.

Leave a comment

Design a site like this with WordPress.com
Get started