none
センサとPCをシリアル通信させて、データをグラフ表示させたいのですが。 RRS feed

  • 質問

  • Arduino(市販のボード)にセンサをつけ、測定データをPCにグラフ表示させたいと考えています。SerialPortを用いて、テキストボックスに
    数値を表示させることには成功しました。次にこの数値をグラフ表示させようとコードを追加したところ、「TargetInovocationExceptionは
    ハンドルされませんでした」のエラーが出力され、プログラムが中断させれてしまいます。どのような原因が考えられるのでしょうか。
            略
            private SerialPort port;
            private byte[] readBuffer = new byte[1024];
            private delegate void AppendMessageDelegate(string mes);
            
            private int[] numBuff = new int[1024];
            int len = 0;
    
        略
    this.port.DataReceived += new SerialReceivedEventHandler(port_DateReceived);   //ここでデータを読み込みます
       略
    void port_DateReceived(object sender,SerialDataReceivedEventArgs e)
    {
     len = this.port.Read(readBuffer, 0, readBuffer.Length);
               string str = Encoding.GetEncoding("Shift_JIS").GetString(readBuffer, 0, len); //まずバイトデータを文字データに変換
    
               this.BeginInvoke(new AppendMessageDelegate(AppendMessage),
                   new object[] { str });
           
           }
        
            private void AppendMessage(string msg)
            {
                this.textBox1.AppendText(msg); //文字を表示します
                
                numBuff[len] = int.Parse(msg);  //文字を整数データに
                len++;
               if (len > 10)   //データが10たまったら描画します
                {
                    method_Picture(); //後述のグラフ描画メソッドです
             
                }
    
                len = 0;
    
            }
          略
       
     private void method_Picture()
            {
                Bitmap bmp = new Bitmap(pictureBox1.Width,pictureBox1.Height);
                pictureBox1.Image = bmp;
                Graphics g = Graphics.FromImage(pictureBox1.Image);
                g.DrawLine(Pens.Red,0,pictureBox1.Height/2,pictureBox1.Width,pictureBox1.Height/2);
    
    
                for(int i=0;i<len;i++)
                {
                    int Ynow = 100 - numBuff[i];
                    int Ynext= 100 - numBuff[i+1];
                    int j = 2 * i;
    
                    g.DrawLine(Pens.Blue,new Point(j,Ynow),new Point  ((j+2),Ynext));
                }
    
            }
    
    

    hibari
    2009年8月6日 6:14

回答

  • ご回答、ありがとうございました。ReadLineを使ったところ、当初の予定通り動作しました。

    同じ開発プロジェクトで今後とも質問させていただく場合もあるかと存知ますが、その際は

    是非、よろしくお願いいたします。


    hibari
    • 回答としてマーク hibari 2009年8月9日 12:19
    2009年8月7日 1:44

すべての返信

  • 受信データの読み取り方法に問題があります。
    バイト列で読み込んでいますがきちんと数字で分割していません。

    「数字+改行コード+数字」といった状態でInt.Parseに突っ込むとTargetInovocationExceptionのエラーを吐きます。
    つまりint.Parse("1\r\n2")を実行すると再現できます。

    SerialPortのEncodingをあらかじめ指定した上で、ReadLineを使用すれば、改行コードで分割して読み取ってもらえます。
    ReadLineでブロックされるのがいやでしたら、読み取ったバイト列を文字列に変換した上で改行コードを分割分離する処理を追加してください。

    int.Parseを単純に行うとシリアル通信で文字化けがあったりするとエラーになります。
    TryParseを使うかTry~Catchでエラー対策しましょう

    あと、データが10たまったらmethod_Pictureを呼び出したいようですが、len=0と毎回セットされていて呼び出されていません。
    • 回答の候補に設定 Jitta 2009年8月9日 23:36
    2009年8月6日 9:06
  • ご回答、ありがとうございました。ReadLineを使ったところ、当初の予定通り動作しました。

    同じ開発プロジェクトで今後とも質問させていただく場合もあるかと存知ますが、その際は

    是非、よろしくお願いいたします。


    hibari
    • 回答としてマーク hibari 2009年8月9日 12:19
    2009年8月7日 1:44