PHPベースのWebインターフェースでArduino Unoを制御する構築ガイド
必要な部品と用品
| Arduino UNO | ×1 |
| Arduino Ethernet Shield 2 | ×1 |
| DHT11 温湿度センサー(4ピン) | ×1 |
| 2回路リレーモジュール | ×4 |
| ミニブレッドボード | ×1 |
| 炎センサー | ×1 |
| MQ4 ガスセンサー(メタン等) | ×1 |
| LDR(光依存抵抗) | ×1 |
| 土壌湿度センサー(Hygrometer) | ×3 |
| ADSLルーターケーブル(LANケーブル) | ×1 |
| プラグ(1極) | ×7 |
| ソケット(1極) | ×7 |
| 9V電池 | ×1 |
| 9V電池バレルケーブル | ×1 |
必要な工具・機器
- ホットグルーガン
使用ソフトウェア
- Apache HTTP Server(ローカルホスト用)
- Notepad++(コード編集)
- Arduino IDE
プロジェクト概要
アップデート
新プロジェクト TheAmplituhedron.com では、サーバーサイドプログラミングを代行し、データパケットの送受信を容易にします。ご支援はWebサイトからどうぞ。
説明
水槽と庭の灌漑システムをWebから制御・監視するため、Apacheローカルホスト上に4つのPHPページ(Arduinautomotion.php, Arduinautomotioncontrol.php, Arduinautomotionformvalue.php, Arduinautomotioncommunication.php)を構築しました。一方、Arduino Ethernet Shield側でもWebサーバー(ArduinoSide.php)を動かし、相互通信を行います。
2週間の休暇中に水槽のフィルター停止や給餌を遠隔操作したいという動機から開発しました。水槽制御6項目(エアポンプ、ライト、給餌、ヒーター、外部/内部フィルター)と灌漑制御1項目をWeb UIから操作可能です。また、DHT11(温湿度)、MQ4(可燃ガス)、LDR(照度)、土壌湿度×3のセンサーデータを取得・表示できます。
HTML/CSS/JavaScript/PHP/jQueryの知識があれば全コードを理解・カスタマイズ可能です。本記事はショーケースとして主要部分を掲載します。


2つのPHPページ間でデータをやり取りする仕組み
- HTMLフォーム + PHP
$_POST/$_GET+$_SESSIONでページ間データ永続化 POSTはセキュアだが実装がやや複雑。Arduinoとの通信にはGETが簡単なので併用- 参考: PHP Forms, PHP Sessions
Apache HTTP Serverでのローカルホスト構築
筆者環境: AppServ → www フォルダに配置。自分のローカルIP(例: https://192.168.1.20/Arduinautomotion.php)でアクセス。

Android端末からローカルホストへアクセス
同一Wi-Fiネットワーク内で、PCのローカルIPをブラウザに入力。Windows設定手順は StackOverflow 参照。
Wi-Fi経由で外部からローカルホストへアクセス(ポートフォワーディング)
グローバルIP + ポートフォワーディングで可能だが、セキュリティリスクに注意。参考リンク, ポートフォワーディング解説
各PHPページの役割
Arduinautomotion.php(メインUI)
Arduinoとの通信ハブ。部屋・水槽・植物・ガイドの4セクションで構成。センサー値に応じて円アイコンの色が変化(緑=正常、橙=最適、赤=危険、黄=ON、白=OFF)。危険値検知時はSpider-Manアラート(音声+動画)を表示。

Arduinautomotioncontrol.php
セッション変数を一元管理し、他ページからのデータを永続化。
Arduinautomotionformvalue.php
フォーム送信値を受け取り、セッション保存 & ArduinoSideへ転送(隠しフォームでGET送信)。ガイドセクションにiframeで埋め込み可能。
Arduinautomotioncommunication.php
ArduinoSideからのGETパラメータを受け取り、セッション更新後、メインページへリダイレクト。
ArduinoSide(Ethernet Shield上のWebサーバー)
固定IP(例: 192.168.1.21)でアクセス可能。センサー値を隠しフォームにセットし、「Communication」ボタン押下でArduinautomotioncommunication.phpへ送信。

配線接続
Arduino DHT11 Pin 2 2 Way Relay (1) Pin 3, Pin 4 2 Way Relay (2) Pin 5, Pin 6 2 Way Relay (3) Pin 7, Pin 8 2 Way Relay (4) Pin 9 Ethernet Shield Pin 10-13 (SPI専用) LDR A0 Flame Sensor A1 MQ4 Sensor A2 Hygrometer (1) A3 Hygrometer (2) A4 Hygrometer (3) A5


※ Ethernet Shield使用時はPin 10-13がSPI専用になるため、リレー等はPin 3-9、センサーはアナログピンを使用。
Arduinoスケッチ(抜粋・主要部)
#include <SPI.h>
#include <Ethernet.h>
#include "DHT.h"
DHT dht;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 21);
EthernetServer server(80);
int pump=3, lamp=4, feed=5, heater=6, filterex=7, filterin=8, irrigation=9;
String readString;
void setup() {
Serial.begin(9600);
pinMode(pump,OUTPUT); ... pinMode(irrigation,OUTPUT);
digitalWrite(pump,HIGH); ... digitalWrite(irrigation,HIGH); // リレーはLOWアクティブ前提
dht.setup(2);
Ethernet.begin(mac, ip);
server.begin();
Serial.println(Ethernet.localIP());
}
void loop() {
delay(dht.getMinimumSamplingPeriod());
float humidity = dht.getHumidity();
float temperature = dht.getTemperature();
float fahrenheit = dht.toFahrenheit(temperature);
int ldrValue=analogRead(A0), flameValue=analogRead(A1), MQ4Value=analogRead(A2);
int HygValueA=analogRead(A3), HygValueB=analogRead(A4), HygValueC=analogRead(A5);
EthernetClient client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (readString.length() < 135) readString += c;
if (c == '\n') {
// HTTPレスポンスヘッダー送信
client.println("HTTP/1.1 200 OK");
client.println("Content-Type:text/html");
client.println("Connection: close");
client.println();
client.println("");
client.println("ArduinoSide ");
client.println("");
client.println("");
// 隠しフォームでセンサー値をArduinautomotioncommunication.phpへ送信
client.println("");
break;
}
}
}
delay(1); client.stop();
// 受信コマンドでリレー制御
if (readString.indexOf("?airpump=pumpIsOn") >0) digitalWrite(pump, LOW);
else if (readString.indexOf("?airpump=pumpIsOff") >0) digitalWrite(pump, HIGH);
if (readString.indexOf("&lamp=lampIsOn") >0) digitalWrite(lamp, LOW);
else if (readString.indexOf("&lamp=lampIsOff") >0) digitalWrite(lamp, HIGH);
if (readString.indexOf("&feed=feedIsOn") >0) digitalWrite(feed, LOW);
else if (readString.indexOf("&feed=feedIsOff") >0) digitalWrite(feed, HIGH);
if (readString.indexOf("&heater=heaterIsOn") >0) digitalWrite(heater, LOW);
else if (readString.indexOf("&heater=heaterIsOff") >0) digitalWrite(heater, HIGH);
if (readString.indexOf("&filterex=exIsOn") >0) digitalWrite(filterex, LOW);
else if (readString.indexOf("&filterex=exIsOff") >0) digitalWrite(filterex, HIGH);
if (readString.indexOf("&filterin=inIsOn") >0) digitalWrite(filterin, LOW);
else if (readString.indexOf("&filterin=inIsOff") >0) digitalWrite(filterin, HIGH);
if (readString.indexOf("&irrigation=start") >0) digitalWrite(irrigation, LOW);
else if (readString.indexOf("&irrigation=stop") >0) digitalWrite(irrigation, HIGH);
readString="";
Serial.println("client disconnected");
}
}
カスタムパーツ・エンクロージャ
- arduinautomotion_wNJ69zA666.ico(ファビコン)
- spidersense_Ge3umcKzBw.mp4(アラート用動画)
- spidermanvoice_EqWLILohmW.mp3(アラート用音声)
回路図


製造プロセス
- Raspberry PiでPIRモーションセンサーとLEDを制御
- Firebase経由で2台のArduino間を温湿度データで連携するIoTチュートリアル
- ArduinoでユニバーサルIRリモコンを自作:ステップバイステップガイド
- Arduino Unoベースの人間検知レスキューロボット:センサー統合ステップバイステップ
- Arduinoで作る赤外線心拍センサー:低コスト・リアルタイム波形表示のステップバイステップガイド
- デジタル身長計の自作:Arduino Nanoとレーザー距離センサーで成長記録
- ESP8266・Arduino・超音波センサーで作るスマートIoTジャー:リアルタイム中身監視
- Arduinoで地球の質量を測定:ステップバイステップDIYガイド
- ESP32で作るIoT環境モニター:温湿度・気圧・CO2をWebダッシュボードで可視化
- ArduinoとProcessingで作るリアルタイムデジタルコンパス
- 初めてのAWS CloudFormationテンプレート構築:実践ガイド