处理/读取串行端口数据流崩溃程序
我正在研究一个简单的程序,用于从简单的旧串行端口读取连续的数据流。该程序是在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 + ");");
// }
// }
}
}
虽然我不熟悉你的特定平台,我从读你的问题的描述首先想到的是,你仍然有一个计时问题。在115,200bps的速度下,数据进入的速度非常快 - 每毫秒超过10个字符。因此,如果您花费宝贵的时间打开数据库(慢速文件IO)或绘制图形(也可能很慢),则可能无法跟上数据。
因此,它可能是把串口处理在自己的线程是一个好主意,中断等,这可能使多任务处理变得更加容易。再一次,这只是一个受过教育的猜测。
而且,你说你的程序“崩溃”当您启用其他操作。你的意思是说整个过程实际上是崩溃的,或者你得到了损坏的数据,或者两者兼而有之?是否有可能超过200字节inBuffer []?在115kbps的速度下,这并不需要20ms。
问题很奇怪 - 这往往是数据的组合被破坏,随后不久将崩溃。就像你说的那样,它似乎确实是一个计时问题。我试图通过将数据库插入移动到draw()函数来补救这一点 - 所以它不会经常被调用。我也完全删除了对db.connect()的检查,这是不安全的,但似乎该函数的开销导致了一些事情。我还将波特率加倍,但保持数据发送到端口的速度不变。这些东西似乎有所帮助,但仍然让我感到好奇。 – mhilmi 2011-01-30 02:20:21