Qt 5下シリアルポートによる高周波自発性データの受信及び処理方法
プロジェクトではQt 5を使用する必要がある.9計器の中のデータを収集して、計器は200 Hzの周波数で自発的に外へ連続的にデータを送信して、送信周波数はとても高くて、その上自発的に送信して、ソフトウェアが1回送信する必要はなくて、更に1回読んで、ソフトウェアが直接読みます.この直接連続読み出しには、2つのキーがあります.1)受信bufferから必要なデータフレームをどのように検索するか.2)毎回受信するデータbufferの中には多くのフレームがあり,どのように保存するか,各フレームの解析,処理.
全体のプログラムは:1)メインプログラムの下でシリアルポート受信信号とシリアルポート受信関数connect部分;2)シリアルポートタイマ起動関数serial_timerstart();3)シリアルポート読取関数部分;
一、メインプログラム下のシリアルポート受信信号とシリアルポート受信関数connect部分
二、シリアルポートタイマー起動関数serial_timerstart();
三、シリアルポート読取関数部分;
四、デバッグ記録は以下の通りである.
receive(buffer.toHex()):="036fffff7d210000a97afd55aa2413740f00d9060000d00f00001cfcffffbc9afdffc748010043a795009a12b01100000000dc55aa2418740f009cf0ffffdcd1ffff39c1ffff2a7cfdff7e400100ea7d95009a12b01100000000b655aa241d740f00c91100004fecffff1ef5fffffb77fdff6d4d0100766595009a12b01100000000ee55aa2422740f0004a2ffff036fffff7d210000a97afdff2e4301006e7795009a12b01100000000f355aa2427740f00f310000063f5ffffd8dbffffeba4fdff15400100c03395009a12b01100000000ae55aa242c740f00649dffff35b6ffff6fe5ffff249afdff06500100ad2895009a12b01100000000f555aa2431740f006968000051060000bb020000879efdff3e5901007d3f95009a12b011000000003455aa2436740f00840b0000fcf0ffffcc8c00008081fdffbc2b0100626795009a12b011000000005e55aa243b740f0090ecffffd9ddffffc90a00004890fdff97440100fb5e95009a12b01100000000ee55aa2440740f00a4ddffff6afcffffa2e6ffff3f99fdffe52e0100316395009a12b01100000000ce55aa2445740f00ce8bffff7cbcffff9bd3ffff267dfdff38480100215c95009a12b011000000008455aa244a740f0033d9ffff4fe8ffff0e530000c48dfdff70460100f95095009a12b01100000000e055aa244f740f0086f1ffff935d0000a50e00002573fdffae470100af3995009a12b011000000008255aa2454740f00e76900009e8affff2ff1ffffe286fdff7b4201004a4195009a12b011000000003e55aa2459740f0030d5ffff7d4100006c080000b69dfdfff34601004f3e95009a12b011000000004d55aa245e740f002fd1ffffc43e000048170000bd93fdffd14d0100a43c95009a12b01100000000b155aa2463740f0033390000db2000008f0e0000bf79fdff34610100b45d95009a12b01100000000eb55aa2468740f0073cfffff2a6d0000be3d0000e0a5fdff4a3801006b7b95009a12b01100000000cd55aa246d740f00b82600007f28000036e9ffff69a8fdff3c3901006d7595009a12b011000000001d55aa2431740f006968"
receive(buffer.toHex().size()):= 25102 receive(buffer1):= "55aa2413740f00d9060000d00f00001cfcffffbc9afdffc748010043a795009a12b01100000000dc"receive(buffer1):= "55aa2418740f009cf0ffffdcd1ffff39c1ffff2a7cfdff7e400100ea7d95009a12b01100000000b6"receive(buffer1):= "55aa241d740f00c91100004fecffff1ef5fffffb77fdff6d4d0100766595009a12b01100000000ee"receive(buffer1):= "55aa2422740f0004a2ffff036fffff7d210000a97afdff2e4301006e7795009a12b01100000000f3"receive(buffer1):= "55aa2427740f00f310000063f5ffffd8dbffffeba4fdff15400100c03395009a12b01100000000ae"receive(buffer1):= "55aa242c740f00649dffff35b6ffff6fe5ffff249afdff06500100ad2895009a12b01100000000f5"receive(buffer1):= "55aa2431740f006968000051060000bb020000879efdff3e5901007d3f95009a12b0110000000034"receive(buffer1):= "55aa2436740f00840b0000fcf0ffffcc8c00008081fdffbc2b0100626795009a12b011000000005e"receive(buffer1):= "55aa243b740f0090ecffffd9ddffffc90a00004890fdff97440100fb5e95009a12b01100000000ee"receive(buffer1):= "55aa2440740f00a4ddffff6afcffffa2e6ffff3f99fdffe52e0100316395009a12b01100000000ce"receive(buffer1):= "55aa2445740f00ce8bffff7cbcffff9bd3ffff267dfdff38480100215c95009a12b0110000000084"receive(buffer1):= "55aa244a740f0033d9ffff4fe8ffff0e530000c48dfdff70460100f95095009a12b01100000000e0"receive(buffer1):= "55aa244f740f0086f1ffff935d0000a50e00002573fdffae470100af3995009a12b0110000000082"receive(buffer1):= "55aa2454740f00e76900009e8affff2ff1ffffe286fdff7b4201004a4195009a12b011000000003e"receive(buffer1):= "55aa2459740f0030d5ffff7d4100006c080000b69dfdfff34601004f3e95009a12b011000000004d"receive(buffer1):= "55aa245e740f002fd1ffffc43e000048170000bd93fdffd14d0100a43c95009a12b01100000000b1"receive(buffer1):= "55aa2463740f0033390000db2000008f0e0000bf79fdff34610100b45d95009a12b01100000000eb"receive(buffer1):= "55aa2468740f0073cfffff2a6d0000be3d0000e0a5fdff4a3801006b7b95009a12b01100000000cd"receive(buffer1):= "55aa246d740f00b82600007f28000036e9ffff69a8fdff3c3901006d7595009a12b011000000001d"receive(buffer1):= "55aa2472740f006eebffff2bedffff74260000287cfdffe04d03901006d765009a11b014000000004d"
五、プログラム分析:
1)最初のステップは、受信bufferをhex,bufferに変換する.toHex()は、上記のデバッグ記録の最初のデータセットを参照してください.
2)whileループにより、受信したバッファから「55 aa」で開始したすべてのデータフレームを検索し、検索した後、インデックス番号で開始したデータフレーム、後の80文字をbuffer 1に格納し、buffer 1のサイズが80であるか否かを判断し、受信したbuffer.toHex()で最後に1フレーム未満を検索したデータを排除する(デバッグレコード「55 aa 2431740 f 006968」)
3)80文字ビットを満たすデータbuffer 1をコンテナvect 1に格納し、vect 1定義:QVectorvect 1は、検索されたすべてのフレームデータをコンテナvect 1に連続的に格納し、インデックス番号変更(80加算)を検索し、次のフレームから検索を開始する.
4)vect 1の各フレームデータを2つのforサイクルでそれぞれ16進バイトデータに処理する.例えば、文字'5'のASCII符号値は53、53-48=5、文字'a'のASCII符号値は97、97-97+10=0 x 0 a
for(int j=0;j { recvnum=0; qDebug() << "recvframenum:= "< for(int i=0;i {
if(vect1[j][i]>='0'&&vect1[j][i]<='9') recvdata[i]=vect1[j][i]-48; else if(vect1[j][i]>='A'&&vect1[j][i]<='F') recvdata[i]=vect1[j][i]-65+10; else if(vect1[j][i]>='a'&&vect1[j][i]<='f') recvdata[i]=vect1[j][i]-97+10; Else QMessageBox::warning(NULL,QString::fromLocal 8 Bit("警告")、QString::fromLocal 8 Bit("受信データエラー"); } for(int i=0;i { recvdata[recvnum]=recvdata[i]*16+recvdata[i+1]; qDebug() << "recvdata:= "< recvnum++; }
....
}
六、まとめ
1)indexOf()を使用して文字列の先頭から特定の文字列を検索し、インデックス番号で完全なデータフレームを検索する
2)コンテナvectを利用して検索したデータフレームを格納する
全体のプログラムは:1)メインプログラムの下でシリアルポート受信信号とシリアルポート受信関数connect部分;2)シリアルポートタイマ起動関数serial_timerstart();3)シリアルポート読取関数部分;
一、メインプログラム下のシリアルポート受信信号とシリアルポート受信関数connect部分
timer = new QTimer();
QObject::connect(&serial,&QSerialPort::readyRead,this,&Trajectory::serial_timerstart);
QObject::connect(timer,&QTimer::timeout,this,&Trajectory::serial_readyRead);
, 。
二、シリアルポートタイマー起動関数serial_timerstart();
void Trajectory::serial_timerstart()
{
timer->start(3);// , 3 ( )
buffer.append(serial.readAll());
}
三、シリアルポート読取関数部分;
void Trajectory::serial_readyRead()
{
unsigned char recvdata[255];
int recvnum=0;
timer->stop();// ,
qDebug() << "receive(buffer.toHex()):= " <vect1;
// "55aa"
while((index = buffer.toHex().indexOf(buffer0,index))='0'&&vect1[j][i]<='9')
recvdata[i]=vect1[j][i]-48;
else if(vect1[j][i]>='A'&&vect1[j][i]<='F')
recvdata[i]=vect1[j][i]-65+10;
else if(vect1[j][i]>='a'&&vect1[j][i]<='f')
recvdata[i]=vect1[j][i]-97+10;
else QMessageBox::warning(NULL, QString::fromLocal8Bit(" "),
QString::fromLocal8Bit(" "));
}
for(int i=0;i
四、デバッグ記録は以下の通りである.
receive(buffer.toHex()):="036fffff7d210000a97afd55aa2413740f00d9060000d00f00001cfcffffbc9afdffc748010043a795009a12b01100000000dc55aa2418740f009cf0ffffdcd1ffff39c1ffff2a7cfdff7e400100ea7d95009a12b01100000000b655aa241d740f00c91100004fecffff1ef5fffffb77fdff6d4d0100766595009a12b01100000000ee55aa2422740f0004a2ffff036fffff7d210000a97afdff2e4301006e7795009a12b01100000000f355aa2427740f00f310000063f5ffffd8dbffffeba4fdff15400100c03395009a12b01100000000ae55aa242c740f00649dffff35b6ffff6fe5ffff249afdff06500100ad2895009a12b01100000000f555aa2431740f006968000051060000bb020000879efdff3e5901007d3f95009a12b011000000003455aa2436740f00840b0000fcf0ffffcc8c00008081fdffbc2b0100626795009a12b011000000005e55aa243b740f0090ecffffd9ddffffc90a00004890fdff97440100fb5e95009a12b01100000000ee55aa2440740f00a4ddffff6afcffffa2e6ffff3f99fdffe52e0100316395009a12b01100000000ce55aa2445740f00ce8bffff7cbcffff9bd3ffff267dfdff38480100215c95009a12b011000000008455aa244a740f0033d9ffff4fe8ffff0e530000c48dfdff70460100f95095009a12b01100000000e055aa244f740f0086f1ffff935d0000a50e00002573fdffae470100af3995009a12b011000000008255aa2454740f00e76900009e8affff2ff1ffffe286fdff7b4201004a4195009a12b011000000003e55aa2459740f0030d5ffff7d4100006c080000b69dfdfff34601004f3e95009a12b011000000004d55aa245e740f002fd1ffffc43e000048170000bd93fdffd14d0100a43c95009a12b01100000000b155aa2463740f0033390000db2000008f0e0000bf79fdff34610100b45d95009a12b01100000000eb55aa2468740f0073cfffff2a6d0000be3d0000e0a5fdff4a3801006b7b95009a12b01100000000cd55aa246d740f00b82600007f28000036e9ffff69a8fdff3c3901006d7595009a12b011000000001d55aa2431740f006968"
receive(buffer.toHex().size()):= 25102 receive(buffer1):= "55aa2413740f00d9060000d00f00001cfcffffbc9afdffc748010043a795009a12b01100000000dc"receive(buffer1):= "55aa2418740f009cf0ffffdcd1ffff39c1ffff2a7cfdff7e400100ea7d95009a12b01100000000b6"receive(buffer1):= "55aa241d740f00c91100004fecffff1ef5fffffb77fdff6d4d0100766595009a12b01100000000ee"receive(buffer1):= "55aa2422740f0004a2ffff036fffff7d210000a97afdff2e4301006e7795009a12b01100000000f3"receive(buffer1):= "55aa2427740f00f310000063f5ffffd8dbffffeba4fdff15400100c03395009a12b01100000000ae"receive(buffer1):= "55aa242c740f00649dffff35b6ffff6fe5ffff249afdff06500100ad2895009a12b01100000000f5"receive(buffer1):= "55aa2431740f006968000051060000bb020000879efdff3e5901007d3f95009a12b0110000000034"receive(buffer1):= "55aa2436740f00840b0000fcf0ffffcc8c00008081fdffbc2b0100626795009a12b011000000005e"receive(buffer1):= "55aa243b740f0090ecffffd9ddffffc90a00004890fdff97440100fb5e95009a12b01100000000ee"receive(buffer1):= "55aa2440740f00a4ddffff6afcffffa2e6ffff3f99fdffe52e0100316395009a12b01100000000ce"receive(buffer1):= "55aa2445740f00ce8bffff7cbcffff9bd3ffff267dfdff38480100215c95009a12b0110000000084"receive(buffer1):= "55aa244a740f0033d9ffff4fe8ffff0e530000c48dfdff70460100f95095009a12b01100000000e0"receive(buffer1):= "55aa244f740f0086f1ffff935d0000a50e00002573fdffae470100af3995009a12b0110000000082"receive(buffer1):= "55aa2454740f00e76900009e8affff2ff1ffffe286fdff7b4201004a4195009a12b011000000003e"receive(buffer1):= "55aa2459740f0030d5ffff7d4100006c080000b69dfdfff34601004f3e95009a12b011000000004d"receive(buffer1):= "55aa245e740f002fd1ffffc43e000048170000bd93fdffd14d0100a43c95009a12b01100000000b1"receive(buffer1):= "55aa2463740f0033390000db2000008f0e0000bf79fdff34610100b45d95009a12b01100000000eb"receive(buffer1):= "55aa2468740f0073cfffff2a6d0000be3d0000e0a5fdff4a3801006b7b95009a12b01100000000cd"receive(buffer1):= "55aa246d740f00b82600007f28000036e9ffff69a8fdff3c3901006d7595009a12b011000000001d"receive(buffer1):= "55aa2472740f006eebffff2bedffff74260000287cfdffe04d03901006d765009a11b014000000004d"
五、プログラム分析:
1)最初のステップは、受信bufferをhex,bufferに変換する.toHex()は、上記のデバッグ記録の最初のデータセットを参照してください.
2)whileループにより、受信したバッファから「55 aa」で開始したすべてのデータフレームを検索し、検索した後、インデックス番号で開始したデータフレーム、後の80文字をbuffer 1に格納し、buffer 1のサイズが80であるか否かを判断し、受信したbuffer.toHex()で最後に1フレーム未満を検索したデータを排除する(デバッグレコード「55 aa 2431740 f 006968」)
3)80文字ビットを満たすデータbuffer 1をコンテナvect 1に格納し、vect 1定義:QVectorvect 1は、検索されたすべてのフレームデータをコンテナvect 1に連続的に格納し、インデックス番号変更(80加算)を検索し、次のフレームから検索を開始する.
while((index = buffer.toHex().indexOf(buffer0,index))
4)vect 1の各フレームデータを2つのforサイクルでそれぞれ16進バイトデータに処理する.例えば、文字'5'のASCII符号値は53、53-48=5、文字'a'のASCII符号値は97、97-97+10=0 x 0 a
for(int j=0;j { recvnum=0; qDebug() << "recvframenum:= "< for(int i=0;i {
if(vect1[j][i]>='0'&&vect1[j][i]<='9') recvdata[i]=vect1[j][i]-48; else if(vect1[j][i]>='A'&&vect1[j][i]<='F') recvdata[i]=vect1[j][i]-65+10; else if(vect1[j][i]>='a'&&vect1[j][i]<='f') recvdata[i]=vect1[j][i]-97+10; Else QMessageBox::warning(NULL,QString::fromLocal 8 Bit("警告")、QString::fromLocal 8 Bit("受信データエラー"); } for(int i=0;i { recvdata[recvnum]=recvdata[i]*16+recvdata[i+1]; qDebug() << "recvdata:= "< recvnum++; }
....
}
六、まとめ
1)indexOf()を使用して文字列の先頭から特定の文字列を検索し、インデックス番号で完全なデータフレームを検索する
2)コンテナvectを利用して検索したデータフレームを格納する