Arduino シリアル通信 その2:visual C#

バージョン情報
Arduino Uno , Arduino IDE 1.0.5 , Visual C# 2013 , Visual Studio Express 2013 for Windows Desktop , windows 8.1

Arduinoを使ってシリアル通信を試してみた。その2。

今回の実験内容
アナログセンサ : フォトリフレクタ

Arduino

PC : Visual C#でグラフ化

Arsuino側は前回と同じ。

写真
IMG_201405271084

回路図
回路図

【Arduinoのスケッチ】
時間とデータをカンマでつないだ文字列として送信。

int analog_in = 0;
int val = 0;
String str_send_data;
unsigned long sTime = 0;        //プログラム開始時間
unsigned long cTime = 0;        //sTimeからの経過時間
unsigned long rTime = 0;        //サンプリングレート調整用

void setup() {                
  Serial.begin(38400);
  sTime = millis();
}

void loop() {
  cTime = millis() - sTime;
  rTime = millis();
  val = analogRead(analog_in);
  str_send_data = String(cTime) + "," + String(val);
  Serial.println(str_send_data);
  while(millis() - rTime < 100){
    delay(1);
  }
}

ここから今回のチャレンジ内容。はじめてのVisual Studioに戸惑いながらもなんとか動くところまでやってみた。

プロジェクトの作成

新しいプロジェクトがから、Visual C# Windows フォームアプリケーションを選択してプロジェクトを作成すると、以下のようなファイルが自動で生成される。
solution_explorer_00

【Program.csの中身】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication3
{
    static class Program
    {
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Main関数の中でForm1が生成されているのかな。

【Form1.csの中身】

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}

フォームの作成

ツールボックスを使ってフォームをつくっていく。流石の”Visual”、お手軽。

Form1_01

続いてプロパティウィンドウでプロパティを設定していく。
特に大事な部分はserialPortの設定でArduinoの設定合わせて以下のように設定する。
proparty_serial

コード作成

次にSerialPortの受信詩時のイベントを実装する。
プロパティウィンドウでイベントを表示させてDataReceivedの部分をダブルクリックするとForm1.csの中にコードが生成される。

proparty_serial_event

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {

        }

この中に受信時の動作をつくればよいみたいだ。今回は以下の二つを実行。
1.受信した文字列をテキストボックスに追加
2.受信した文字列を時間とアナログ値で散布図に表示(時間の経過と共に左に流れていく)。
その他に接続ボタンで通信開始、切断ボタンで通信終了するコードを書くと、Form1.csはこのようになる。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _20140604_serial_test01
{
    public partial class Form1 : Form
    {
        string RxString;

        public Form1()
        {
            InitializeComponent();
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            RxString = serialPort1.ReadLine();
            this.Invoke(new EventHandler(DisplayText));
            this.Invoke(new EventHandler(showChart));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
        }

        private void DisplayText(object sender, EventArgs e)
        {
            textBox1.AppendText(RxString + Environment.NewLine);
        }

        private void showChart(object sender, EventArgs e)
        {
            string[] strArrayData = RxString.Split(',');
            int x = int.Parse(strArrayData[0]);
            int y = int.Parse(strArrayData[1]);

            chart1.Series["Series1"].Points.AddXY(x, y);

            chart1.ChartAreas[0].AxisX.Maximum = x;
            chart1.ChartAreas[0].AxisX.Minimum = x - 10000;

        }

    }
}

実行結果はこんな感じ
result_image_00

processingよりシンプルにできたような気がする。
visual studioの使い方に慣れるまで大変な気もするがなんとかなるかな。

【今回のはまりポイント】
・シリアル通信の設定をどこですれば良いか、Google先生に聞きまくった。
・chartオブジェクトのプロパティ探し。
・イベント実行時のFormの更新が理解できていない。
 この部分 ↓ 、おいおい勉強しよう。

this.Invoke(new EventHandler(DisplayText));
this.Invoke(new EventHandler(showChart));

Arduino シリアル通信 その2:visual C#」への3件のフィードバック

  1. 大変参考になりました。ありがとうございました。
    C#おもしろいですね。はじめてでしたが、今の印象はJavaより作りやすい気がしてます。
    ArduinoのプログラムでSerial通信のbpsが38400になっていますが、9600ではないでしょうか
    当方まったくの素人ですので・・・。もしくは38400で問題ないようでしたらご教授願います。

    1. コメントありがとうございます。
      通信速度について、38400で問題なく動作しました。9600でも動作すると思います。(試してません。)
      ポイントは以下の二つです。
      ・通信相手の通信速度と合わせる: 今回はC#側のSerialPort の BaudRate。
      ・通信の量とタイミング : 今回は100ミリ秒に一回の送信。
      参考になれば幸いです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です