バージョン情報
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側は前回と同じ。
【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 フォームアプリケーションを選択してプロジェクトを作成すると、以下のようなファイルが自動で生成される。

【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”、お手軽。
続いてプロパティウィンドウでプロパティを設定していく。
特に大事な部分はserialPortの設定でArduinoの設定合わせて以下のように設定する。

コード作成
次にSerialPortの受信詩時のイベントを実装する。
プロパティウィンドウでイベントを表示させてDataReceivedの部分をダブルクリックするとForm1.csの中にコードが生成される。
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;
}
}
}
processingよりシンプルにできたような気がする。
visual studioの使い方に慣れるまで大変な気もするがなんとかなるかな。
【今回のはまりポイント】
・シリアル通信の設定をどこですれば良いか、Google先生に聞きまくった。
・chartオブジェクトのプロパティ探し。
・イベント実行時のFormの更新が理解できていない。
この部分 ↓ 、おいおい勉強しよう。
this.Invoke(new EventHandler(DisplayText)); this.Invoke(new EventHandler(showChart));









大変参考になりました。ありがとうございました。
C#おもしろいですね。はじめてでしたが、今の印象はJavaより作りやすい気がしてます。
ArduinoのプログラムでSerial通信のbpsが38400になっていますが、9600ではないでしょうか
当方まったくの素人ですので・・・。もしくは38400で問題ないようでしたらご教授願います。
コメントありがとうございます。
通信速度について、38400で問題なく動作しました。9600でも動作すると思います。(試してません。)
ポイントは以下の二つです。
・通信相手の通信速度と合わせる: 今回はC#側のSerialPort の BaudRate。
・通信の量とタイミング : 今回は100ミリ秒に一回の送信。
参考になれば幸いです。