xxxxxxxxxx
196
let port, reader, writer;
let serialActive = false;
async function getPort(baud = 9600) {
let port = await navigator.serial.requestPort();
await port.open({ baudRate: baud });
// create read & write streams
textDecoder = new TextDecoderStream();
textEncoder = new TextEncoderStream();
readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
writableStreamClosed = textEncoder.readable.pipeTo(port.writable);
reader = textDecoder.readable
.pipeThrough(new TransformStream(new LineBreakTransformer()))
.getReader();
writer = textEncoder.writable.getWriter();
return { port, reader, writer };
}
class LineBreakTransformer {
constructor() {
this.chunks = "";
}
transform(chunk, controller) {
this.chunks += chunk;
const lines = this.chunks.split("\r\n");
this.chunks = lines.pop();
lines.forEach((line) => controller.enqueue(line));
}
flush(controller) {
controller.enqueue(this.chunks);
}
}
async function setupSerial() {
noLoop();
({ port, reader, writer } = await getPort());
serialActive = true;
runSerial();
loop();
}
async function runSerial() {
try {
while (true) {
const { value, done } = await reader.read();
if (done) {
reader.releaseLock();
break;
}
readSerial(value);
}
} catch (e) {
console.error(e);
}
}
////////////////////////////////////////////////////////////
let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let windSpeed;
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);
textSize(16);
}
function draw() {
background(0);
if (serialActive){
wind.x = map(windSpeed, 0, 1023, -1, 1);
}
applyForce(wind);
applyForce(gravity);
velocity.add(acceleration);
velocity.mult(drag);
position.add(velocity);
acceleration.mult(0);
ellipse(position.x, position.y, mass, mass);
console.log("Wind Speed: " + windSpeed); // For debugging
if (position.y > height - mass / 2) {
velocity.y *= -0.9; // A little dampening when hitting the bottom
position.y = height - mass / 2;
// Send signal to Arduino on bounce
if (serialActive) {
sendBounceSignal();
}
}
if (!serialActive) {
fill(255);
text("Press SPACE to connect to Serial Port", 20, 30);
} else {
fill(0, 255, 0);
text("Connected to Serial Port", 20, 30);
}
}
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 (keyCode == LEFT_ARROW) {
wind.x = -1;
}
if (keyCode == RIGHT_ARROW) {
wind.x = 1;
}
if (key == " ") {
if (!serialActive) {
setupSerial();
} else {
mass = 50;
position.y = -mass;
velocity.mult(0);
}
}
}
async function setupSerial() {
try {
noLoop();
// ({ port, reader, writer } = await getPort());
port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
// Create a TextDecoderStream to decode incoming bytes to text
const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
// Create the reader to read from the decoded text stream
reader = textDecoder.readable
.pipeThrough(new TransformStream(new LineBreakTransformer())) // Optional: split data by lines
.getReader();
writer = port.writable.getWriter();
serialActive = true;
// Start reading data after successfully opening the port
runSerial();
loop();
} catch (err) {
console.error("Serial connection failed:", err);
serialActive = false;
}
}
function readSerial(data) {
if (data != null) {
let fromArduino = trim(data); // Remove any whitespace
console.log(data);
if (fromArduino !== "") {
fromArduino = parseInt(fromArduino, 10);
windSpeed = int(fromArduino); // Convert the string to an integer
}
}
}
async function sendBounceSignal() {
try {
if (writer) {
await writer.write(new TextEncoder().encode("bounce\n"));
}
} catch (err) {
console.error("Failed to send bounce signal:", err);
}
}