I had a really fun time exploring the serial communication between Arduino and Processing this week! My project was inspired by the R, G, B color mapping on Arduino buttons, and without further ado, let me explain what I did.
💡 idea
I wanted to figure out a way, in which I could use my Arduino as a joystick for the Processing game. I started off with some LEDs and a potentiometer, but then decided that I would like to try something different than what we did in class last Wednesday. After that, I wired three buttons on the breadboard, and the colors of the buttons immediately reminded me of the (R, G, B) color mapping. I decided to create a movement game and use my buttons as a joystick for moving whatever I have in my Processing console.
When a player starts the Processing sketch, they will see a rectangle on the console, and whenever each button is pressed, the rectangle changes color and moves to a particular side of the screen. The player’s score increments if the rectangle “hits” the side of the screen.
🛠 process
One of the main challenges while implementing this game was to figure out a way to transfer multiple serial communication bits into Processing. At first, I thought I would create an array of bits that occur while pressing the buttons. However, as I was exploring this idea it seemed like I was overcomplicating it, and then I just tried sending a different type of serial message each time a different button is pressed. For example, if the red button is pressed, I send “1”; if the blue one is pressed, I send “2”, and so on.
After reading this serial communication from my Processing, I created a boolean variable to track which button is pressed. For each boolean variable, I then created corresponding code lines to run throughout the game to move the rectangle. When the rectangle reaches the end of the screen, it reappears on the console, and the game continues until they eventually get tired of playing 😅. Right now, there is no way to stop or restart the game without closing the program, but it could be something to think about as a next step.
🎲 demo
Arduino code:
int buttonR = 2; int buttonB = 4; int buttonG = 7; int prevRState = 0; int prevGState = 0; int prevBState = 0; void setup() { // put your setup code here, to run once: pinMode(buttonR, INPUT); pinMode(buttonG, INPUT); pinMode(buttonB, INPUT); Serial.begin(9600); } void loop() { // getting digital communication from buttons int buttonRState = digitalRead(buttonR); int buttonGState = digitalRead(buttonG); int buttonBState = digitalRead(buttonB); // read if the buttons are pressed int valueR = digitalRead(buttonR); int valueG = digitalRead(buttonG); int valueB = digitalRead(buttonB); // output for debugging Serial.print(valueR); Serial.print(valueG); Serial.print(valueB); if (buttonRState == 1 && prevRState == LOW){ // send values if buttons are pressed Serial.write(valueR); } if (buttonGState == 1 && prevGState == LOW){ // send values if buttons are pressed Serial.write(valueG+1); } if (buttonBState == 1 && prevBState == LOW){ // send values if buttons are pressed Serial.write(valueB+2); } // track button states prevRState = buttonRState; prevGState = buttonGState; prevBState = buttonBState; }
Processing code:
import processing.serial.*; // importing from library Serial port; // creating a serial port object int numBtns = 3; // number of buttons int locX, locY; // position of each rectangle int rectW, rectH; // width and height of each rectangle int value = 0; // passed value boolean isRed, isGreen, isBlue = false; // keep track of colors int numCollide; // keep track of collisions void setup(){ size(500, 500); rectMode(CENTER); locX = 250; locY = 250; rectW = 100; rectH = 100; numCollide = 0; //printArray(Serial.list()); // debugging port = new Serial(this, Serial.list()[1], 9600); // initializing the port } void draw(){ background(255); // initializing the game rect(locX, locY, rectW, rectH); displayScore(); // green mode if (isGreen == true){ rect(8, 250, rectW-80, height); locX-=5; } // red mode if (isRed == true){ rect(490, 250, rectW-80, height); locX+=5; } // blue mode if (isBlue == true){ rect(250, 10, width, rectH-80); locY-=5; } // start again reStart(); } void serialEvent(Serial port){ // reading from the port value = port.read(); // change to red if (value == 1){ fill(255, 0, 0); isRed = true; isBlue = false; isGreen = false; } /// change to green if (value == 2){ fill(0, 255, 0); isRed = false; isBlue = false; isGreen = true; } // change to blue if (value == 3){ fill(0, 0, 255); isRed = false; isBlue = true; isGreen = false; } } // restart each time the rectangle is caught void reStart(){ if (locX==-rectW || locY == -rectH || locX == width+rectW){ numCollide++; locX = 250; locY = 250; } } // display the instructions and the score void displayScore(){ textAlign(CENTER); push(); textSize(16); fill(0); text("Press any arduino button to start!", width/2, height-100); pop(); push(); textSize(32); fill(0); text("Score: " + numCollide, width/2, height-50); pop(); }
Be careful doing a serial.print for debugging when you’re doing serial communication since all of this gets sent over the serial bus. This will create errors in Processing and things won’t work consistently, if at all.