0

シリアル COM ポートを介してデバイスから送信されたデータを読み取ることができる必要がある Java ソフトウェアを開発しています。通信速度は私にとって非常に重要であるため、ボーレートは 921600 に設定されています。最初はすべてが機能します。うまくいきます (したがって、デバイスがシリアル ポート経由で送信する正しいデータを読み取ります) が、しばらくすると、ソフトウェアは間違ったデータを読み取り始めます。ソフトウェアが遅すぎて、実際にはデータの一部が入力バッファーに入っているときに失われているようです (おそらく、入力バッファーが初めて完全に満たされたとき)。読み取り操作を高速化するために、私は現在、ソフトウェアが読み取りごとにできるだけ多くのバイトを処理する読み取りアプローチを使用しています。また、入力バッファ サイズを大きくしようとしました (serialPort. setInputBufferSize(byte) メソッドを使用しましたが、私の問題は解決しませんでした) では、Java で高速シリアル通信を行ったことがありますか? 何か不足していますか?すべてがしばらく正常に動作し、その後正常に動作しなくなるのはなぜですか?

これは、読み取り部分 (駆動されている場合でも) の私のコードです。データ変換の部分をスキップしてください。これは、すべてのデータが実際には 2 バイトで構成されているため、txt ファイルに書き込む前にそれらを構成する必要があるためです。

/**
 *
 * @param evt
 */
@Override
public void serialEvent(SerialPortEvent evt) {

     switch(evt.getEventType()) {

        case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
            System.out.println("THE OUTPUT BUFFER IS EMPTY");
            break;

        case SerialPortEvent.DATA_AVAILABLE:
            try {     

                while(SerialPortEvent.DATA_AVAILABLE == 1) {


                   num_bytes = input.available();
                   array = new byte[num_bytes];

                   bytes_read = input.read(array, 0, num_bytes);

                   dato = new short[bytes_read];
                   datoc = new int[bytes_read/2];
                   datos = new String[bytes_read/2];


                   for(j=0;j<bytes_read;j++){                           
                       dato[j] = (short) (((byte) array[j]) & 0xff);
                   }

                   k = 0;
                   for(j=0;j<(bytes_read/2);j++){

                       datoc[j] = dato[k];
                       datoc[j] = (datoc[j]<<8) + dato[k+1];
                       datoc[j] = datoc[j] & 0xffffffff;  
                       k = k + 2;
                   }

                   for(j=0;j<(bytes_read/2);j++){

                       System.out.println(datoc[j]);
                       datos[j] = Integer.toString(datoc[j]);
                       output1.write(datos[j] + " ");
                   }

               }
            } catch(IOException ex) {
              logText = "Failed to read data. (" + ex.toString() + ")";
              System.out.println(logText);
            }
            break;

    }
4

2 に答える 2

0

シリアル通信の速度を低下させていたのは、 の使用でしSystem.out.println()た。それがなければ、データの受信は最終的にうまくいきました

于 2013-07-14T18:55:52.997 に答える
0

あなたのプログラムは、受信データを十分に速く処理できていないようです。入力がバッファに入り、バッファを空にすると、より多くの入力のためのスペースが増えるため、一定期間は機能します。しかし、データが全体的に処理するよりも速く入ってくる場合、最終的にはバッファがいっぱいになり、データがまだ入ってきて行き場がなくなります. このようなデータが (仮想) フロアにダンプされるのは、シリアル通信では一般的でした。

「バッファオーバーフロー」を示すステータスが設定されることも一般的です。最初に確認することは、シリアルデータの読み取りに使用しているライブラリでこのステータスが利用できるかどうか、および設定されるかどうか/いつ設定されるかを確認することです。これにより、上記が起こっていることが確認されます。

ご使用の環境で妥当な場合に確認するもう 1 つの点は、XON/XOFF 機能です。これは、一部のシリアル通信の機能であり、受信者が送信者にバッファーがほぼ満杯であることを示し、送信を停止 (XOFF) してから、送信を再開しても問題ないことが通知される (XON) ことを可能にします。すべてのハードウェアとソフトウェアがこの機能をサポートしているわけではありません。

なんらかの理由でそれが機能せず、これが実際に問題である場合は、データをより高速に処理するか、さらにバッファリングするというより良い仕事をする必要があります. 単純なブルート フォース アプローチは、バイトが入ってくるとストレージに書き込み、別のスレッドで読み取ることです。たとえば、これが従来のコンピューター システムの場合、それらをディスクに書き込んでからディスク ファイルを処理し、あるスレッドで読み取り用に開き、別のスレッドで書き込むことができます (なんて楽しい!)。

于 2012-10-04T17:39:19.117 に答える