Week 11 – Serial Communication

Task 1:
Make something that uses only one sensor  on Arduino and makes the ellipse in p5 move on the horizontal axis, in the middle of the screen, and nothing on arduino is controlled by p5

P5js code:

let sensorValue = 0;

function setup() {
  createCanvas(640, 480);
}

function draw() {
  background(220);

  // Map the sensor value (0–1023) to canvas width (0–640)
  let x = map(sensorValue, 0, 1023, 0, width);
  
  // Draw ellipse in center which is moved on the x axis by the potentiometer
  ellipse(x, height / 2, 50, 50);
}

function keyPressed() {
  if (key === ' ') {
    setUpSerial();
  }
}

function readSerial(data) {
  if (data != null) {
    sensorValue = int(trim(data)); 
  }
}

Arduino code:

void setup() {
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A0); //read the data from the potentiometer
  Serial.println(sensorValue);      //send it to p5
  delay(20);                        
}
Task 2:
Make something that controls the LED brightness from p5
P5js code:
function setup() {
  createCanvas(640, 480);
  background(0);
}

function draw() {
  background(0);
  
  // Map mouseX to brightness value (0–255)
  let brightness = map(mouseX, 0, width, 0, 255);
  fill(brightness);
  ellipse(mouseX, height / 2, 50, 50);

  // Send to Arduino only if serial is active
  if (serialActive) {
    writeSerial(int(brightness) + '\n');  // Send as string + newline
  }
}

function keyPressed() {
  if (key === ' ') {
    setUpSerial();
  }
}

//need to leave this empty as we are not reading anything from the arduino
function readSerial(data) {
}

Arduino code:

void setup() {
  Serial.begin(9600);
  pinMode(5, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    int brightness = Serial.parseInt();  //read incoming value from p5
    if (Serial.read() == '\n') {
      brightness = constrain(brightness, 0, 255);
      analogWrite(5, brightness);        // set LED brightness
    }
  }
}
Task 3:

Take the gravity wind example (https://editor.p5js.org/aaronsherwood/sketches/I7iQrNCul) and make it so every time the ball bounces one led lights up and then turns off, and you can control the wind from one analog sensor

P5js code:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;

let sensorValue = 512; // default before Arduino sends anything
let bounced = false;

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(255);

  // Map sensorValue to wind force between -1 and 1
  let windStrength = map(sensorValue, 0, 1023, -1, 1);
  wind.x = windStrength;

  applyForce(wind);
  applyForce(gravity);

  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);

  ellipse(position.x, position.y, mass, mass);

  // Bounce detection
  if (position.y > height - mass / 2) {
    velocity.y *= -0.9;
    position.y = height - mass / 2;

    if (!bounced) {
      bounced = true;
      if (serialActive) {
        writeSerial("1\n");
      }
    }
  } else {
    bounced = false;
  }
}

function applyForce(force) {
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}

function keyPressed() {
  if (key === ' ') {
    setUpSerial();
    position.y = -mass;
    velocity.mult(0);
  }
}

function readSerial(data) {
  if (data != null) {
    sensorValue = int(trim(data));
  }
}

Arduino code:

int ledPin = 5;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  //read potentiometer value
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue);

  //if we receive "1\n" from p5, blink the LED
  if (Serial.available()) {
    int signal = Serial.parseInt();
    if (Serial.read() == '\n' && signal == 1) {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
    }
  }

  delay(20);
}

Leave a Reply