处理/读取串行端口数据流崩溃程序

时间:2011-01-29 22:54:27

标签: java sqlite serial-port processing

我正在开发一个简单的程序来从普通的旧串口读取连续的数据流。该程序是在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 + ");" );
    //      }
    //   }
  }
}

1 个答案:

答案 0 :(得分:1)

虽然我不熟悉您的特定平台,但我在阅读您的问题描述时首先想到的是您仍有时间问题。在115,200bps时,数据进入相当快 - 每毫秒超过10个字符。因此,如果您花费宝贵的时间打开数据库(慢速文件IO)或绘制图形(也可能很慢),您可能无法跟上数据。

因此,将串行端口处理放在自己的线程,中断等上可能是个好主意。这可能会使多任务处理变得更加容易。同样,这只是一个有根据的猜测。

另外,当您启用其他操作时,您说您的程序“崩溃”。您是说整个过程实际崩溃,还是数据损坏,或两者兼而有之?您是否有可能超过200字节inBuffer []?以115kbps的速度运行,不需要20ms。