C#でCOMポート番号とシリアル接続機器名を同時に取得する方法
マイコン機器とデータ通信を行う方法としては、
シリアル通信(RS-232)を行うことがメジャーだと思います。
.NET Framework 2.0以降ではSerialPortクラスが実装され、
シリアル通信を行うプログラムを書くのがお手軽になりました。
http://msdn.microsoft.com/ja-jp/library/system.io.ports.serialport(v=vs.110).aspx
有効なCOM番号の取得
シリアル機器とPCを接続しているときに、
SerialPortクラスのGetPortNameクラスを呼べば、
現在有効なCOM番号が出てきます。
ShowSerialPortNum.cs
using System; using System.IO.Ports; namespace ShowSerialPortNum { class ShowSerialPortNum { public static void Main() { string[] ports = SerialPort.GetPortNames(); foreach(string port in ports) { Console.WriteLine(port); } Console.ReadLine(); } } }
出力例(COM8が有効なとき)
COM8
接続している機器が1台だけなら気にせずそこに繋げればOK。
でも複数台接続をしていたらどのCOM番号が何と接続しているのかわからない。
そんなときは、
「マイコンピュータ右クリック」→「プロパティ」
→「デバイスマネージャ」→「ポート(COMとLPT)」
とデバイスマネージャを参照して確認する必要があり、
ユーザーに対して不親切だし非常にメンドクサイ。
頼みのSerialPortクラスもそこまでは教えてくれないので、
頑張って別の方法を使って探しに行きます。
COM番号と接続機器名の取得
方法としてはWMIのWin32_PnPEntityクラスを使って、
上記したデバイスマネージャに記述されている内容を拾いに行きます。
ShowSerialPortName.cs
using System; using System.Management; namespace ShowSerialPortName { class ShowSerialPortName { public static void Main() { string[] ports = GetDeviceNames(); if(ports != null) { foreach (string port in ports) { Console.WriteLine(port); } } Console.ReadLine(); } public static string[] GetDeviceNames() { var deviceNameList = new System.Collections.ArrayList(); var check = new System.Text.RegularExpressions.Regex("(COM[1-9][0-9]?[0-9]?)"); ManagementClass mcPnPEntity = new ManagementClass("Win32_PnPEntity"); ManagementObjectCollection manageObjCol = mcPnPEntity.GetInstances(); //全てのPnPデバイスを探索しシリアル通信が行われるデバイスを随時追加する foreach (ManagementObject manageObj in manageObjCol) { //Nameプロパティを取得 var namePropertyValue = manageObj.GetPropertyValue("Name"); if (namePropertyValue == null) { continue; } //Nameプロパティ文字列の一部が"(COM1)~(COM999)"と一致するときリストに追加" string name = namePropertyValue.ToString(); if (check.IsMatch(name)) { deviceNameList.Add(name); } } //戻り値作成 if (deviceNameList.Count > 0) { string[] deviceNames = new string[deviceNameList.Count]; int index = 0; foreach (var name in deviceNameList) { deviceNames[index++] = name.ToString(); } return deviceNames; } else { return null; } } } }
出力例(COM8にArduino Unoを接続しているとき)
Arduino Uno (COM8)
やっていることとしては、
ManagementClassのコンストラクタに
Win32_PnPEntityクラスを指定して、
GetInstances()メソッドを呼び出すことで、
プラグアンドプレイデバイスのコレクション配列を取得
ManagementClass mcPnPEntity = new ManagementClass("Win32_PnPEntity"); ManagementObjectCollection manageObjCol = mcPnPEntity.GetInstances();
コレクションの要素を順次アクセスし、
GetPropertyValue関数でNameプロパティを取得。
Nameプロパティで得られたオブジェクトが、
デバイスマネージャ上で表示される値みたいです。
その後正規表現で"(COM1-999の番号)"が含まれるデータのみを抽出。
foreach (ManagementObject manageObj in manageObjCol) { //Nameプロパティを取得 var namePropertyValue = manageObj.GetPropertyValue("Name"); if (namePropertyValue == null) { continue; } //Nameプロパティ文字列の一部が"(COM1)~(COM999)"と一致するときリストに追加" string name = namePropertyValue.ToString(); if (check.IsMatch(name)) { deviceNameList.Add(name); } }
これでデバイス名とCOM番号を同時に取得します。
COM番号は文字列から数値を抜き出せばOKです。
参考
http://www-ice.yamagata-cit.ac.jp/ken../senshu/sitedev/index.php?AVR%2Favrdude36#xceb3d84
http://www.wmifun.net/library/win32_pnpentity.html
Androidで外部保存域の空き容量を取得する
Androidで無造作にデータを保存して、
空き容量が無いってことをしないために。
検索でよく引っかかったのが
StatFsクラスのgetAvailableBlocksメソッドを使う以下の例
long freeByteSize = 0; String state = Environment.getExternalStorageState(); //外部保存領域が使用可能かチェック if(Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { //サイズ取得 StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath()); freeByteSize = (long)statFs.getBlockSize() * (long)statFs.getAvailableBlocks(); }
しかしこのソースEclipse(ADT)では、
メソッド getBlockSize() は型 StatFs で使用すべきではありません
メソッド getAvailableBlocks() は型 StatFs で使用すべきではありません
と警告を受けます。
警告は無視しても作れますが気になるので別の方法を調べたところ、
どうやらAndroid API 9からは FileクラスのgetFreeSpaceが使えるらしい。
long freeByteSize = 0; String state = Environment.getExternalStorageState(); //外部保存領域が使用可能かチェック if(Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { //サイズ取得 freeByteSize = Environment.getExternalStorageDirectory().getFreeSpace(); }
これで警告も消えて一安心。
参考
http://stackoverflow.com/questions/8133417/android-get-free-size-of-internal-external-memory
http://www.techdoctranslator.com/android/guide/data-storage
Android4.4(KitKat)でsendBroadcastの強制マウントメディアスキャンを行うと落ちる
Androidアプリ内で作成した画像等のデータファイルをストレージに保存したのにファイルが確認できない。
って時に使うように紹介されている魔法のコード
sendBroadcast( new Intent( Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory() ) );
これAndroid4.4ではエラーを吐きます。
解決策
http://www.taosoftware.co.jp/blog/2013/11/android44kitkattpacketcapture.html