In this week’s assignments, we were tasked with figuring out three different exercises to understand and practice serial communication between Arduino and P5js.
EXERCISE 1:
In this exercise we have to make an eclipse move across the p5js sketch using anything on the Arduino. For this we decided to use a potentiometer and an eclipse that gradually changes color along with it’s background.
Code:
/* Week 11.2 bidi serial example
* Originally by Aaron Sherwood
* Modified by Mangtronix
*
* Add this library to Sketch files
* https://github.com/mangtronix/IntroductionToInteractiveMedia/blob/master/code/p5.web-serial.js files
*
* You must include this line in your index.html (in Sketch Files) to load the
* web-serial library
*
* <script src="p5.web-serial.js"></script>
*
* Arduino code:
* https://github.com/mangtronix/IntroductionToInteractiveMedia/blob/master/code/Week11Serial.ino
*/
let rVal = 0;
let alpha = 255;
let left = 0; // True (1) if mouse is being clicked on left side of screen
let right = 0; // True (1) if mouse is being clicked on right side of screen
function setup() {
createCanvas(640, 480);
textSize(18);
}
function draw() {
// one value from Arduino controls the background's red color
background(map(rVal, 0, 1023, 0, 255), 255, 255);
let ellipseX = map(rVal, 0, 1023, 0, width);
ellipse(ellipseX, height / 2, 50, 50); // The ellipse's Y position is fixed at the center
// the other value controls the text's transparency value
fill(255, 0, 255, map(alpha, 0, 1023, 0, 255));
if (!serialActive) {
text("Press Space Bar to select Serial Port", 20, 30);
} else {
text("Connected", 20, 30);
}
// click on one side of the screen, one LED will light up
// click on the other side, the other LED will light up
if (mouseIsPressed) {
if (mouseX <= width / 2) {
left = 1;
} else {
right = 1;
}
} else {
left = right = 0;
}
}
function keyPressed() {
if (key == " ") {
// important to have in order to start the serial connection!!
setUpSerial();
}
}
// This function will be called by the web-serial library
// with each new *line* of data. The serial library reads
// the data until the newline and then gives it to us through
// this callback function
function readSerial(data) {
////////////////////////////////////
//READ FROM ARDUINO HERE
////////////////////////////////////
if (data != null) {
// make sure there is actually a message
// split the message
let fromArduino = split(trim(data), ",");
// if the right length, then proceed
if (fromArduino.length == 2) {
// only store values here
// do everything with those values in the main draw loop
// We take the string we get from Arduino and explicitly
// convert it to a number by using int()
// e.g. "103" becomes 103
rVal = int(fromArduino[0]);
alpha = int(fromArduino[1]);
}
//////////////////////////////////
//SEND TO ARDUINO HERE (handshake)
//////////////////////////////////
let sendToArduino = left + "," + right + "\n";
writeSerial(sendToArduino);
}
}
//Arduino Code
/*
// Week 11.2 Example of bidirectional serial communication
// Inputs:
// - A0 - sensor connected as voltage divider (e.g. potentiometer or light sensor)
// - A1 - sensor connected as voltage divider
//
// Outputs:
// - 2 - LED
// - 5 - LED
int leftLedPin = 2;
int rightLedPin = 5;
void setup() {
// Start serial communication so we can send data
// over the USB connection to our p5js sketch
Serial.begin(9600);
// We'll use the builtin LED as a status output.
// We can't use the serial monitor since the serial connection is
// used to communicate to p5js and only one application on the computer
// can use a serial port at once.
pinMode(LED_BUILTIN, OUTPUT);
// Outputs on these pins
pinMode(leftLedPin, OUTPUT);
pinMode(rightLedPin, OUTPUT);
// Blink them so we can check the wiring
digitalWrite(leftLedPin, HIGH);
digitalWrite(rightLedPin, HIGH);
delay(200);
digitalWrite(leftLedPin, LOW);
digitalWrite(rightLedPin, LOW);
// start the handshake
while (Serial.available() <= 0) {
digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
Serial.println("0,0"); // send a starting message
delay(300); // wait 1/3 second
digitalWrite(LED_BUILTIN, LOW);
delay(50);
}
}
void loop() {
// wait for data from p5 before doing something
while (Serial.available()) {
digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
int left = Serial.parseInt();
int right = Serial.parseInt();
if (Serial.read() == '\n') {
digitalWrite(leftLedPin, left);
digitalWrite(rightLedPin, right);
int sensor = analogRead(A0);
delay(5);
int sensor2 = analogRead(A1);
delay(5);
Serial.print(sensor);
Serial.print(',');
Serial.println(sensor2);
}
}
digitalWrite(LED_BUILTIN, LOW);
}
*/
P5* Sketch:
Video:
EXERCISE 2:
For this exercise we were tasked with making an LED change brightness based on a p5js sketch, which we decided to make more interesting by taking inspiration from the sun and making a p5 sketch look like a sky. The latter has moving clouds and a sun that changes based on the brightness which is controlled by the keyboard “up” and “down” keys which also control the LED brightness.
Code:
let brightness=0;
let cloud1X = 100;
let cloud2X = 40;
let cloud3X = 200;
function setup() {
createCanvas(1000, 480);
textSize(18);
}
function draw() {
noStroke();
background(135, 206, 235);
fill(0);
drawCloud(cloud1X, 60); // Cloud on the right of the sun
drawCloud(cloud2X, 100); // Cloud below the sun
drawCloud(cloud3X, 350); // Cloud at the bottom
//Moves the clouds
cloud1X += 1;
cloud2X += 1;
cloud3X += 1;
// Loop the clouds once they move off screen
if (cloud1X > width + 30) {
cloud1X = -60;
}
if (cloud2X > width + 30) {
cloud2X = -60;
}
if (cloud3X > width + 30) {
cloud3X = -60;
}
if (!serialActive) {
text("Press Space Bar to select Serial Port", 20, 30);
} else {
text("Connected", 20, 30);
}
fill(255,255,0,brightness)
circle(width/2-150,height/2-30, 100)
fill(0)
text("WATCH THE SUN LIGHT UP: "+str(brightness),width/2-50,height/2)
text("UP to make the brightness higher, DOWN to make brightness dimmer ",width/2-220,height/2+50)
if (keyIsPressed) {
if (keyCode==UP_ARROW) {
if (brightness<255){
brightness+=5;
}
} else if (keyCode==DOWN_ARROW) {
if (brightness>0){
brightness-=5;
}
}
}
}
function drawCloud(x, y) {
fill(255);
// Group of ellipses to form a cloud shape
ellipse(x, y, 30, 30);
ellipse(x + 20, y, 30, 30);
ellipse(x - 20, y, 30, 30);
ellipse(x - 20, y, 30, 30);
ellipse(x + 10, y + 15, 30, 30);
ellipse(x - 10, y + 15, 30, 30);
}
function keyPressed() {
if (key == " ") {
// important to have in order to start the serial connection!!
setUpSerial();
}
}
function readSerial(data) {
if (data != null) {
writeSerial(brightness+"\n");
}
}
//ARDUINO
//int LedPin = 9;
//void setup() {
// Start serial communication so we can send data
// over the USB connection to our p5js sketch
//Serial.begin(9600);
// We'll use the builtin LED as a status output..
//pinMode(LED_BUILTIN, OUTPUT);
// Outputs on this pin
//pinMode(LedPin, OUTPUT);
// Blink them so we can check the wiring
// digitalWrite(LedPin, HIGH);
// delay(200);
// digitalWrite(LedPin, LOW);
// start the handshake
//// while (Serial.available() <= 0) {
// digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
// Serial.println("0"); // send a starting message
// delay(300); // wait 1/3 second
// digitalWrite(LED_BUILTIN, LOW);
// delay(50);
//// }
//}
//void loop() {
// wait for data from p5 before doing something
// while (Serial.available()) {
// Serial.println("0");
// digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
// int brightness = Serial.parseInt();
// if (Serial.read() == '\n') {
// analogWrite(LedPin, brightness);
// }
// }
// digitalWrite(LED_BUILTIN, LOW);
//}
P5* sketch:
Video:
EXERCISE 3:
This exercise comes in two parts, part one is creating a circuit that can blink an LED every time that the ball bounces on the p5 sketch and the second part is making a circuit that controls the wind on the game and moves the ball depending on it and as a general theme and personal touch we choose to use a soccer ball and green background.
Part 1 and 2 code:
let velocity;
let gravity;
let posit5
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let LED=0;
let wind_speed=0;
let ball;
function preload(){
ball = loadImage('ball.png');
}
function setup() {
createCanvas(640, 360);
noFill();
position = createVector(width/2, 0);
velocity = createVector(0,0);
acceleration = createVector(0,0);
gravity = createVector(0, 0.5*mass);
wind = createVector(0,0);
}
function draw() {
background (34, 139, 34 );
fill(0)
if (!serialActive) {
text("Press , RIGHT key to select Serial Port", 20, 30);
} else {
text("Connected", 20, 30);
}
applyForce(wind);
applyForce(gravity);
velocity.add(acceleration);
velocity.mult(drag);
position.add(velocity);
acceleration.mult(0);
fill(205,104,219);
imageMode(CENTER); // Ensures the image is centered on the position
image(ball, position.x, position.y, mass, mass); // Draw the image
if (position.y > height-mass/2) {
velocity.y *= -0.9; // A little dampening when hitting the bottom
position.y = height-mass/2;
}
if (position.y==height-mass/2){
LED=1
}
else{
LED=0
}
if (position.x>=width || position.x<=0){
position.x=width/2
}
}
function applyForce(force){
// Newton's 2nd law: F = M * A
// or A = F / M
let f = p5.Vector.div(force, mass);
acceleration.add(f);
}
function keyPressed(){
if (key==' '){
mass=random(15,80);
position.y=-mass;
velocity.mult(0);
}
if (keyCode==RIGHT_ARROW){
setUpSerial();
}
}
function readSerial(data) {
////////////////////////////////////
//READ FROM ARDUINO HERE
////////////////////////////////////
if (data != null) {
let fromArduino = trim(data);
distance= int(fromArduino);
if (distance>10){
wind.x=2
}
else{
wind.x=-2
}
let sendToArduino = LED+"\n";
writeSerial(sendToArduino);
}
}
//Arduino
// int LedPin = 9;
// int trigPin = 8;
// int echoPin = 10;
// long duration;
// int distance;
// void setup() {
// // Start serial communication so we can send data
// // over the USB connection to our p5js sketch
// pinMode(trigPin, OUTPUT);
// pinMode(echoPin, INPUT);
// Serial.begin(9600);
// pinMode(LED_BUILTIN, OUTPUT);
// // Outputs on these pins
// pinMode(LedPin, OUTPUT);
// // Blink them so we can check the wiring
// digitalWrite(LedPin, HIGH);
// delay(200);
// digitalWrite(LedPin, LOW);
// // start the handshake
// while (Serial.available() <= 0) {
// digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
// Serial.println("0,0"); // send a starting message
// delay(300); // wait 1/3 second
// digitalWrite(LED_BUILTIN, LOW);
// delay(50);
// }
// }
// void loop() {
// // wait for data from p5 before doing something
// while (Serial.available()) {
// digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
// int LED = Serial.parseInt();
// if (Serial.read() == '\n') {
// digitalWrite(LedPin, LED);
// digitalWrite(trigPin, LOW);
// delayMicroseconds(2);
// digitalWrite(trigPin, HIGH);
// delayMicroseconds(10);
// digitalWrite(trigPin, LOW);
// // Reads the echoPin, returns the sound wave travel time in microseconds
// duration = pulseIn(echoPin, HIGH);
// // Calculating the distance
// distance = duration * 0.034 / 2;
// Serial.println(distance);
// }
// }
// digitalWrite(LED_BUILTIN, LOW);
// }
P5* Sketch:
Video:
Part 1:
Part 2: