
みなさんもVisual C#でArduinoと通信してみたいということがあると思います。
ここではシリアルポートを開いたのち、C#からのデータを受け取り、Arduinoが文字列を送り返す、というプログラムを作ります。
参考:C#でフォームアプリケーション(当サイト)
C#でシリアル通信を行う(外部サイト)
ツールボックスから「SerialPort」コントロールをフォームへドラッグ&ドロップします。
すると、[デザイン]タブの下にコントロールが追加されます。
今回はArduinoの接続されているCOMポートを「コンボボックス」から選択し、「ボタン」を押すと通信を開始、受け取った文字列を「ラベル」2に表示する仕様にしたいと思います。
コンボボックスのプロパティ、「Item」には、「COM1 ~ COM5」の文字列を入力しておきます。
これらアイテムには0~行数-1の数値が割り振られます。
ボタンには、「Click」したときに発生するイベントを設定しておきます。
下のシリアルポートオブジェクトを選択して、こいつにもイベントを設定します。
ここには、シリアルポート接続機器からデータを受け取った時に発生するイベント、「DataReceived」メソッドを設定します。
コード側で、ボタンのClickイベントとシリアルポートのDataReceivedイベントの中身をそれぞれ記入します。
using System;
using System.Windows.Forms;
using System.Threading;
namespace arduino_sample1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void start_serial(object sender, EventArgs e)
{
if (button1.Enabled)
{
serialPort1.PortName = comboBox1.SelectedItem.ToString(); // 選択されたCOMをポート名に設定
serialPort1.Open(); // ポートを開く
serialPort1.Write("A"); // ポートへ適当な文字列を書き込む
button1.Enabled = false; // ボタンを押した直後、利用不能にしておく
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
string data = serialPort1.ReadExisting(); // ポートから文字列を受信する
if (!string.IsNullOrEmpty(data))
{
Invoke((MethodInvoker)(() => // 受信用スレッドから切り替えてデータを書き込む
{
label2.Text = data; // ラベルを受信した文字列へ変更
Thread.Sleep(1);
button1.Enabled = true; // ボタンを押せるようにしておく
}));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
C#側はこれで準備OK。今度はArduinoへ下記のコードを書き込みます。
int inByte = 0;
int SA = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
SA = Serial.available(); // シリアルポートにデータがあるかを確認
if(SA > 0){
inByte = Serial.read(); // データを読み込む
if(inByte==65){
Serial.print("Done."); // ASCIIコードで"A"だった場合に"Done."を送信
delay(1000); // 通信用の待機時間
}
}
}
さあこれをArduinoへ書き込んだところで、C#も走らせてみましょう。