C#アプリケーションとの通信にFirmataライブラリを備えたArduinoを使用していますが、COMポート構成コンポーネントはマシンごとに変わる可能性があるため、削除したいと思います...
次のことが可能ですか?
- システム内のCOMポートのリストを列挙しますか?(私のグーグルでは、かなり醜いWin32 APIコードを見てきましたが、もっとクリーンなバージョンがあることを期待しています)
- Arduinoに接続されているCOMポートを自動検出しますか?
この小さなコードは、これに対して非常にうまく機能しています (Arduino が検出された場合、COM ポート文字列、つまり「COM12」を返します)。
private string AutodetectArduinoPort()
{
ManagementScope connectionScope = new ManagementScope();
SelectQuery serialQuery = new SelectQuery("SELECT * FROM Win32_SerialPort");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(connectionScope, serialQuery);
try
{
foreach (ManagementObject item in searcher.Get())
{
string desc = item["Description"].ToString();
string deviceId = item["DeviceID"].ToString();
if (desc.Contains("Arduino"))
{
return deviceId;
}
}
}
catch (ManagementException e)
{
/* Do Nothing */
}
return null;
}
これを試してみてください。私は非常によく似たプロジェクトに取り組んでいます。また、誰でも自由に編集してください!
Arduino コードのセットアップ部分で、setupComms() メソッドを呼び出します。このメソッドは、「a」を受け取るまで単に「A」を出力します。「a」が受信されると、メインの loop() 関数にジャンプします。そのため、C# の部分は利用可能な各ポートで "A" をチェックし、"A" が見つかった場合は、Arduino へのポートを開いたことがわかります。
繰り返しますが、これはあまりきれいではないかもしれませんが、うまくいきます。コメントや提案をお待ちしています!
foreach (string s in SerialPort.GetPortNames())
{
com.Close(); // To handle the exception, in case the port isn't found and then they try again...
bool portfound = false;
com.PortName = s;
com.BaudRate = 38400;
try
{
com.Open();
status.Clear();
status.Text += "Trying port: " + s+"\r";
}
catch (IOException c)
{
status.Clear();
status.Text += "Invalid Port"+"\r";
return;
}
catch (InvalidOperationException c1)
{
status.Clear();
status.Text += "Invalid Port" + "\r";
return;
}
catch (ArgumentNullException c2)
{
// System.Windows.Forms.MessageBox.Show("Sorry, Exception Occured - " + c2);
status.Clear();
status.Text += "Invalid Port" + "\r";
return;
}
catch (TimeoutException c3)
{
// System.Windows.Forms.MessageBox.Show("Sorry, Exception Occured - " + c3);
status.Clear();
status.Text += "Invalid Port" + "\r";
return;
}
catch (UnauthorizedAccessException c4)
{
//System.Windows.Forms.MessageBox.Show("Sorry, Exception Occured - " + c);
status.Clear();
status.Text += "Invalid Port" + "\r";
return;
}
catch (ArgumentOutOfRangeException c5)
{
//System.Windows.Forms.MessageBox.Show("Sorry, Exception Occured - " + c5);
status.Clear();
status.Text += "Invalid Port" + "\r";
return;
}
catch (ArgumentException c2)
{
//System.Windows.Forms.MessageBox.Show("Sorry, Exception Occured - " + c2);
status.Clear();
status.Text += "Invalid Port" + "\r";
return;
}
if (!portfound)
{
if (com.IsOpen) // Port has been opened properly...
{
com.ReadTimeout = 500; // 500 millisecond timeout...
sent.Text += "Attemption to open port " + com.PortName + "\r";
try
{
sent.Text += "Waiting for a response from controller: " + com.PortName + "\r";
string comms = com.ReadLine();
sent.Text += "Reading From Port " + com.PortName+"\r";
if (comms.Substring(0,1) == "A") // We have found the arduino!
{
status.Clear();
status.Text += s + com.PortName+" Opened Successfully!" + "\r";
//com.Write("a"); // Sends 0x74 to the arduino letting it know that we are connected!
com.ReadTimeout = 200;
com.Write("a");
sent.Text += "Port " + com.PortName + " Opened Successfully!"+"\r";
brbox.Text += com.BaudRate;
comboBox1.Text = com.PortName;
}
else
{
sent.Text += "Port Not Found! Please cycle controller power and try again" + "\r";
com.Close();
}
}
catch (Exception e1)
{
status.Clear();
status.Text += "Incorrect Port! Trying again...";
com.Close();
}
}
}
}
すべての Try Catch ステートメントは、私が最初にテストしていたときからそこにあり、これまでのところうまくいきました。幸運を!
Arduino nano の中国語のクローンがデバイス マネージャーで COM ポートを正しく表示することに気付きましたが、次のコマンドを使用してすべてのポートを取得しようとすると、C# アプリの dorp down リストには表示されません。
using (var searcher = new ManagementObjectSearcher("SELECT * FROM WIN32_SerialPort"));
ただし、次を実行すると正しく表示されます。
foreach (string z in SerialPort.GetPortNames())
したがって、2 つのリストがあります。1 つは最初のコードの出力、もう 1 つは 2 番目のコードからの出力です。両方を比較すると、正しい COM ポートが見つかります。明らかに、元の Andurino Uno を使用すると、両方のコマンドがポートを正しく表示するため、このソリューションは、奇妙な理由で見えない中国のクローンに対してのみ機能します。using (var searcher = new ManagementObjectSearcher("SELECT * FROM WIN32_SerialPort"));
この方法では、arduino がコンピューターに接続されているポートを特定することはできません。
SerialPort.GetPortNames メソッド ()
// Get a list of serial port names.
string[] ports = SerialPort.GetPortNames();
Console.WriteLine("The following serial ports were found:");
Console.WriteLine("Aşşağıda Seri Bağlantı Noktaları Bulundu:");//For Turkish
// Display each port name to the console.
foreach(string port in ports)
{
Console.WriteLine(port);
}
Console.ReadLine();
このphpスクリプトを使用すると、arduinoからデータを送受信できます
<?php
/**
* Remember to go to Device Manager> Ports (COM & LPT)>Arduino XXX (COMXX)>right
* click>Properties>
* Port Settings>Advanced>uncheck "use FIFO buffers ........."
* In other hand, remeber that the Tx speed has to be the same in PhpConnect.php, in
* Arduino sketch and in the COM
* properties in Device manager, I selected 115200 b/s.
*
*/
// RX form PC**************
$t = $_POST['text1'];
include 'PruebaBatchCOM.php';
$puerto = escapeshellarg($usbCOM);
$dato = escapeshellarg($t);
exec("node C:\\xampp\\htdocs\\DisenoWEBTerminados\\BatteryTester\\Scripts\\writeandread.js {$puerto} {$dato} 2>&1", $output1);
$str = implode($output1);
$str1 = explode(",",$str);
$myJSON = json_encode($str1);// this is the response to AJAX
echo $myJSON;
?>
PruebaBatchCOM.php は
<?php
$puerto = array();
$file111 = "PruebaCOMRetrieve.bat";
exec($file111, $puerto);
$usbCOM = implode(",",$puerto);
?>
PruebaCOMRetrieve.bat
@echo off
setlocal
for /f "tokens=1* delims==" %%I in ('wmic path win32_pnpentity get caption
/format:list ^| find "Arduino Uno"') do (
call :setCOM "%%~J"
)
:: end main batch
goto :EOF
:setCOM <WMIC_output_line>
:: sets _COM#=line
setlocal
set "str=%~1"
set "num=%str:*(COM=%"
set "num=%num:)=%"
set port=COM%num%
echo %port%