Я работаю над простой программой для чтения непрерывного потока данных из простого старого последовательного порта. Программа написана на 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 + ");" );
// }
// }
}
}