Программа обработки потоковых данных обработки / чтения последовательного порта - PullRequest
1 голос
/ 30 января 2011

Я работаю над простой программой для чтения непрерывного потока данных из простого старого последовательного порта.Программа написана в обработке.Выполнение простого чтения данных и выгрузки на консоль прекрасно работает, но всякий раз, когда я добавляю в программу какие-либо другие функции (построение графиков, ввод БД), порт начинает десинхронизироваться, и все данные с последовательного порта начинаютстать коррумпированным.

Входящие данные из последовательного порта имеют следующий формат:
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 Ответ

1 голос
/ 30 января 2011

Хотя я не знаком с вашей конкретной платформой, моя первая мысль после прочтения описания вашей проблемы заключается в том, что у вас все еще есть проблема с синхронизацией. При скорости 115 200 бит / с данные поступают довольно быстро - более 10 символов в каждую миллисекунду. Поэтому, если вы тратите драгоценное время на открытие базы данных (медленный ввод-вывод файла) или на рисование графики (также потенциально медленное), вы, вероятно, не сможете идти в ногу с данными.

Таким образом, было бы неплохо поместить обработку последовательного порта в отдельный поток, прерывание и т. Д. Это может сделать многозадачность намного проще. Опять же, это просто обоснованное предположение.

Также вы говорите, что ваша программа «вылетает», когда вы включаете другие операции. Вы имеете в виду, что весь процесс на самом деле падает, или вы получаете поврежденные данные, или оба? Возможно ли, что вы превышаете свой 200-байтовый inBuffer []? На скорости 115 кбит / с это займет не более 20 мс.

...