Arduino and p5.js:
Zayed and Zein
Exercise 1: Moving an Ellipse with One Sensor
Arduino Code:
int pot = analogRead(A0);
// Less responsive: smaller output range
int xPos = map(pot, 0, 1023, 100, 300);
delay(100); // longer delay = slower updates
void setup(){
Serial.begin(9600);
}
void loop(){
int pot = analogRead(A0);
// Less responsive: smaller output range
int xPos = map(pot, 0, 1023, 100, 300);
Serial.println(xPos);
delay(100); // longer delay = slower updates
}
void setup(){
Serial.begin(9600);
}
void loop(){
int pot = analogRead(A0);
// Less responsive: smaller output range
int xPos = map(pot, 0, 1023, 100, 300);
Serial.println(xPos);
delay(100); // longer delay = slower updates
}
Challenges:
It was difficult to make the ball move gradually, this was an issue with the p5.js sketch and we added a smoothing factor to make the movement more ideal.
Video:
Exercise 2:
Arduino Code:
// Arduino: LED brightness via Serial input
const unsigned long BAUD = 9600;
while (!Serial) ; // wait for Serial Monitor
Serial.println("LED Brightness Control");
Serial.println("Send a number 0–255, then <Enter>:");
// only proceed if we have a full line
if (Serial.available()) {
String line = Serial.readStringUntil('\n');
line.trim(); // remove whitespace
b = constrain(b, 0, 255);
Serial.print("
Brightness set to "); // Fade smoothly to a target brightness
void fadeTo(int target, int speed = 5, int delayMs = 10) {
// read current duty by trial (not perfect, but illustrates the idea)
for (int i = 0; i < 256; i++) {
curr += (target > curr) ? speed : -speed;
curr = constrain(curr, 0, 255);
analogWrite(ledPin, curr);
// Arduino: LED brightness via Serial input
const int ledPin = 6;
const unsigned long BAUD = 9600;
void setup() {
Serial.begin(BAUD);
while (!Serial) ; // wait for Serial Monitor
pinMode(ledPin, OUTPUT);
Serial.println("LED Brightness Control");
Serial.println("Send a number 0–255, then <Enter>:");
}
void loop() {
// only proceed if we have a full line
if (Serial.available()) {
String line = Serial.readStringUntil('\n');
line.trim(); // remove whitespace
if (line.length() > 0) {
int b = line.toInt();
b = constrain(b, 0, 255);
analogWrite(ledPin, b);
Serial.print("

Brightness set to ");
Serial.println(b);
}
}
}
// Fade smoothly to a target brightness
void fadeTo(int target, int speed = 5, int delayMs = 10) {
int curr = 0;
// read current duty by trial (not perfect, but illustrates the idea)
for (int i = 0; i < 256; i++) {
analogWrite(ledPin, i);
if (i == target) {
curr = i;
break;
}
}
while (curr != target) {
curr += (target > curr) ? speed : -speed;
curr = constrain(curr, 0, 255);
analogWrite(ledPin, curr);
delay(delayMs);
}
}
// Arduino: LED brightness via Serial input
const int ledPin = 6;
const unsigned long BAUD = 9600;
void setup() {
Serial.begin(BAUD);
while (!Serial) ; // wait for Serial Monitor
pinMode(ledPin, OUTPUT);
Serial.println("LED Brightness Control");
Serial.println("Send a number 0–255, then <Enter>:");
}
void loop() {
// only proceed if we have a full line
if (Serial.available()) {
String line = Serial.readStringUntil('\n');
line.trim(); // remove whitespace
if (line.length() > 0) {
int b = line.toInt();
b = constrain(b, 0, 255);
analogWrite(ledPin, b);
Serial.print("
Brightness set to ");
Serial.println(b);
}
}
}
// Fade smoothly to a target brightness
void fadeTo(int target, int speed = 5, int delayMs = 10) {
int curr = 0;
// read current duty by trial (not perfect, but illustrates the idea)
for (int i = 0; i < 256; i++) {
analogWrite(ledPin, i);
if (i == target) {
curr = i;
break;
}
}
while (curr != target) {
curr += (target > curr) ? speed : -speed;
curr = constrain(curr, 0, 255);
analogWrite(ledPin, curr);
delay(delayMs);
}
}
Challenges:
For this exercise the challenges were 1: making the gradient slider animation look intuitive for functionality, and we spent a lot of time debating on whether a rainbow slider was cool or not. We decided that it was.
Exercise 3:
For this exercise we decided to build on the example provided and improve the physics of the wind as well as the animation of the ball itself. To keep track of the sensor values and ensure we are receiving consistent results, we included variables to track the potentiometer, bounce (1 results in LED high, 0 results in LED low) and the mass is just an added feature.
Challenges:
The issues we faced were plenty, including making the wind seem more realistic and making the interaction smoother. The first approach to solve this challenge were to implement debounce to discard those operations that would occur too closely during the runtime interval. We also had to be particularly careful about how often the p5.js asks for the potentiometer reading, considering the frequency of the frames displaying the visual text and the frequency of the potentiometer reading.
Arduino Code:
const int LED_PIN = 9; // LED pin
const int P_PIN = A0; // Potentiometer pin
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW); // Initial LED state
// Handshake: Wait for p5.js to send a start signal
while (Serial.available() <= 0) {
Serial.println("INIT"); // Send "INIT" until p5.js responds
delay(100); // Avoid flooding
// Check for incoming serial data
if (Serial.available() > 0) {
char incoming = Serial.read(); // Read a single character
if (incoming == 'B') { // p5.js sends 'B' followed by 0 or 1
while (Serial.available() <= 0); // Wait for the value
int bounce = Serial.read() - '0'; // Convert char '0' or '1' to int
digitalWrite(LED_PIN, bounce); // Set LED (0 = LOW, 1 = HIGH)
else if (incoming == 'R') { // p5.js requests potentiometer reading
int potValue = analogRead(P_PIN); // Read potentiometer (0-1023)
Serial.println(potValue); // Send value
// Clear any remaining buffer (e.g., newlines)
while (Serial.available() > 0) {
const int LED_PIN = 9; // LED pin
const int P_PIN = A0; // Potentiometer pin
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW); // Initial LED state
// Handshake: Wait for p5.js to send a start signal
while (Serial.available() <= 0) {
Serial.println("INIT"); // Send "INIT" until p5.js responds
delay(100); // Avoid flooding
}
}
void loop() {
// Check for incoming serial data
if (Serial.available() > 0) {
char incoming = Serial.read(); // Read a single character
if (incoming == 'B') { // p5.js sends 'B' followed by 0 or 1
while (Serial.available() <= 0); // Wait for the value
int bounce = Serial.read() - '0'; // Convert char '0' or '1' to int
digitalWrite(LED_PIN, bounce); // Set LED (0 = LOW, 1 = HIGH)
}
else if (incoming == 'R') { // p5.js requests potentiometer reading
int potValue = analogRead(P_PIN); // Read potentiometer (0-1023)
Serial.println(potValue); // Send value
}
// Clear any remaining buffer (e.g., newlines)
while (Serial.available() > 0) {
Serial.read();
}
}
}
const int LED_PIN = 9; // LED pin
const int P_PIN = A0; // Potentiometer pin
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW); // Initial LED state
// Handshake: Wait for p5.js to send a start signal
while (Serial.available() <= 0) {
Serial.println("INIT"); // Send "INIT" until p5.js responds
delay(100); // Avoid flooding
}
}
void loop() {
// Check for incoming serial data
if (Serial.available() > 0) {
char incoming = Serial.read(); // Read a single character
if (incoming == 'B') { // p5.js sends 'B' followed by 0 or 1
while (Serial.available() <= 0); // Wait for the value
int bounce = Serial.read() - '0'; // Convert char '0' or '1' to int
digitalWrite(LED_PIN, bounce); // Set LED (0 = LOW, 1 = HIGH)
}
else if (incoming == 'R') { // p5.js requests potentiometer reading
int potValue = analogRead(P_PIN); // Read potentiometer (0-1023)
Serial.println(potValue); // Send value
}
// Clear any remaining buffer (e.g., newlines)
while (Serial.available() > 0) {
Serial.read();
}
}
}
ONE VIDEO FOR ALL 3 EXERCISES IN RESPECTIVE ORDER