P5.js与Arduino按钮映射问题:蚀刻素描清屏功能失效求助
Arduino Uno + P5.js 蚀刻素描项目问题修复
问题概述
- 电位器数值已被Arduino和P5.js正常读取,但坐标映射未生效,画笔无法覆盖整个画布
- 按钮触发清屏的逻辑完全失效,点击按钮无任何反应
原始P5.js代码
let prevX, prevY, button; let isCleared = false; let serialPortName = '/dev/tty.usbserial-1130'; let serial; let sensors = [200,200,0]; function setup() { createCanvas(400, 400); prevX = width/2; PrevY = height/2; serial = new p5.SerialPort(); serial.open('/dev/tty.usbserial-1130'); serial.on('data', gotData); serial.on('open', gotOpen); } function draw() { if (isCleared ==true){ background(250); isCleared = false; } // prevX = map(prevX, 0,1023, 0, 200); // prevY = map(prevY, 0,1023, 200,0 ); strokeWeight(10); line(prevX, prevY, sensors[0], sensors[1]); prevX = sensors[0]; prevY = sensors[1]; //button = sensors[2]; //prevX = map(prevX, 0,1023, 0, 200); // prevY = map(prevY, 0,1023, 200,0 ); } function gotData() { let currentString = serial.readLine(); trim(currentString); if (!currentString) return; sensors = split(currentString, ','); console.log(sensors); serial.write('A'); } if (sensors[2] == 1){ isCleared = true; } function gotOpen(){ print("Serial Port is Open"); serial.clear(); // clears the buffer of any outstanding data serial.write('A'); // send a byte to the Arduino } //function buttonPressed(){ // if (sensors[2] == 1){ // isCleared = true; //} //}
硬件说明
- 硬件包含Arduino Uno、2个电位器、1个按钮,布线及Arduino代码可在Tinkercad项目中查看
- 布线示意图:

问题修复方案
1. 解决坐标映射问题
- 错误点:变量名大小写错误(
PrevY应改为prevY),导致初始Y坐标未正确设置;未对电位器0-1023的原始数值做映射,直接使用会限制画笔活动范围 - 修复方式:在读取串口数据后,立即将X、Y值映射为画布宽高范围内的坐标(0到400)
2. 修复按钮清屏逻辑
- 错误点:按钮判断代码写在
gotData函数外部,无法实时响应串口数据更新;串口读取的数值为字符串类型,直接和数字1比较会导致判断失效 - 修复方式:将按钮判断逻辑移到
gotData函数内部,同时将读取到的按钮值转为数字后再做比较
修改后的完整P5.js代码
let prevX, prevY; let isCleared = false; let serialPortName = '/dev/tty.usbserial-1130'; let serial; let sensors = [200, 200, 0]; function setup() { createCanvas(400, 400); // 修正变量名大小写错误 prevX = width / 2; prevY = height / 2; serial = new p5.SerialPort(); serial.open(serialPortName); serial.on('data', gotData); serial.on('open', gotOpen); } function draw() { if (isCleared) { background(250); isCleared = false; // 清屏后重置画笔位置到画布中心 prevX = width / 2; prevY = height / 2; } strokeWeight(10); // 使用映射后的坐标绘制线条 line(prevX, prevY, sensors[0], sensors[1]); prevX = sensors[0]; prevY = sensors[1]; } function gotData() { let currentString = serial.readLine(); trim(currentString); if (!currentString) return; sensors = split(currentString, ','); // 将串口读取的字符串转为数字,并完成坐标映射 sensors[0] = map(Number(sensors[0]), 0, 1023, 0, width); sensors[1] = map(Number(sensors[1]), 0, 1023, 0, height); // 按钮清屏逻辑:转换为数字后判断,按下时触发清屏 if (Number(sensors[2]) === 1) { isCleared = true; } console.log(sensors); serial.write('A'); } function gotOpen() { print("Serial Port is Open"); serial.clear(); serial.write('A'); }
内容的提问来源于stack exchange,提问作者K-PopCorn
相关产品推荐
相关产品推荐

