Processing串口采集数据存CSV:解决无数据时越界异常
解决Processing串口数据获取的数组越界问题
你的核心问题是draw()函数每秒循环执行60次,无论是否有新串口数据都会直接访问数组,加上未处理数据解析失败的情况,导致数组越界。以下是针对性的修复方案,同时补充CSV保存功能:
修改要点
- 新增
hasNewData布尔标志,仅在收到有效新数据时触发显示更新与CSV写入 - 解析串口数据时先校验数组长度,确保格式符合预期再赋值
- 修复原代码中未定义的
inStr变量错误 - 实现CSV文件的追加写入逻辑,包含时间戳便于数据追溯
完整修复代码
import processing.serial.*; import java.io.*; Serial myPort; float[] sensorData = {0, 0, 0}; boolean hasNewData = false; // 标记是否有有效新数据 PrintWriter csvWriter; void setup() { size(1043, 152); background(255); // 初始化串口 myPort = new Serial(this, "COM4", 9600); myPort.bufferUntil('\n'); // 初始化CSV写入器(追加模式) csvWriter = createWriter("sensor_data.csv"); // 写入CSV表头(仅首次运行时执行) csvWriter.println("Timestamp,Temperature,Humidity,Moisture"); csvWriter.flush(); } void draw() { // 仅在有有效新数据时更新界面 if (hasNewData) { background(255); // 刷新背景 fill(0); rect(10, 2, sensorData[0], 46); rect(10, 52, sensorData[1], 46); rect(10, 102, sensorData[2], 46); fill(255); rect(390, 14, 265, 21); fill(0); textAlign(CENTER); textSize(14); text("Temperature: " + sensorData[0] + " Humidity: " + sensorData[1] + " Moisture: " + sensorData[2], width/2, 30); hasNewData = false; // 重置标志,等待下一次新数据 } } void serialEvent(Serial myPort) { String serialData = myPort.readStringUntil('\n'); if (serialData != null) { serialData = trim(serialData); String[] dataStr = split(serialData, ','); // 校验数据格式必须为3个数值 if (dataStr.length == 3) { try { sensorData = float(dataStr); hasNewData = true; // 标记有新数据 // 写入CSV:时间戳+传感器数据 String timestamp = year() + "-" + nf(month(),2) + "-" + nf(day(),2) + " " + nf(hour(),2) + ":" + nf(minute(),2) + ":" + nf(second(),2); csvWriter.println(timestamp + "," + sensorData[0] + "," + sensorData[1] + "," + sensorData[2]); csvWriter.flush(); // 立即写入文件 print("Received valid data: "); println(sensorData); } catch (Exception e) { println("Failed to parse data: " + serialData); } } else { println("Invalid data length: " + serialData); } } } // 程序退出时关闭CSV写入器,避免数据丢失 void exit() { if (csvWriter != null) { csvWriter.close(); } super.exit(); }
关键逻辑说明
- 标志位控制:
hasNewData确保draw()仅在收到有效数据时执行界面更新,彻底避免无数据时的数组访问异常 - 数据校验:解析前先检查分割后的数组长度,过滤格式错误的串口数据
- CSV持久化:每次收到有效数据时追加写入文件,包含时间戳方便后续数据分析
- 资源清理:
exit()方法确保程序关闭时正确关闭文件流,防止数据丢失
内容的提问来源于stack exchange,提问作者Justin Wilker
相关产品推荐
相关产品推荐

