2012-02-03 20 views
0

カメラとのインターフェイスにシリアルポートを使用しようとしています。現在のところ、カメラには独自のプロトコルがあり、これはかなりシンプルで、6バイトのコマンドと確認応答を使用します。C#SerialPort - Strange Behavior

今、私はWPFを使用できるので、カメラとインターフェイスするプログラムを書くためにC#を使用していますが、とにかくC#で快適です。

画像を取得するようにカメラを設定しようとすると、私の問題が発生します。シリアルポートオブジェクトは、プログラムをステップ実行したときに、これを行う上で絶対にうまく動作します。しかし、私がフルスピードで実行するとすぐに、何らかの理由で私はポートのメッセージが非常にひどく読み込まれていても見逃してしまいます。実際のデータを取得し始める直前に、セットアッププロセスが終了します。まだポートにバッファ内にあるコマンドやものは残っています。

今、この解決策は、プロトコルを学んで現時点で問題を解決する非常にハッキリな試みであり、私は完全に後で改善するつもりですが、なぜそれがこれを行うのか分かりません。カメラは、最後のパケットを確認するまで次のパケットを送信することは想定されていないので、シリアルポートオブジェクトに問題があります。カメラまたはプロトコルの処理ではありません。

私は(遅い、はい)UIスレッドでこの機能を持っている可能性がありますか?ここで

はコードです:ここでは

private void retreivePhoto() 
    { 
     progressBar1.Visibility = Visibility.Visible; 
     photo = new FileStream(Environment.CurrentDirectory + @"/photos/" + (photoNum++) + ".jpg", FileMode.OpenOrCreate); 
     port.Open(); 
     progressBar1.Value = 0.5; 
     setup.theMessage = setup.JPEG(); 
     port.Write(setup.theMessage, 0, setup.theMessage.Length); 
     while (port.BytesToRead < 0) ; 
     port.Read(received.theMessage, 0, received.theMessage.Length); 
     setup.theMessage = setup.Package(); 
     port.Write(setup.theMessage, 0, setup.theMessage.Length); 
     while (port.BytesToRead < 0) ; 
     port.Read(received.theMessage, 0, received.theMessage.Length); 
     setup.theMessage = (byte[])Message.SNAPSHOT.Clone(); 
     port.Write(setup.theMessage, 0, setup.theMessage.Length); 
     while (port.BytesToRead < 0) ; 
     port.Read(received.theMessage, 0, received.theMessage.Length); 
     setup.theMessage = (byte[])Message.BLANK.Clone(); 
     setup.theMessage[1] = (byte)Message.MessageTypes.GETPICTURE; 
     setup.theMessage[2] = (byte)Message.PictureType.SNAPSHOT; 
     port.Write(setup.theMessage, 0, setup.theMessage.Length); 
     while (port.BytesToRead < 0) ; 
     port.Read(received.theMessage, 0, received.theMessage.Length); 
     while (port.BytesToRead < 0) ; 
     port.Read(received.theMessage, 0, received.theMessage.Length); 
     int length = (received.theMessage[5] << 16) + (received.theMessage[4] << 8) + received.theMessage[3]; 
     length /= data.theMessage.Length-6; 
     byte[] temp = {0xaa, 0x0e, 0x00, 0x00, 0x00, 0x00}; 
     port.DiscardInBuffer(); 
     port.Write(temp, 0, temp.Length); 

     int next = 0; 
     int bytes; 

     for (int i = 0; i < length; i++) 
     { 
      if ((bytes = port.BytesToRead) > 0) 
      { 
       port.Read(data.theMessage, 0, data.theMessage.Length); 
       if (bytes < data.theMessage.Length) 
       { 
        photo.Write(data.theMessage, 4, bytes - 6); 
       } 
       else 
       { 
        photo.Write(data.theMessage, 4, data.theMessage.Length - 6); 
       } 
       photo.Flush(); 
      } 


      next = ((data.theMessage[1] << 8) + data.theMessage[0]) + 1; 

      byte[] nextBytes = System.BitConverter.GetBytes(next); 

      if (length - i == 1) 
      { 
       temp[4] = temp[5] = 0xf0; 
      } 
      else 
      { 
       temp[4] = nextBytes[0]; 
       temp[5] = nextBytes[1]; 
      } 

      port.Write(temp, 0, temp.Length); 
     } 

     progressBar1.Value = 1.0; 
     photo.Flush(); 
     photo.Close(); 
     port.Close(); 
     progressBar1.Visibility = Visibility.Hidden; 

    } 

は、プロトコルを記述し、カメラのデータシートです。

+1

私の目 - 潜在的な応答に魅力的に見えるようにコードをレイアウトしてみてください – AnthonyBlake

+1

おそらく、while(port.BytesToRead <0)ではなくイベントを使う方が良いでしょう。 – sll

+1

Take 'serliaPort.ErrorReceived'と' serialPort.DataReceived'イベントを見てください – sll

答えて

1
while (port.BytesToRead < 0) ; 
port.Read(received.theMessage, 0, received.theMessage.Length); 

http://www.4dsystems.com.au/downloads/micro-CAM/Docs/uCAM-DS-rev7.pdfあなたがreceived.theMessage.Lengthバイトを読み取ることを意味するものではありません。 1 & received.theMessage.Lengthの間であれば何でもかまいません。返された値を確認する必要があります

+0

これが問題だとわかりました。これに該当する特別な理由はありますか?なぜ私のバッファにできるだけ多くのデータを埋め込むだけではないのですか? – Luke

+0

お使いのデバイス(シリアル通信)の速度がコンピュータの速度より遅い。利用可能なバイトがすぐに読み始めます。おそらくデバイスがまだ2番目のバイトを送信していない可能性があります。 –

+0

私は参照してください。さて、一度にたくさんのバイトを読み込むようにコードを変更しました。これがうまくいくかどうかわかります。 – Luke