-
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 p5For this exercise, I modified the p5js code using a potentiometer on the arduino. Different values of the potentiometer are mapped to the x coordinates of the ellipse. This makes it move across the horizontal axis in the middle of the screen. The arduino code remains the same as the example code.
let y=height/2; let x = 0; 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() { background(255); // one value from Arduino controls the background's red color fill(255, 0, 255, map(x, 0, 1023, 0, 255)); ellipse(map(x, 0, 1023, 0, width), 30, 30); // the other value controls the text's transparency value if (!serialActive) { text("Press Space Bar to select Serial Port", 20, 30); } else { text("Connected", 20, 30); } 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 y = int(fromArduino[0]); x = int(fromArduino[1]); } ////////////////////////////////// //SEND TO ARDUINO HERE (handshake) ////////////////////////////////// let sendToArduino = left + "," + right + "\n"; writeSerial(sendToArduino); } }
2. make something that controls the LED brightness from p5
again tweaking the previous p5js and arduino codes, for this one, Pressing the up or down arrow key on the keyboard, run through p5js, increases or decreases the brightness of the leds on the arduino respectively. this was done using the concept of pulse width modulation.
p5js code:
let rVal = 0; let alpha = 255; let brightness = 0; function setup() { createCanvas(640, 480); textSize(18); } function draw() { background(map(rVal, 0, 1023, 0, 255), 255, 255); 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); text('rVal = ' + str(rVal), 20, 50); text('alpha = ' + str(alpha), 20, 70); } } function keyPressed() { if (key == " ") { setUpSerial(); } else if (keyCode === UP_ARROW) { brightness = constrain(brightness + 20, 0, 255); sendToArduino(); } else if (keyCode === DOWN_ARROW) { brightness = constrain(brightness - 20, 0, 255); sendToArduino(); } } function sendToArduino() { let sendToArduino = brightness + "\n"; writeSerial(sendToArduino); } function readSerial(data) { if (data != null) { let fromArduino = split(trim(data), ","); if (fromArduino.length == 2) { rVal = int(fromArduino[0]); alpha = int(fromArduino[1]); } let sendToArduino = brightness + "," + brightness + "\n"; writeSerial(sendToArduino); } }
arduino code:
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') { Serial.print("Left: "); Serial.print(left); Serial.print(", Right: "); Serial.println(right); analogWrite(leftLedPin, left); analogWrite(rightLedPin, right); } } digitalWrite(LED_BUILTIN, LOW); }
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
I found this one to be a little challenging but eventually made it work. the ball bounces with the same logic and physics from the example. Each time it touches the ground, using a boolean variable ballOnGround, it is equated to 1 or 0. this is then sent to the arduino where the LED turns on if it is 1. For the sensor contrilling wind, Im using a photoresitor whose values are mapped to the x coordinate of the wind vector. The ball moves faster when the value is larger. MouseClicking restarts the movement of the ellipse. The issue I face is slight delay in the led lighting up.
video:
p5.js Code:
let velocity; let gravity; let position; let acceleration; let wind; let drag = 0.99; let mass = 20; let ballOnGround=1; 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); if (!serialActive) { text("Press Space Bar to select Serial Port", 20, 30); } else { applyForce(wind); applyForce(gravity); velocity.add(acceleration); velocity.mult(drag); position.add(velocity); acceleration.mult(0); fill(0); ellipse(position.x, position.y, mass, mass); if (position.y > height - mass / 2) { velocity.y *= -0.9; // A little dampening when hitting the bottom position.y = height - mass / 2; ballOnGround = 1; let sendToArduino = ballOnGround + "\n"; writeSerial(sendToArduino); ballOnGround = 0; sendToArduino = ballOnGround + "\n"; writeSerial(sendToArduino); } else { ballOnGround = 0; } } if (mouseIsPressed) { restartSketch(); } } 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 == " ") { // important to have in order to start the serial connection!! setUpSerial(); } } function readSerial(data) { 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 == 1) { // only store values here // do everything with those values in the main draw loop let photoresistor = int(fromArduino[0]); //change the wind based on the photoresistor readings wind.x = map(photoresistor, 0, 1000, -5, 5); } ////////////////////////////////// //SEND TO ARDUINO HERE (handshake) ////////////////////////////////// // let sendToArduino = ballOnGround + "\n"; // writeSerial(sendToArduino); } } function restartSketch() { // Reset relevant variables to their initial values position = createVector(width / 2, 0); velocity = createVector(0, 0); acceleration = createVector(0, 0); wind = createVector(0, 0); mass = 50; ballOnGround = 0; }
arduino code:
int ledPin = 2; const int photoresistorPin = A0; void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); pinMode(ledPin, OUTPUT); pinMode(photoresistorPin, INPUT); // 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 ballOnGround = Serial.parseInt(); if (Serial.read() == '\n') { int photoresistorValue = analogRead(photoresistorPin); // Send photoresistor value to p5.js Serial.println(photoresistorValue); digitalWrite(ledPin, HIGH); digitalWrite(ledPin, LOW); // Control the LED based on the bouncing state. if (ballOnGround == 1) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } } } digitalWrite(LED_BUILTIN, LOW); }