B. CONCEPTION AND DESIGN:
The concept of this project is based on constant communication between two players. From our previous project during the midterm, one of the criticisms we got was the limited interactivity. We had created a trash can that reacts to a piece of trash being thrown away, but that had mostly been the extent to which the interaction would reach. Building on this past experience, we wanted to create a project that would require a stream of interactions while using it. This prompted us to create a two-player game in which the players were solely reliant on one another. This idea was loosely based on the existing video game “Keep Talking and Nobody Explodes”. In this game, one player has a bomb with several components, including a timer counting down to its detonation, on their screen. The other player, on their screen, has a manual on how to defuse this bomb. The instructions for defusing the bomb vary by game, but the best way to survive is to clearly communicate with the other player. For our project, we used this concept of puzzles and communication, and put our own spin on it. We wanted to give each player a similar experience to each other, so rather than giving one person the buttons, and the other person the instructions, we decided to give both players one set of instructions and one set of buttons each. From this design, we created the basic objective of helping an alien break out of a facility with your partner. Both players have a screen that gives a series of 3 puzzles and a controller that is used to complete the puzzles. However, the players don’t get to see their own screens. Instead, they are given the other player’s screens. In order to finish the game, the two players must describe the obstacles that they see and the controls that they have to figure out a way through each puzzle.
Since this was a relatively complicated concept, to see if this idea was feasible, my partner and I did a preliminary user testing using paper and simple drawings. Using these basic materials, we got feedback on our initial ideas for the puzzles and their difficulty. At first our puzzles had been confusing, and the controls for each puzzle had been ambiguously connected. To remedy this, we prioritized using unique sensors and controls that would differ depending on the game. During the in-class user testing, we didn’t have a fully fleshed out code and game for people to test, so we simulated it for them like the preliminary user testing. Since at this point the game was more than a concept, we got more detailed feedback about the user experience. Our classmates suggested that we include some kind of indication or feedback for the other player, so they could tell if what they were doing was affecting the game. On one hand, adding a feature like this would make the game more engaging and user friendly, but on the other hand it could also take away from the core of communication. If the other player could tell that their actions were making a difference, then the communication would be less prioritized. However, we also realized that it was quite easy for the players to just press random buttons and progress to the next game without figuring out the answer. This was a fatal flaw, so we had to redesign and rethink some of our puzzle ideas to work around this issue. Additionally, we didn’t want to help guide the users through the whole game, so we decided to add basic directions for each puzzle to get them started. Once we had a more finalized controller and working game code, we conducted another user testing round to file down any sharp edges. During this round, we found that users had been able to see the other person’s controls, which had given them hints to how to solve the puzzles, so we decided to create a physical barrier high enough to block players from viewing the other’s controls, but also low enough to where they could speak to each other naturally.
C. FABRICATION AND PRODUCTION:
We purposely created our puzzle concepts around a specific controller or sensor to make the coding process go much smoother. If we kept the controller options in mind during the ideation, we were able to work on a more realistic scale based on our abilities and previous learning. For controller 1, we designed a puzzle based on 4 buttons, a slider sensor, and a joystick each. For controller 2, we designed a puzzle based on 4 toggle switches, a keypad, and a potentiometer. By basing the puzzles off of the controller it would be connected to, we were able to work within the constraints of our knowledge and not overestimate our abilities.
Before we could begin coding the games, we needed the controllers to be ready and wired so that the coding wouldn’t be done blindly. This was the first part of the fabrication process. We knew that we wanted to create a box with the controller components embedded in it, but we also needed one with a removable lid for easy wiring access. We figured laser cutting a box would be the easiest way to do this, especially since we needed to make two different controllers. We looked up a template for a box with a hinged lid, but all of the ones we found were locked behind a paywall, so we just improvised on cuttle.xyz by using the template as a guide. The initial cardboard cut had gone successfully, besides a little radius adjustment to make the hinge stronger, but we realized we still needed to make the holes in the lid for the sensors and controls. We assembled all the components and measured them to scale them on the digital file. After getting the first controller top measured out, we couldn’t find any more cardboard pieces and decided to just print on 5mm wood straight away. Luckily everything went smoothly for this controller. All the pieces fit together and the controller components fit inside the holes we measured. However, we soon realized that using 5mm for the second controller would pose a problem for the potentiometer because of its thickness. So instead, we printed on 3mm wood for the second controller. The issue with this is that the original design was made for 5mm wood, which means the gaps for the box corners to fit together had extended a few millimeters further than intended. Since we didn’t want to waste more wood, we just rolled with the mistake we made and glued it all together regardless.
After finishing the actual fabrication of the controller boxes, we had to wire the pieces to the arduino board. This was relatively easy, as there weren’t any pieces too complicated to wire, but it took a lot of time and tape to sort out all the wires where they needed to go. The biggest obstacle in this step was working around the cardboard mounts we created for some of the controls to sit on. These mounts were essential to making the controls fit against the lid while also letting us open it, so we had to navigate the wires through them within the box. We had to get a little creative about the placement and construction of these mounts in order to also connect the arduino board to the computer.
After finally completing the controllers, we started to work on the individual puzzles in processing. When we first began to code the game, we were suggested to code the three games in separate sketches as if they were meant for three different projects, then we could figure out how to connect them together for the final product. This helped break the task of creating a fully developed game down into more doable steps. Instead of creating the graphics of the games all in processing, we opted to draw different screens using autodesk on the ipad. This allowed us to easily control different aspects of the puzzles without too much confusion or difficulty. Our knowledge of coding was quite minimal, so doing as much as we could to minimize the complexity of the code was crucial in making this project work. This section of producing the project took a lot of trial and error. Many files were revised and edited to make sure everything would fit seamlessly. For example, in one of the original game backgrounds, we were told that visual hints had been ambiguous or unclear during a user testing. So we had to go back into the file to edit it and export it again to replace it. We had a similar approach with the code where something didn’t quite work the way we intended, so we found ways around it with the help of learning assistants or ChatGPT when learning assistants werent available. For example, one of the puzzles required several rectangles’ opacity to be commanded by two independent button presses simultaneously. So, one button press would make a row of 4 rectangles disappear, while another would make a column or 4 rectangles disappear, one of which would also be commanded by the previous button and vice versa. For this, we had coded all the individual rectangles and tried several rounds of commands to arrange it. It was difficult though, like we had all the components but didn’t know how to put them together. Finally, we put it through chatGPT and it just arranged all the opacities manually, which I had thought of originally but thought it would be too tedious. This was the most difficult puzzle to work on, but the most difficult part of coding was putting it all together. Like mentioned above, we had to ask for help before even starting because we didn’t know how to approach doing this. We were told to use if functions to track ‘screen’ changes. This way we would be able to transition between different ‘screens’ and puzzles through specific fulfillments. Once we had figured out the basic outline of how to transition, it was mostly copying and pasting the individually coded pieces onto one big processing sketch. The worst part was keeping track of the curly brackets due to all of the if statements. Combining the variables and files was a bit of an issue though, because we had coded the original pieces using different names for the universal variables. In hindsight, we should’ve used the same variable names throughout the individual coding because we ended up having to rename a lot of things when combing.
D. CONCLUSIONS:
Our goal was to initiate a constant stream of communication between two people which would help them develop their verbal explanation skills. I think based on user testing this had been achieved because of the successful communication we saw to get through the puzzles. We noticed that the users would often struggle in the beginning, but get better and better at communicating as the game progressed. It may have also been due to the difficulty of the first puzzle compared the the other two, but we definitely saw an improvement in ease of discussion. Our presentation of the project was a little rocky, however and pointed out a few things to us. The users found it restrictive to communicate in english, which had been the primary language of the game, and weren’t able to be as descriptive as they wanted to. This is definitely something that we kind of overlooked when making it, and it also highlighted how visually reliant the games were. We also hadn’t finished coding the sound in yet, which emphasized the visual aspect even more. For future endeavors, it would be a good idea to keep in mind the audience and potential users when designing the game. It was interesting to see how different players had varying levels of chemistry when it came to communicating though. Some partners ‘clicked’ more than others and finished the game more smoothly compared to some. I think this observation could also be a good point to expand upon if a project like this were to arise again.
E. DISASSEMBLY:
F. APPENDIX
Arduino Code – Purple Controller:
Arduino Code – Red Controller:
Processing Code – Purple Controller:
//imported libraries from processing
import gifAnimation.*;
Gif complete;
import processing.serial.*;
import processing.sound.*;
SoundFile intro;
SoundFile task;
SoundFile end;
SoundFile numb;
SoundFile beam;
SoundFile gopen;
SoundFile gclose;
Serial serialPort;
int NUM_OF_VALUES_FROM_ARDUINO = 6; /* CHANGE THIS … */
/* This array stores values from Arduino */
int arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO];
//keycode
PImage cells;
PImage al;
PImage text1;
//processing
String keyString = "";
int r15 = 250;
int r16 = 250;
int r17 = 250;
int r18 = 250;
int r25 = 250;
int r26 = 250;
int r27 = 250;
int r28 = 250;
int r35 = 250;
int r36 = 250;
int r37 = 250;
int r38 = 250;
int r45 = 250;
int r46 = 250;
int r47 = 250;
int r48 = 250;
//togglegate
PImage bg;
PImage alex;
PImage text2;
int g1;
int g2;
int g3;
int g4;
//starpower
PImage star;
PImage text3;
PImage title;
PImage win;
PImage pinstruct;
long time;
int screen = 0;
void setup() {
//fullScreen();
size(1440, 900);
//frameRate(24);
printArray(Serial.list());
serialPort = new Serial(this, "/dev/cu.usbmodem11201", 9600);/////////
//keycode
cells = loadImage("cells.png");
al = loadImage("bruh.PNG");
text1 = loadImage("keytext.png");
//togglegate
bg = loadImage("bg.png");
alex = loadImage("al.png");
text2 = loadImage("gatetext.png");
g1 = 50;
g2 = 700;
g3 = 700;
g4 = 50;
//starpower
star = loadImage("starpower.png");
text3 = loadImage("startext.png");
complete = new Gif(this, "complete.gif");
complete.loop();
title = loadImage("title.png");
win = loadImage("DONE.png");
imageMode(CORNER);
pinstruct = loadImage("pinstruct.png");
intro = new SoundFile(this, "intro.mp3");
task = new SoundFile(this, "completed.mp3");
end = new SoundFile(this, "win.mp3");
numb = new SoundFile(this, "numbers.mp3");
gopen = new SoundFile(this, "gateopen.mp3");
gclose = new SoundFile(this, "gateclose.mp3");
beam = new SoundFile(this, "beam.mp3");
intro.play();
}
void draw() {
getSerialData();
//title
if (screen == 0) {
image(title, 0, 0, width, height);
image(pinstruct, 300, 50);
if (!intro.isPlaying()) {
intro.loop();
}
//GAME 1
if (arduino_values[0] != 0) {
screen = 1;
if (intro.isPlaying()) {
intro.pause();
}
println("here");
}
} else if (screen == 1) {
background(150, 100, 255);
image(cells, 0, 0);
image(al, 1060, 625, 125, 125);
noStroke();
fill(0, r15);
rect(310, 100, 237, 170);
fill(0, r16);
rect(530, 100, 237, 170);
fill(0, r17);
rect(760, 100, 237, 170);
fill(0, r18);
rect(990, 100, 270, 170);
fill(0, r25);
rect(310, 270, 227, 160);
fill(0, r26);
rect(540, 270, 227, 165);
fill(0, r27);
rect(760, 270, 227, 165);
fill(0, r28);
rect(990, 270, 270, 165);
fill(0, r35);
rect(310, 430, 225, 170);
fill(0, r36);
rect(545, 430, 210, 170);
fill(0, r37);
rect(760, 430, 237, 170);
fill(0, r38);
rect(990, 430, 270, 170);
fill(0, r45);
rect(315, 595, 225, 160);
fill(0, r46);
rect(535, 600, 225, 160);
fill(0, r47);
rect(760, 600, 225, 160);
fill(0, r48);
rect(990, 600, 270, 160);
if (arduino_values[0] != 0 ) {
keyString += arduino_values[0];
numb.play();
}
if (keyString.length() > 0) {
char lastChar = keyString.charAt(keyString.length() - 1);
//ChatGPT arranged this section
if (lastChar == '1') {
r25 = 250;
r26 = 250;
r27 = 250;
r28 = 250;
r35 = 250;
r36 = 250;
r37 = 250;
r38 = 250;
r45 = 250;
r46 = 250;
r47 = 250;
r48 = 250;
r15 = 0;
r16 = 0;
r17 = 0;
r18 = 0;
} else if (lastChar == '2') {
r15 = 250;
r16 = 250;
r17 = 250;
r18 = 250;
r35 = 250;
r36 = 250;
r37 = 250;
r38 = 250;
r45 = 250;
r46 = 250;
r47 = 250;
r48 = 250;
r25 = 0;
r26 = 0;
r27 = 0;
r28 = 0;
} else if (lastChar == '3') {
r15 = 250;
r16 = 250;
r17 = 250;
r18 = 250;
r25 = 250;
r26 = 250;
r27 = 250;
r28 = 250;
r45 = 250;
r46 = 250;
r47 = 250;
r48 = 250;
r35 = 0;
r36 = 0;
r37 = 0;
r38 = 0;
} else if (lastChar == '4') {
r15 = 250;
r16 = 250;
r17 = 250;
r18 = 250;
r25 = 250;
r26 = 250;
r27 = 250;
r28 = 250;
r35 = 250;
r36 = 250;
r37 = 250;
r38 = 250;
r45 = 0;
r46 = 0;
r47 = 0;
r48 = 0;
} else if (lastChar == '5') {
r16 = 250;
r17 = 250;
r18 = 250;
r26 = 250;
r27 = 250;
r28 = 250;
r36 = 250;
r37 = 250;
r38 = 250;
r46 = 250;
r47 = 250;
r48 = 250;
r15 = 0;
r25 = 0;
r35 = 0;
r45 = 0;
} else if (lastChar == '6') {
r15 = 250;
r17 = 250;
r18 = 250;
r25 = 250;
r27 = 250;
r28 = 250;
r35 = 250;
r37 = 250;
r38 = 250;
r45 = 250;
r47 = 250;
r48 = 250;
r16 = 0;
r26 = 0;
r36 = 0;
r46 = 0;
} else if (lastChar == '7') {
r15 = 250;
r16 = 250;
r18 = 250;
r25 = 250;
r26 = 250;
r28 = 250;
r35 = 250;
r36 = 250;
r38 = 250;
r45 = 250;
r46 = 250;
r48 = 250;
r17 = 0;
r27 = 0;
r37 = 0;
r47 = 0;
} else if (lastChar == '8') {
r15 = 250;
r16 = 250;
r17 = 250;
r25 = 250;
r26 = 250;
r27 = 250;
r35 = 250;
r36 = 250;
r37 = 250;
r45 = 250;
r46 = 250;
r47 = 250;
r18 = 0;
r28 = 0;
r38 = 0;
r48 = 0;
} else {
// Default case when none of the above conditions are met
r15 = 250;
r16 = 250;
r17 = 250;
r18 = 250;
r25 = 250;
r26 = 250;
r27 = 250;
r28 = 250;
r35 = 250;
r36 = 250;
r37 = 250;
r38 = 250;
r45 = 250;
r46 = 250;
r47 = 250;
r48 = 250;
}
}
if (keyString.length() > 0 &&
keyString.charAt(keyString.length() - 1) == '8' &&
keyString.charAt(keyString.length() - 2) == '4') {
screen = 2;
task.play();
}
} else if (screen == 2) {
image(complete, 0, 0, width, height);
image(pinstruct, 300, 50);
}
//GAME 2
if (screen == 2) {
if (arduino_values[0] != 0 && arduino_values[0] != 8) {
screen = 3;
}
} else if (screen == 3) {
image(bg, 0, 0, width, height);
image(alex, 0, 0, width, height);
image(text2, 50, 800);
rectMode(BOTTOM);
fill(205);
noStroke();
if (arduino_values[1] == 0) {
rect(500, 750, 450, g1);
g1 = 700;
} else {
rect(500, 750, 450, g1);
g1 = 50;
}
if (arduino_values[2] == 0) {
rect(650, 750, 600, g2);
g2 = 50;
} else {
rect(650, 750, 600, g2);
g2 = 700;
}
if (arduino_values[3] == 0) {
rect(800, 750, 750, g3);
g3 = 50;
} else {
rect(800, 750, 750, g3);
g3 = 700;
}
if (arduino_values[4] == 0) {
rect(950, 750, 900, g4);
g4 = 700;
} else {
rect(950, 750, 900, g4);
g4 = 50;
}
if (arduino_values[1] == 0 && arduino_values[2] == 1 &&
arduino_values[3] == 1 && arduino_values[4] == 0) {
screen = 4;
task.play();
}
} else if (screen == 4) {
image(complete, 0, 0, width, height);
image(pinstruct, 300, 50);
}
//GAME 3
if (screen == 4) {
if (arduino_values[0] != 0) {
screen = 5;
beam.play();
}
} else if (screen == 5) {
image(star, 0, 0, width, height);
image(text3, 50, 25);
if (!beam.isPlaying()) {
beam.loop();
}
rectMode(BOTTOM);
fill(255, 255, 0);
noStroke();
float h = map(arduino_values[5], 1023, 0, 780, 0);
rect(1275, 780, 1325, h);
if (arduino_values[5] >= 410 && arduino_values[5] <= 418) {
if (time == 0) {
time = millis();
} else {
if (millis() - time > 3000) {
screen = 6;
if (beam.isPlaying()) {
beam.pause();
}
end.play();
}
}
}
} else if (screen == 6) {
image(win, 0, 0);
}
}
void getSerialData() {
while (serialPort.available() > 0) {
String in = serialPort.readStringUntil(10); // 10 = '\n' Linefeed in ASCII
if (in != null) {
print("From Arduino: " + in);
String[] serialInArray = split(trim(in), ",");
if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) {
for (int i=0; i<serialInArray.length; i++) {
arduino_values[i] = int(serialInArray[i]);
}
println(keyString);
}
}
}
}
Processing Code – Red Controller:
//imported libraries from processing
import processing.sound.*;
import gifAnimation.*;
Gif complete;
import processing.serial.*;
SoundFile intro;
SoundFile cabinet;
SoundFile task;
SoundFile maze;
SoundFile end;
PImage bg;
PImage lock;
PImage unlock;
PImage text1;
PImage guard;
PImage exit;
PImage text2;
int x = 150;
int y = 750;
// Maze Template from ChatGPT and edited
int tileSize = 100;
int cols, rows;
int[][] grid = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
{1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1},
{1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
PImage ship;
PImage al;
PImage forest;
PImage text3;
PImage title;
PImage win;
PImage in;
long time;
Serial serialPort;
int NUM_OF_VALUES_FROM_ARDUINO = 7; /* CHANGE THIS … */
/* This array stores values from Arduino */
int arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO];
int screen = 0;
void setup() {
//fullScreen();
size(1440, 900);
frameRate(24);
printArray(Serial.list());
serialPort = new Serial(this, "/dev/cu.usbmodem1101", 9600);
lock = loadImage("lock.png");
unlock = loadImage("unlock.png");
bg = loadImage("bg.png");
text1 = loadImage("keytext.png");
guard = loadImage("guard.png");
exit = loadImage("exit.png");
text2 = loadImage("mazetext.png");
cols = 15;
rows = 9;
ship = loadImage("UFO.PNG");
al = loadImage("bruh.PNG");
forest = loadImage("Untitled 7.png");
text3 = loadImage("shiptext.png");
complete = new Gif(this, "complete.gif");
complete.loop();
title = loadImage("title.png");
win = loadImage("DONE.png");
in = loadImage("rinstruct.png");
imageMode(CORNER);
intro = new SoundFile(this, "intro.mp3");
cabinet = new SoundFile(this, "cabinet.wav");
task = new SoundFile(this, "completed.mp3");
maze = new SoundFile(this, "guard.mp3");
end = new SoundFile(this, "win.mp3");
intro.play();
}
void draw() {
getSerialData();
//title
if (screen == 0) {
image(title, 0, 0, width, height);
image(in, 300, 50);
println("screen=0");
if (!intro.isPlaying()) {
intro.loop();
}
//intro.play();
//GAME 1
if (arduino_values[0] == 0 || arduino_values[1] == 0 ||
arduino_values[2] == 0 || arduino_values[3] == 0) {
screen = 1;
if (intro.isPlaying()) {
intro.pause();
}
println("here");
}
} else if (screen == 1) {
image(bg, 0, 0, width, height);
image(lock, 0, 0, width, height);
image(text1, 250, 800);
if (arduino_values[1] == 0 && arduino_values[3] == 0) {
screen = 2;
cabinet.play();
time = millis();
}
} else if (screen == 2) {
if (millis() - time < 2000) {
image(unlock, 0, 0, width, height);
} else {
screen = 3;
task.play();
}
} else if (screen == 3) {
image(complete, 0, 0, width, height);
image(in, 300, 50);
}
/// GAME 2
if (screen == 3) {
if (arduino_values[0] == 0 || arduino_values[1] == 0 ||
arduino_values[2] == 0 || arduino_values[3] == 0) {
screen = 4;
}
} else if (screen == 4) {
background(255);
drawMaze();
imageMode(CENTER);
image(guard, 250, 150, 100, 100);
image(guard, 550, 550, 100, 100);
image(guard, 1150, 250, 100, 100);
image(guard, 850, 650, 100, 100);
image(exit, 1350, 750, 100, 100);
image(text2, 1150, 850);
image(al, x, y, 50, 50); // Adjust the position of the character image
// Maze Wall Barrier code edited by ChatGPT
if (arduino_values[4] > 1 && !checkCollision(x - 100, y)) {
x = x - 100;
delay(200);
}
if (arduino_values[4] < 1 && !checkCollision(x + 100, y)) {
x = x + 100;
delay(200);
}
if (arduino_values[5] < 1 && !checkCollision(x, y - 100)) {
y = y - 100;
delay(200);
}
if (arduino_values[5] > 1 && !checkCollision(x, y + 100)) {
y = y + 100;
delay(200);
}
if (x == 250 && y == 150) {
maze.play();
}
if (x == 550 && y == 550) {
maze.play();
}
if (x == 1150 && y == 250) {
maze.play();
}
if (x == 850 && y == 650) {
maze.play();
}
if (x == 1350 && y == 750) {
screen = 5;
task.play();
}
} else if (screen == 5) {
image(complete, width/2, height/2);
image(in, 700, 50);
}
//GAME 3
if (screen == 5) {
if (arduino_values[0] == 0 || arduino_values[1] == 0 ||
arduino_values[2] == 0 || arduino_values[3] == 0) {
screen = 6;
time = 0;
}
} else if (screen == 6) {
imageMode(CENTER);
image(forest, width/2, height/2);
image(ship, width/2, 550, 400, 400);
image(text3, 650, 850);
float m = map(arduino_values[6], 0, 1023, 0, width);
image(al, m, 525, 100, 100);
if (arduino_values[6] >= 555 && arduino_values[6] <= 595) {
if (time == 0) {
time = millis();// - time;
} else {
if (millis() - time > 3000) {
screen = 7;
}
}
} else {
time = 0;
}
} else if (screen == 7) {
image(win, width/2, height/2);
end.play();
}
}
//Maze template from ChatGPT
void drawMaze() {
noStroke();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (grid[i][j] == 1) {
fill(0); // Wall
} else {
fill(255); // Empty space
}
rect(j * tileSize, i * tileSize, tileSize, tileSize);
}
}
}
boolean checkCollision(int newX, int newY) {
int gridX = newX / tileSize;
int gridY = newY / tileSize;
return grid[gridY][gridX] == 1;
}
void getSerialData() {
while (serialPort.available() > 0) {
String in = serialPort.readStringUntil(10); // 10 = '\n' Linefeed in ASCII
if (in != null) {
//print("From Arduino: " + in);
String[] serialInArray = split(trim(in), ",");
if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) {
for (int i=0; i<serialInArray.length; i++) {
arduino_values[i] = int(serialInArray[i]);
}
}
}
}
}