For this project, I created an interactive system that integrates Arduino with p5.js, using Node.js for serial communication, allowing seamless interaction between the hardware (Arduino) and software (p5.js sketch).
The project consists of three tasks, each demonstrating different ways Arduino sensors and outputs can interact with visual and digital elements in p5.js. Below is a detailed description of each task, including the setup, code, and outcomes.
Task 1: Control Ellipse Horizontal Position with Arduino Sensor
Goal: Use a potentiometer connected to Arduino to control the horizontal position of an ellipse in p5.js.
Task 2: Control LED Brightness from p5.js Mouse Position
Goal: Use the mouse cursor in p5.js to control the brightness of an LED connected to Arduino.
Task 3: Gravity-Wind Sketch with LED Bounce Feedback
Goal: Modify the gravity-wind sketch (from Aaron Sherwood’s example) so that:
-A potentiometer controls the wind force.
-Each time the ball bounces, an LED lights up briefly.
systemic diagram:

Conclusion:
This project showcased the flexibility of combining Arduino and p5.js via Node.js, enabling rich interaction between hardware and software. The local setup allowed full control over serial communication, overcoming the browser-based limitations.
Future Improvements:
-
Add sound effects when the ball bounces.
-
Use multiple sensors to control more aspects of the sketch.
-
Expand interaction with other hardware components (motors, buzzers).
p5.js
The codes:
let serial;
let sensorValue = 0;
function setup() {
createCanvas(400, 400);
serial = new p5.SerialPort();
serial.on('list', printList);
serial.on('connected', serverConnected);
serial.on('open', portOpen);
serial.on('data', gotData);
serial.on('error', serialError);
serial.on('close', portClose);
serial.list(); // get list of serial ports
serial.openPort('COM3'); // replace with your actual port
}
function gotData() {
let val = serial.readLine().trim();
if (val !== "") {
sensorValue = int(val);
print(sensorValue);
}
}
function draw() {
background(220);
ellipse(map(sensorValue, 0, 1023, 0, width), height / 2, 50, 50);
}
// Optional helper functions
function printList(portList) {
console.log("List of Serial Ports:");
for (let i = 0; i < portList.length; i++) {
console.log(i + ": " + portList[i]);
}
}
function serverConnected() {
console.log('Connected to server.');
}
function portOpen() {
console.log('Serial port opened.');
}
function serialError(err) {
console.log('Serial port error: ' + err);
}
function portClose() {
console.log('Serial port closed.');
let serial;
function setup() {
createCanvas(400, 400);
serial = new p5.SerialPort();
serial.on('open', () => console.log("Serial port opened"));
serial.openPort('COM3'); // change this if needed
}
function draw() {
background(220);
let brightness = int(map(mouseX, 0, width, 0, 255));
fill(brightness);
ellipse(width / 2, height / 2, 100, 100);
serial.write(brightness + "\n"); // send brightness to Arduino
void setup() {
Serial.begin(9600);
pinMode(9, OUTPUT); // LED on pin 9
}
void loop() {
int sensor = analogRead(A0);
Serial.println(sensor);
delay(10); // short delay
if (Serial.available()) {
char c = Serial.read();
if (c == 'B') {
digitalWrite(9, HIGH);
delay(100);
digitalWrite(9, LOW);
}
}
}
void setup() {
Serial.begin(9600);
pinMode(9, OUTPUT); // LED on pin 9
}
void loop() {
int sensor = analogRead(A0);
Serial.println(sensor);
delay(10); // short delay
if (Serial.available()) {
char c = Serial.read();
if (c == 'B') {
digitalWrite(9, HIGH);
delay(100);
digitalWrite(9, LOW);
}
}
}
let serial;
let sensorValue = 0;
let windForce = 0;
let ball;
let gravity;
function setup() {
createCanvas(400, 400);
serial = new p5.SerialPort();
// Open the correct serial port
serial.openPort('COM3'); // ← Change to your actual Arduino COM port!
// When data comes in from Arduino
serial.on('data', gotData);
gravity = createVector(0, 0.2);
ball = new Ball();
}
function gotData() {
let val = serial.readLine().trim();
if (val !== "") {
sensorValue = int(val);
windForce = map(sensorValue, 0, 1023, -0.2, 0.2);
print("Sensor:", sensorValue, "→ Wind:", windForce);
}
}
function draw() {
background(240);
// Apply wind from sensor and gravity
ball.applyForce(createVector(windForce, 0));
ball.applyForce(gravity);
// Update + show ball
ball.update();
ball.display();
// If ball bounced, tell Arduino to blink LED
if (ball.isBouncing()) {
serial.write('B\n');
}
}
class Ball {
constructor() {
this.position = createVector(width / 2, 0);
this.velocity = createVector();
this.acceleration = createVector();
this.radius = 24;
this.bounced = false;
}
applyForce(force) {
this.acceleration.add(force);
}
update() {
this.velocity.add(this.acceleration);
this.position.add(this.velocity);
this.acceleration.mult(0);
// Bounce off bottom
if (this.position.y >= height - this.radius) {
this.position.y = height - this.radius;
this.velocity.y *= -0.9;
this.bounced = true;
} else {
this.bounced = false;
}
}
isBouncing() {
return this.bounced;
}
display() {
fill(50, 100, 200);
noStroke();
ellipse(this.position.x, this.position.y, this.radius * 2);
}
}
Arduino code:
int sensorPin = A0; // Potentiometer connected to analog pin A0
int sensorValue = 0; // Variable to store the potentiometer value
void setup() {
Serial.begin(9600); // Start serial communication at 9600 baud rate
}
void loop() {
sensorValue = analogRead(sensorPin); // Read the potentiometer value (0-1023)
Serial.println(sensorValue); // Send the value to the computer
delay(10); // Short delay to prevent overloading serial data
}
void setup() {
Serial.begin(9600);
pinMode(9, OUTPUT); // LED connected to pin 9 (PWM)
}
void loop() {
if (Serial.available()) {
int brightness = Serial.parseInt();
brightness = constrain(brightness, 0, 255); // safety check
analogWrite(9, brightness);
}
}
void setup() {
Serial.begin(9600);
pinMode(9, OUTPUT); // LED on pin 9
}
void loop() {
int sensor = analogRead(A0);
Serial.println(sensor);
delay(10); // short delay
if (Serial.available()) {
char c = Serial.read();
if (c == 'B') {
digitalWrite(9, HIGH);
delay(100);
digitalWrite(9, LOW);
}
}
}
The videos:
https://drive.google.com/drive/u/0/folders/1Kk2lkQgoAyybXSYWVmY2Dog9uQVX_DMq