我正在开发一个简单的程序来从普通的旧串口读取连续的数据流。该程序是在Processing中编写的。执行简单的数据读取并转入控制台的工作完全正常,但每当我向程序添加任何其他功能(图形,数据库条目)时,端口开始变为去同步,并且来自串行端口的所有数据都开始变得腐败。
来自串口的输入数据采用以下格式:
A [TAB] //开始标志
数据1 [TAB]
数据2 [TAB]
数据3 [TAB]
数据4 [TAB]
数据5 [TAB]
数据6 [TAB]
数据7 [TAB]
数据8 [TAB]
COUNT [TAB] //发送的邮件数量计数
Z [CR] //结束标志后跟回车
如上所述,如果我运行下面的程序并将其输出到控制台,它运行正常,几个小时没有问题。如果我添加图形功能或数据库连接,串行数据开始出现乱码,串行端口处理程序永远无法再次正确解码消息。我已经尝试了各种解决方法来解决这个问题,认为这是一个时间问题,但降低串口的速度似乎并没有改变。
如果您看到串口处理程序,我提供一个大缓冲区,以防终止Z字符被切断。我检查以确保A和Z字符在正确的位置,然后创建的“子字符串”是正确的长度。当程序开始失败时,子字符串将连续失败,直到程序崩溃为止。有任何想法吗?我已经尝试了几种不同的方式来读取串口,我只是开始怀疑我是否在这里错过了一些愚蠢的东西。
//Serial Port Tester
import processing.serial.*;
import processing.net.*;
import org.gwoptics.graphics.graph2D.Graph2D;
import org.gwoptics.graphics.graph2D.traces.ILine2DEquation;
import org.gwoptics.graphics.graph2D.traces.RollingLine2DTrace;
import de.bezier.data.sql.*;
SQLite db;
RollingLine2DTrace r1,r2,r3,r4;
Graph2D g;
Serial mSerialport; //the serial port
String[] svalues = new String[8]; //string values
int[] values = new int[8]; //int values
int endflag = 90; //Z
byte seperator = 13; //carriage return
class eq1 implements ILine2DEquation {
public double computePoint(double x,int pos) {
//data function for graph/plot
return (values[0] - 32768);
}
}
void connectDB()
{
db = new SQLite( this, "data.sqlite" );
if ( db.connect() )
{
db.query( "SELECT name as \"Name\" FROM SQLITE_MASTER where type=\"table\"" );
while (db.next())
{
println( db.getString("Name") );
}
}
}
void setup () {
size(1200, 1000);
connectDB();
println(Serial.list());
String portName = Serial.list()[3];
mSerialport = new Serial(this, portName, 115200);
mSerialport.clear();
mSerialport.bufferUntil(endflag); //generate serial event when endflag is received
background(0);
smooth();
//graph setup
r1 = new RollingLine2DTrace(new eq1(),250,0.1f);
r1.setTraceColour(255, 0, 0);
g = new Graph2D(this, 1080, 500, false);
g.setYAxisMax(10000);
g.addTrace(r1);
g.position.y = 50;
g.position.x = 100;
g.setYAxisTickSpacing(500);
g.setXAxisMax(10f);
}
void draw () {
background(200);
//g.draw(); enable this and program crashes quickly
}
void serialEvent (Serial mSerialport)
{
byte[] inBuffer = new byte[200];
mSerialport.readBytesUntil(seperator, inBuffer);
String inString = new String(inBuffer);
String subString = "";
int startFlag = inString.indexOf("A");
int endFlag = inString.indexOf("Z");
if (startFlag == 0 && endFlag == 48)
{
subString = inString.substring(startFlag+1,endFlag);
}
else
{
println("ERROR: BAD MESSAGE DISCARDED!");
subString = "";
}
if ( subString.length() == 47)
{
svalues = (splitTokens(subString));
values = int(splitTokens(subString));
println(svalues);
// if (db.connect()) //enable this and program crashes quickly
// {
// if ( svalues[0] != null && svalues[7] != null)
// {
// statement = svalues[7] + ", " + svalues[0] + ", " + svalues[1] + ", " + svalues[2] + ", " + svalues[3] + ", " + svalues[4] + ", " + svalues[5] + ", " + svalues[6];
// db.execute( "INSERT INTO rawdata (messageid,press1,press2,press3,press4,light1,light2,io1) VALUES (" + statement + ");" );
// }
// }
}
}
答案 0 :(得分:1)
虽然我不熟悉您的特定平台,但我在阅读您的问题描述时首先想到的是您仍有时间问题。在115,200bps时,数据进入相当快 - 每毫秒超过10个字符。因此,如果您花费宝贵的时间打开数据库(慢速文件IO)或绘制图形(也可能很慢),您可能无法跟上数据。
因此,将串行端口处理放在自己的线程,中断等上可能是个好主意。这可能会使多任务处理变得更加容易。同样,这只是一个有根据的猜测。
另外,当您启用其他操作时,您说您的程序“崩溃”。您是说整个过程实际崩溃,还是数据损坏,或两者兼而有之?您是否有可能超过200字节inBuffer []?以115kbps的速度运行,不需要20ms。