Floating Cars Around the World

For this week’s project, I recycled my “Floating Cars” project to add a little twist to it. The idea is to change the background where the cars are floating by pressing a button from the Sparkfun Arduino deck.

This is achieved by getting Arduino to communicate with Processing by signaling any button presses which are then translated by a switch in the background image. I chose images of 3 cities (Paris, London and New York) because of their features as large economic hubs with generally dense traffic. Below is the final product.

The most challenging part was establishing an easy and efficient connection between Arduino and Processing. After multiple tries, I simplified my code for the Arduino to just send a value between 0 and 1 to Processing which then interprets it as a cue to change the background image.

Below is my code.

Processing Code

PImage []img=new PImage[3];
int image_index;
import processing.serial.*;
Serial myPort;
boolean buttonState=false;

int num = 500; // number of cars
Car[] myCars; // array for cars
boolean buttonPress;
int drive=0;

void setup() {
for (int i=0; i<3; i++){
img[0] = loadImage("london.jpg");
img[1] = loadImage("pariiis.jpg");
img[2] = loadImage("ny.jpg");
}
 
String portname= Serial.list()[3];
myPort= new Serial(this, portname, 9600);
myPort.clear();
myPort.bufferUntil('\n'); //print until the end of the line
 
size(500, 500);
smooth();
myCars = new Car[num]; 
for (int i =0;i<num;i++) {
myCars[i] = new Car();
}
}

void draw() {
//background(255);
image(img[image_index], 0, 0);
for (int i =0;i<num;i++) {
myCars[i].display();
myCars[i].go();
}
}

class Car {
color col;
int x;
int y;
int speed;

//constructor
Car () {
col = color(random(256), random(256), random(256), random(256));
//speed= s;
speed = int(random(1, 10));
if (random(1)>0.5) {
speed = -speed;
}
x = int(random(width));
y = int(random(height));
}

// methods
void display() {
// draw car as a box
noStroke();
fill(col);
rect(x, y, 20, 10);
ellipse(x+5, y+10, 5, 5);
ellipse(x+15, y+10, 5, 5);
}


void go() {
//speed=s;
x+= speed;
if (x>width && speed>0) {
x = -20;
}
if (x<0 && speed < 0) {
x = width+20;
}
}
}

void serialEvent(Serial myPort){ //no need to call in the function in the draw loop
String s = myPort.readStringUntil('\n');
s=trim(s); //remove any space
println(s);
if (s!=null){
int value[]=int(split(s,','));
if (value.length==1){
if (value[0]==1 && buttonState==false){
buttonState=true;
image_index+=1;
image_index %=3;
}
if (value[0]==0){
buttonState=false;
}
}
}
 
}

Arduino Code

const int Switch=8;
const int ledPin=2;
boolean buttonPress=false;

void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 pinMode(Switch, INPUT);
 pinMode(ledPin, OUTPUT);
 Serial.println("0");
}

void loop() {
 // put your main code here, to run repeatedly:

if (digitalRead(8)==HIGH){
 buttonPress=true;
 Serial.println(1);
 }
 else{
 buttonPress=false;
 Serial.println(0);
 }

}