Java 处理/读取串行端口数据流崩溃程序
我正在编写一个简单的程序,从一个普通的旧串口读取连续的数据流。该程序是在处理过程中编写的。执行简单的数据读取并将其转储到控制台工作得非常好,但是每当我向程序添加任何其他功能(绘图、db条目)时,端口开始变得不同步,来自串行端口的所有数据开始变得损坏 来自串行端口的传入数据采用以下格式:Java 处理/读取串行端口数据流崩溃程序,java,sqlite,serial-port,processing,Java,Sqlite,Serial Port,Processing,我正在编写一个简单的程序,从一个普通的旧串口读取连续的数据流。该程序是在处理过程中编写的。执行简单的数据读取并将其转储到控制台工作得非常好,但是每当我向程序添加任何其他功能(绘图、db条目)时,端口开始变得不同步,来自串行端口的所有数据开始变得损坏 来自串行端口的传入数据采用以下格式: [TAB]//开始标志 数据1[选项卡] 数据2[选项卡] 数据3[选项卡] 数据4[选项卡] 数据5[选项卡] 数据6[选项卡] 数据7[选项卡] 数据8[选项卡] 计数[选项卡]//已发送邮件数的计数 Z[C
[TAB]//开始标志
数据1[选项卡]
数据2[选项卡]
数据3[选项卡]
数据4[选项卡]
数据5[选项卡]
数据6[选项卡]
数据7[选项卡]
数据8[选项卡]
计数[选项卡]//已发送邮件数的计数
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 + ");" );
// }
// }
}
}
虽然我不熟悉您的特定平台,但阅读您的问题描述后,我的第一个想法是您仍然存在时间问题。以115200bps的速度,数据输入速度相当快——每毫秒超过10个字符。因此,如果您花费宝贵的时间打开数据库(文件IO速度较慢)或绘制图形(也可能较慢),则很可能无法跟上数据 因此,将串行端口处理放在自己的线程、中断等上可能是一个好主意,这可能会使多任务处理更加容易。同样,这只是一个有根据的猜测
另外,当您启用其他操作时,您会说您的程序“崩溃”。你的意思是整个过程实际上崩溃了,还是数据被破坏了,或者两者兼而有之?是否有可能您的缓存[]超过了200字节?以115kbps的速度运行,只需20毫秒即可完成。虽然我不熟悉您的特定平台,但阅读您的问题描述后,我的第一个想法是您仍然存在计时问题。以115200bps的速度,数据输入速度相当快——每毫秒超过10个字符。因此,如果您花费宝贵的时间打开数据库(文件IO速度较慢)或绘制图形(也可能较慢),则很可能无法跟上数据 因此,将串行端口处理放在自己的线程、中断等上可能是一个好主意,这可能会使多任务处理更加容易。同样,这只是一个有根据的猜测
另外,当您启用其他操作时,您会说您的程序“崩溃”。你的意思是整个过程实际上崩溃了,还是数据被破坏了,或者两者兼而有之?是否有可能您的缓存[]超过了200字节?以115kbps的速度运行,只需20毫秒即可完成。问题很奇怪,它往往是数据损坏后不久发生崩溃的组合。正如你所说,这似乎是一个时间问题。我试图通过将数据库插入移动到draw()函数来解决这个问题,这样就不会频繁地调用它。我还完全删除了对db.connect()的检查,这是不安全的,但该函数的开销似乎导致了一些问题。我还将波特率提高了一倍,但将数据发送到端口的速度保持不变。这些事情似乎有所帮助,但仍然让我感到好奇。问题是奇怪的——它往往是数据被破坏的组合,随后不久就发生了崩溃。正如你所说,这似乎是一个时间问题。我试图通过将数据库插入移动到draw()函数来解决这个问题,这样就不会频繁地调用它。我还完全删除了对db.connect()的检查,这是不安全的,但该函数的开销似乎导致了一些问题。我还将波特率提高了一倍,但将数据发送到端口的速度保持不变。这些事情似乎有所帮助,但仍然让我好奇。