Processing按AM/PM分时段保存CSV表并重置数据表的问题
问题
我有一个项目,每15分钟通过串口接收数据,用Processing读取并保存为CSV文件。预期每12小时创建一个新文件,但从AM切换到PM时,之前所有AM的数据都会被存入PM文件。我试过这段代码:
saveTable(dataTable, fileName()); dataTable.clearRows();
但这样操作只会清空CSV文件,请问如何正确重置数据表并开始保存到新文件?
生成文件名的代码
String fileName() { String fileName = ""; String month = ""; String day = ""; int m = month(); int d = day(); if (d < 10) { day = str(d); day = "-0" + day; } else { day = "-" + str(d); } switch(m) { case 1: month = "-JAN"; break; case 2: month = "-FEB"; break; case 3: month = "-MAR"; break; case 4: month = "-APR"; break; case 5: month = "-MAY"; break; case 6: month = "-JUN"; break; case 7: month = "-JUL"; break; case 8: month = "-AUG"; break; case 9: month = "-SEP"; break; case 10: month = "-OCT"; break; case 11: month = "-NOV"; break; case 12: month = "-DEC"; break; } if (hour() >= 12) { hour = "-PM"; } else { hour = "-AM"; } fileName = "SensorData_" + str(year()) + month + day + hour + ".csv"; return fileName; }
更新:数据采集与保存代码
void serialEvent(Serial myPort) { if (myPort.available() > 0) { String serialDataString = myPort.readString(); if (serialDataString != null) { serialDataString = trim(serialDataString); float[] sensorData = float(split(serialDataString, ',')); TableRow newRow = dataTable.addRow(); if (sensorData.length == 4) { temperature = sensorData[0]; humidity = sensorData[1]; moisture = sensorData[2]; int packet = int(sensorData[3]); if (packet < 10) { packets = "00" + str(packet); } else if (packet < 100) { packets = "0" + str(packet); } String time = str(hour()) + ":" + str(minute()) + ":" + str(second()); String date = str(month()) + "/" + str(day()); newRow.setFloat("Temperature", temperature); newRow.setFloat("Humidity", humidity); newRow.setFloat("Moisture", moisture); newRow.setString("Time", time); newRow.setString("Date", date); } saveTable(dataTable, fileName()); } } }
解决方案
问题根源在于每次调用saveTable时,都会把dataTable的全部内容写入当前文件名对应的文件。当时间从AM切换到PM时,新的PM文件名生成后,dataTable仍保留着AM时段的所有数据,导致这些数据被一并写入PM文件。
正确做法是跟踪当前正在使用的文件名,每次生成新文件名时,先保存旧文件并重置数据表:
- 添加全局跟踪变量
Table dataTable; String currentFileName; // 跟踪当前使用的文件名
- 初始化数据表与文件名
在setup()中完成初始化:
void setup() { // 串口初始化等其他代码 dataTable = new Table(); // 添加数据表列 dataTable.addColumn("Temperature"); dataTable.addColumn("Humidity"); dataTable.addColumn("Moisture"); dataTable.addColumn("Time"); dataTable.addColumn("Date"); currentFileName = fileName(); // 初始化当前文件名 }
- 修改串口事件处理逻辑
每次处理数据前检查文件名是否变化,按需保存旧文件并重置数据表:
void serialEvent(Serial myPort) { if (myPort.available() > 0) { String serialDataString = myPort.readString(); if (serialDataString != null) { serialDataString = trim(serialDataString); float[] sensorData = float(split(serialDataString, ',')); // 检查文件名是否更新 String newFileName = fileName(); if (!newFileName.equals(currentFileName)) { // 保存旧时段的数据表 saveTable(dataTable, currentFileName); // 清空数据表,准备新时段数据 dataTable.clearRows(); // 更新当前文件名 currentFileName = newFileName; } if (sensorData.length == 4) { float temperature = sensorData[0]; float humidity = sensorData[1]; float moisture = sensorData[2]; int packet = int(sensorData[3]); String packets; if (packet < 10) { packets = "00" + str(packet); } else if (packet < 100) { packets = "0" + str(packet); } else { packets = str(packet); // 补充三位数的处理 } String time = str(hour()) + ":" + str(minute()) + ":" + str(second()); String date = str(month()) + "/" + str(day()); // 仅在数据有效时添加行 TableRow newRow = dataTable.addRow(); newRow.setFloat("Temperature", temperature); newRow.setFloat("Humidity", humidity); newRow.setFloat("Moisture", moisture); newRow.setString("Time", time); newRow.setString("Date", date); } // 保存当前数据到对应文件 saveTable(dataTable, currentFileName); } } }
- 修复文件名函数的变量冲突
原函数中hour是Processing内置函数,不能用作变量名,修改为:
String fileName() { String fileName = ""; String month = ""; String day = ""; int m = month(); int d = day(); if (d < 10) { day = "-0" + str(d); } else { day = "-" + str(d); } switch(m) { case 1: month = "-JAN"; break; case 2: month = "-FEB"; break; case 3: month = "-MAR"; break; case 4: month = "-APR"; break; case 5: month = "-MAY"; break; case 6: month = "-JUN"; break; case 7: month = "-JUL"; break; case 8: month = "-AUG"; break; case 9: month = "-SEP"; break; case 10: month = "-OCT"; break; case 11: month = "-NOV"; break; case 12: month = "-DEC"; break; } String hourSuffix = (hour() >= 12) ? "-PM" : "-AM"; fileName = "SensorData_" + str(year()) + month + day + hourSuffix + ".csv"; return fileName; }
核心改进点:
- 通过跟踪文件名,确保时段切换时仅保存对应时段的数据
- 避免无效空行生成,仅在数据有效时添加行
- 修复了变量名冲突问题
内容的提问来源于stack exchange,提问作者Justin Wilker
相关产品推荐
相关产品推荐

