For this week’s assignment, we were asked to create a project that combines both Arduino and Processing by allowing them to perform a serial “handshake”.
To do this, I used my OOP processing project and replaced the mouse interaction with a rotary potentiometer. This was, for the most part, easy to do. We completed an in-class example where we controlled a basic ellipse shape across the X-axis as well, and I was surprised that I could apply the same simple code (with a few minor tweaks) to a processing sketch that was a bit more complex, without breaking the code.
Here is a video demonstration:
I created a box for the potentiometer, in an attempt to make it a little bit more visually appealing.
Here’s my code:
Arduino:
void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println('0'); } void loop() { if(Serial.available()>0){ char inByte=Serial.read(); int sensor = analogRead(A0); delay(0); Serial.println(sensor); } }
Processing:
//arrayList to hold all stars ArrayList<Star> stars = new ArrayList<Star>(); import processing.serial.*; Serial myPort; int xPos=0; int State = 0; //instantiate new moon object Moon moon = new Moon(); int modifier; float raindrop; int red, green, blue; void setup() { size(585,430); background(0); raindrop= 0; printArray(Serial.list()); String portname=Serial.list()[1]; println(portname); myPort = new Serial(this,portname,9600); myPort.clear(); //myPort.bufferUntil('\n'); //generate 30 random stars for (int i = 0; i < 30; i++) { //adds them to star ArrayList for easy access stars.add(new Star()); } } void draw() { //move raindrop down screen raindrop = raindrop + 4; //speed //if raindrop falls below canvas, reset to zero if (raindrop >= height) raindrop = 0; //map xPos to rgb values of background red = int(map(xPos, 0, width, 83, 0)); green = int(map(xPos, 0, width, 157, 0)); blue = int(map(xPos, 0, width, 253, 0)); modifier = int(map(xPos, width/2, width, 29, 0)); background(red, green, blue); if (xPos > width/2) { for (int i = 0; i < stars.size() - modifier; i++) { Star s = stars.get(i); s.drawStar(); } } moon.update(); moon.drawMoon(); //rainfall fill(211,211,211); rect(10, raindrop, 2, 5); rect(50, raindrop+20, 2, 5); rect(80, raindrop, 2, 5); rect(110, raindrop+100, 2, 5); rect(140, raindrop+150,2, 5); rect(180, raindrop-200, 2, 5); rect(200, raindrop-150, 2, 5); rect(240, raindrop-50, 2, 5); rect(240, raindrop, 2, 5); rect(300, raindrop+20, 2, 5); rect(440, raindrop, 2, 5); rect(440, raindrop, 2, 5); rect(550, raindrop+100, 2, 5); rect(530, raindrop-250, 2, 5); rect(530, raindrop-200, 2, 5); rect(580, raindrop-300, 2, 5); rect(300, raindrop-400, 2, 5); rect(140, raindrop-350, 2, 5); rect(400, raindrop-300, 2, 5); rect(400, raindrop-250, 2, 5); rect(400, raindrop-200, 2, 5); rect(550, raindrop, 2, 5); //this part of my code uses & adapts from "skyline" by Shiwen Qin on OpenProcessing //building 1 fill(250); rect(35,255,5,55); fill(250); rect(40,250,40,60); fill(51, 51, 51); quad(80,250,80,310,95,310,95,260); fill(106,106,71); for (int y=258; y<310; y+=8){ fill(106,106,71); rect(36,y,2,2); } for (int y=258; y<300;y+=10){ for(int x=44; x<78; x+=10){ fill(106,106,71); rect(x,y,3,3); } } //building 2 fill(51, 51, 51); rect(93,265,40,60); for (int y=270; y<300;y+=10){ for(int x=96; x<130; x+=10){ fill(165,160,102); rect(x,y,5,3); } } //building 3 fill(220,220,220); rect(150,225,15,120); fill(220,220,220); rect(164,215,10,140,6); fill(169,169,169); rect(166,218,2,140,7); fill(105,105,105); arc(170,250,70,70,-PI/2,0); rect(170,250,35,140); fill(192,192,192); arc(170,250,60,60,-PI/2,0); rect(170,250,30,140); fill(192,192,192); arc(170,250,40,40,-PI/2,0); rect(170,250,20,140); //fourth building fill(250); fill(250); rect(235,225,5,75); fill(250); rect(240,225,40,80); fill(106,106,71); for (int y=258; y<310; y+=8){ fill(106,106,71); rect(236,y,2,2); } for (int y=258; y<300;y+=10){ for(int x=244; x<278; x+=10){ fill(106,106,71); rect(x,y,3,3); } } // fifth building fill(102, 102, 102); rect(300,185,36,120); fill (51, 51, 51); rect (295, 185, 5, 120); rect (305, 185, 5, 120); //sixth building fill(51, 51, 51); rect(376,172,2,10); rect(375,180,3,15); quad(350,206,350,316,380,316,380,190); fill(102, 102, 102); quad(375,198,375,316,405,316,405,215); fill(51, 51, 51); rect(387,215,1,115); rect(396,215,1,115); //seventh building fill(51, 51, 51); rect(430,200, 40 ,150); fill(250); rect(430,200, 40 ,5); rect(470,200, 2 ,150); //seventh building .2 fill(192,192,192); rect(490,200, 40 ,150); fill(250); rect(490,200, 40 ,5); rect(500,200, 2 ,150); //eighth building fill(51, 51, 51); rect(225,225,10,120); rect(270,225,10,120); //building 8 arc(540,190,70,70,-PI*4/6,-PI*1/6,CHORD); quad(523,159,523,325,570,325,570,172); for(int y=170;y<325 ;y+=5){ fill(106,106,71); quad(523,y,570,y+2,570,y+4,523,y+2); } //ninth building fill(51, 51, 51); quad(585,165,615,155,620,325,585,325); fill(31,30,72); triangle(614,155,622,158,619,325); for(int y=210;y<325 ;y+=5){ fill(106,106,71); quad(585,y,615,y-1,615,y+1,585,y+2); } for(int y=210;y<325 ;y+=5){ fill(64,64,34); quad(615,y-1,621,y,621,y+2,615,y+1); } //shore fill(69, 137, 163); rect(0,310,900,400); //mangroves, forloop for(int x=0;x<900;x+=20){ mangroves(x,310,10,10,3,28,5,255); //varying parameters for mangroves mangroves(x+10,305,8,8,6,41,8,255); mangroves(x+5,300,5,4,14,62,17,255); } } void cloud(int x,int y,int w,int h,int red,int green,int blue,int a){ fill(red,green,blue,a); ellipse(x,y,w,h); } //sets variables they're being created in void mangroves(int x,int y,int w,int h,int red,int green,int blue,int a){ fill(red,green,blue,a); ellipse(x,y,w,h); ellipse(x+5,y+5,w,h); ellipse(x-5,y-3,w,h); ellipse(x+3,y-5,w,h); ellipse(x-3,y+5,w,h); } void serialEvent(Serial myPort){ String s=myPort.readStringUntil('\n'); s=trim(s); if (s!=null) xPos=(int)map(int(s),0,650,0, width); //jere println(xPos); myPort.write(State); }
class Moon { int x; int y; int sizeMod = 0; Moon() { //instantiate moon at x = 60, y = 90 this.x = 60; this.y = 90; } void drawMoon() { int blue, green; //map xPos to green and blue rgb values for moon green = int(map(xPos, 0, width, 221, 250)); blue = int(map(xPos, 0, width, 0, 205)); noStroke(); fill(255, green, blue); //map Pos X to rgb values for background/sky int bg_red = int(map(xPos, 0, width, 83, 0)); int bg_green = int(map(xPos, 0, width, 157, 0)); int bg_blue = int(map(xPos, 0, width, 253, 0)); //map xPos to variable sizeMod, starting at 0, ending at 20 sizeMod = int(map(xPos, 0, width/6, 0, 20)); //width/6 divides canvas into 6, for each moon/sun phase if (xPos <= width/6) { //sizeMod decreases size of moon, starts at 80, ends at 80 - 20 = 60 ellipse(x, y, 80 - sizeMod, 80 - sizeMod); } else if (xPos > width/6 && xPos <= 2 * (width/6)) { arc(x, y, 60, 60, HALF_PI, 3 * HALF_PI, OPEN); } else if (xPos > 2 * width/6 && xPos <= 3 * width/6) { ellipse(x, y, 60, 60); //draw two overlapping circles to give illusion of crescent moon fill(bg_red, bg_green, bg_blue); ellipse(x + 10, y, 50, 50); } else if (xPos > 3 * width/6 && xPos <= 4 * width/6) { ellipse(x, y, 60, 60); //can't figure out how to flip arc, just cover with rectangle fill(bg_red, bg_green, bg_blue); rect(x - 30, y - 30, 30, 60); } else if (xPos > 4 * width/6 && xPos <= 5 * width/6) { ellipse(x, y, 60, 60); //draw two overlapping circles to give illusion of crescent moon fill(bg_red, bg_green, bg_blue); ellipse(x - 10, y, 50, 50); } else { ellipse(x, y, 60, 60); } } void update() { x = xPos; } }
class Star { int x; int y; Star() { //instantiate star with random x and random y values, every time you restart sketch it' random this.x = int(random(0, width)); this.y = int(random(0, height/3)); } void drawStar() { fill(255); ellipse(x, y, -1.5, -1.5); } }
Great job on this Sara. The controller box is a really nice touch.