Arduino実験機2号~PHPからリレーを制御
Sunday, 18 July 2010
ThumbnailArduino(公式サイト)を使えば、現実の世界とコンピューターとを結び付けて、アイデア次第で色々なことが出来るようになることは言うまでもありません。

世の中には既にArduino(またはそれに準ずるもの)を使って、役に立つものから遊び心溢れるものまで出揃っていますが、そろそろ生活に役立ちそうなものを考えてみようと言うことで、Arduinoでコンセント(AC120V)をコントロールする回路を作ってみようと思います。

コンセントのON/OFFにはリレーが必要ですが、Arduinoと同じ5V駆動のリレーを使ったとしても、当然ながらArduinoのデジタル入出力端子からはコントロールできません。

リレーをON/OFFするには、Arduinoのデジタル入出力端子からの微弱電流を増幅してリレーを駆動させるような回路が必要です。
ネットで検索してみると、先人の知恵と言うか回路図が簡単に見つかるので、ちょっと拍子抜け感がありますが、トランジスタ、ダイオードと抵抗と言うシンプルな構成でリレーを駆動させることが可能なようです(参考リンク)。

問題はコンピューター側のソフトウェアで、Flashを使ってお洒落なインターフェイスにするのも一興ですが、とりあえずきちんとリレーを制御できるかどうかを見るだけであれば、通信も頻繁にする必要はないですし、リレーのON/OFFの信号さえやり取りできれば良いので、今回はPHPを使ってリレーをON/OFFするようにしてみます。

PHPでArduinoをコントロールする方法は大きく分けて二つ、FlashとArduinoを通信させるために使用した、serproxy等のサーバーを介してTCPからcomポートへ信号を転送する方法と、PHPから直接comポートを操作する方法です。

今回はPHPからせっかく直接comポートを操作できるので、そちらを使用してみることにします。

PHPでArduinoと通信できれば、その時点で基本的にはあらゆるネットワーク上からArduinoを操作できることになり、Flashよりも更に簡単に色んなことが出来るようになります。

では早速、PHPのコードはこんな感じでしょうか。
<?php
$comPort="com4";
exec('mode com4: baud=9600 data=8 stop=1 parity=n xon=off to=off dtr=off',$output);

if ($_POST["chk"]!="") {
	$key=$_POST["chk"];
	serialWrite($key);
}

function serialWrite($key) {
	global $comPort;
	$fd = fopen($comPort, "w");
	fputs($fd,$key);
	sleep(1);
	fclose($fd);
}
?>

<html>
<head><title>Socket Communication Test</title></head>
<body>
<h1>Relay Control Via PHP</h1>
<pre><?php echo implode("\n",$output);?></pre>
<form method="post" action="<?php echo $PHP_SELF;?>">
	<input type="hidden" value="0" name="chk">
	<input type="submit" value="Switch">
</form>
</body>
</html>
comポートの番号は適宜変更が必要です。

実は何度試してもリレーがON/OFFせず諦めかけていたんですが、comポートの状態を何気に出力させた時、”DTR circuit: ON”になっていることに気が付きました。

ネットにあるガイドのほとんどは、dtrオプションについて触れられていませんでしたが、試しに”dtr=off”を含めて指定すると、無事にリレーがON/OFFするようになりました

動作の仕組みとしては、GETなりPOSTなりで”0”を送信、PHP側で”0”を検出したら、comポートにそのまま送り、後はArduino側に任せると言うシンプルなものです。

Arduino側は、
#define RELAY_PIN 3
#define LED_PIN 13
void setup()
{
  pinMode(RELAY_PIN, OUTPUT);
  Serial.begin(9600);
}
void loop()
{
  static int relayVal = 0;
  int cmd;
  while (Serial.available() > 0)
  {
    cmd = Serial.read();
    if (cmd==48){
        relayVal ^= 1;
        if (relayVal){
          digitalWrite(LED_PIN,HIGH); //Relay ON
          Serial.println("ON");
        }else{
          digitalWrite(LED_PIN,LOW); //Relay OFF
          Serial.println("OFF");
        }
    }
    if (relayVal)
      digitalWrite(RELAY_PIN, HIGH);
    else
      digitalWrite(RELAY_PIN, LOW);
   }
}
こんな感じで、シリアルポートから”0”を受け取ったらリレーON/OFF用のデジタル端子をON/OFF、一応目視でリレーの状態が分かるように13ピンも連動してON/OFFさせます。

欲を言えば、現在のリレーの状態をArduinoからシリアルポート経由で取得し、ウェブページに反映させたいものですが、何をやってもうまく行きません

ネットで調べてみると、どうやらWindows上で動作しているPHPではシリアルポートの読み込みができない模様です。

手元にWindows以外の環境がないので試せていませんが、今回はテストが目的なのでとりあえず良しとしておきましょう。

自宅の無線LAN上にあるサーバーに取付けて、携帯からアクセス、Arduinoに接続した卓上ランプなんかをON/OFFすれば、何気に感動的です。

Dim lights