クリーンでスマートな発電への移行が進む中、あちこちの屋根や裏庭に小規模な太陽電池パネルが見られるようになっています。これらの設備の中には高度な監視機能や自己調節機能を備えたインテリジェントなものもありますが、そうした機能を持たないものもあります。後者の場合であっても、基本的な運転データを得るための安価で適切な方法があると、所有者にとっては便利です。
太陽電池パネルの所有者は、与えられた条件の下で太陽電池パネルが最適な動作をしているかどうかを知りたがります。光と気温の両方、さらに風速やその他の要素がパネルの出力に影響します。光量が多ければ発電量は増えますが、発電量が増えると太陽電池セルの温度が上昇し、セルの効率が低下します。風は熱の発散に有効です。理想的には、強い光と低い気温という条件、そして適度な風または人工的な冷却が必要です。
Arduino はセンサーとデータ・ストレージの間を仲介する役割をします。永続的にデータを記録し、必要に応じてデータを表示するのは単純です。この記事では、TMP36 温度センサーを温度測定に使用し、また単純な LED (発光ダイオード) を光量測定に使用して、測定データをログに記録する方法について調べます。
Arduino は安価で、幅広い適応性があり、プログラミング可能なオープンソースのマイクロプロセッサーであり、アナログ・ピンの電圧から入力データを読み取ることができます。Arduino に関する基本的な情報については「参考文献」を参照してください。また、developerWorks にはゲーム用に Arduino を使用する例を紹介した記事があります。特定の入力ピンにセンサーを接続すると、Arduino はそれらの入力ピンのデータをプログラムで読み取ります。その情報を使って Arduino が何をするかは、ハードウェアの構成方法によります。
Arduino からデータを取得する最も単純な方法は、Arduino をホスト・コンピューターの USB (Universal Serial Bus) インターフェースに直接接続し、シリアル接続であるかのように Arduino のデータを読み取る方法です。ただし Arduino は、電源と通信チャネルがあれば、コンピューターに接続しなくても独立して動作することもできます。Arduino に拡張ボード (「シールド」) を追加すると、microSD メモリー・カードにデータを直接保存することや、ミニ Web ブラウザーを使用して CAT5e ネットワーク・ケーブルを介してデータを送信すること、さらには互換性のある受信機に無線でデータを送信することもできます。
図 1 は Arduino マイクロプロセッサーに Ethernet シールドを追加し、また CAT5e イーサネット・ケーブルと電源ケーブルを接続した状態を示しています。この図で Arduino の大きさの感覚がつかめると思います。
図 1. イーサネット・シールドを追加した Arduino
一部のセンサーはデータを平滑化するための内部回路を独自に持っていますが、単純なセンサーにはそうした回路はありません。そのため、必要な処理をすべて Arduino で行ってからデータを保存、送信するのか、あるいは生の測定データを単純に出力し、後から別のマシンで処理するのか、という判断をしなければなりません。どちらの方法も、まったく妥当です。このプロジェクトでは、単純に生の測定データを出力し、後で処理を行います。こうすることで、いつでも必要に応じて平滑化アルゴリズムを変更することができます。平滑化プロセスが適用されたデータは固定化され、おそらく平滑化前の状態に戻すことはできません。一方で、リアルタイム・データの場合で平滑化要件が十分に理解されている場合には、Arduino に平滑化を行わせた方が妥当です。
Arduino には多種多様なセンサーを使用することができます。この記事では、単純で安価、そして手軽に繰り返し使用できるセンサーとして、TMP36 と LED を使用します。
TMP36 は特別に作られたトランジスターです。TMP36 に電圧を印加すると、TMP36 はさまざまに組み合わせた太陽電池セルの周囲温度に従って連続的に変化する別の電圧を出力します。TMP36 の出力電圧を記録して単純な計算を行うと、設定に応じて摂氏または華氏の温度を得ることができます。TMP36 について、また TMP36 を Arduino に接続する方法については、「参考文献」を参照してください。
太陽光発電で温度データをログに記録するのはとても簡単に思えますが、いくつかの難題を克服する必要があります。第 1 に、周囲温度に関する問題として、どこにセンサーを配置するかを決めなければなりません。データを誤って読み取らないように、直射日光が当たらず、水がかかることのない、風通しの良い場所に配置する必要があります。第 2 に、太陽電池パネルは何種類ものセルで構成されており、周囲の条件が同じでもそれぞれがセルごとに異なる温度で動作します。理想的な状況では、すべてのセルを測定し、それらの平均をとります。別の方法としては、いくつものセルを測定し、それらを代表する平均的なセルを特定し、そのセルのみを監視します。
LED は適切な電圧を印加して電流を流すと発光し、また光を受けると電圧を発生します (「参考文献」に挙げた Mike Cook の記事を参照)。光が強ければ強いほど、Arduino の接続ピンで測定される電圧は高くなります。温度センサーの場合は特定の温度範囲に対応するように設計されていますが、LED の場合はそれとは異なり、LED からの出力と既知の光強度範囲とがどう対応するのか、実験で確認する必要があります。
条件として、太陽電池の設置場所には電気が供給されており、イーサネット・ケーブルを接続するための LAN (Local Area Network) ジャックはありませんが、無線アクセスポイントの電波が届く範囲内にある、と考えてみてください。この場合には、その設置場所の電源を利用してアクセスポイントと Arduino の両方を起動し、イーサネット・シールドを追加した Arduino をリピーターに接続することができます。そしてピン 1 とピン 2 はイーサネット・シールドを使用するために予約されているとすると、アナログ・ピン 3 と 6 をセンサー入力に使用することができます (ピンの使い方についての詳細は「参考文献」を参照)。4 本のピンがあるということは、4 つのセンサーが使えるということです。例えば、2 つの温度センサー (1 つは周囲温度用、もう 1 つはパネル温度用)、光量センサー、風速センサーを使用することができます。以上が受動パネルのセットアップに関する各種データになります。
Arduino とセンサーの間の実際の配線は、通常の CAT3 電話ケーブルを使って短い距離で配線することができます。CAT3 電話ケーブルは、シールドなしで太さ 24 AWG (American wire gauge) の電線 2 対を撚り合わせたものです。CAT3 電話ケーブルを使うことで、市販の電話用アダプターやケーブルを使用することができます。
Arduino とイーサネット・シールドとの組み合わせは、USB/シリアルのみで接続された Arduino ほど簡単ではなく、考慮すべき詳細事項として以下に挙げるものがあります。
- 通常、センサーが接続されていないピンの電圧をポーリングする必要はありません。
- Arduino は電源コネクターから供給される、ある範囲の電圧で動作します (詳細は「参考文献」を参照)。アナログ・ピンの電圧読み取り値は Arduino に供給される電源電圧に大きく依存するようです。センサーの校正には必ず、フィールドで使用する予定の電源ユニットと同じ電源ユニットを使用する必要があります。上級ユーザーはアナログ基準電圧 (AREF) ピンを使用して基準電圧を供給してください。
- 温度センサーは太陽電池セルの背面に取り付けます。短期間であれば、温度が少し高くても、セルにセンサーを固定する上でダクト・テープが非常に便利なようですが、露出している電線やコネクターをすべて適切な絶縁テープで保護、絶縁しておく必要があります。周囲温度が 20°C (69°F) で常に微風が吹いている状態のとき、強い光を受けて NOCT (公称動作セル温度) が 50°C (124°F) に上昇することは珍しくありません。
- イーサネット・シールドを追加した Arduino は非常に大きな電力を消費します。フル充電された AA (単 3) サイズの電池セットを使用して電圧と電流を供給する場合、ほんの数時間しかもちません。上級ユーザーは、電力使用量を制御するスリープ・モードを調べてみてください。
図 2 は TMP36 センサーを太陽電池ラックと太陽電池パネルに付けた状態を示しています。右側の黒い絶縁テープの下にセンサーがあり、金属のポールの温度を周囲温度として測定します。その左側にはもう 1 つセンサーがあり、太陽電池セルの背面にダクト・テープで固定されています。ダクト・テープは一般消費者向けの絶縁テープよりも、少なくとも短期間であれば、粘着力が大幅に優れています。
図 2. 太陽電池パネルに付けられたセンサー
図 3 は、雨を防ぐために逆さにした試験管の中に設置された緑色 LED を示しています。
図 3. 光センサー
収集されたデータへアクセスするための Arduino プログラム (Arduino ではスケッチ (sketch) と呼びます) は、ブラウザーやスクリプトを使用してアクセスできる単純な Web サーバーです (リスト 1 を参照)。基本コードはコード・サンプル集の一部として Arduino に用意されており、皆さん自身の要件に合わせて少し編集する必要があります。
リスト 1. Arduino の Web サーバー
// based on example web server sketch from http://arduino.cc/
#include <SPI.h>
#include <Ethernet.h>
//
byte mac[] = { 0x!!, 0x!!, 0x!!, 0x!!, 0x!!, 0x!! };
byte ip[] = { 192,168,0,xxx };
Server server(80);
//
void setup()
{
// start the Ethernet connection and the server:
delay(10000);
Ethernet.begin(mac, ip);
server.begin();
}
//
void loop()
{
// listen for incoming clients
Client client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
//
// output the value of each analog input pin
for (int analogChannel = 3; analogChannel < 7; analogChannel++) {
//client.print("analog input ");
client.print(analogChannel);
client.print(" : ");
client.print(analogRead(analogChannel));
client.println("<br />");
}
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
|
リスト 1 ではまず、必要なヘッダー・ライブラリー、イーサネット・シールドの MAC (Media Access Control) アドレス、Arduino を特定するための
IP (Internet Protocol) アドレスを指定しています。さらに、値を保存するためのサーバー・オブジェクトと変数も設定しています
(これらは後で破棄することができます)。setup() サブルーチンは起動時に 1
度だけ実行され、サーバーを初期化します。次に loop() サブルーチンは永遠にループを繰り返して HTTP リクエストを待機し、リクエストを受信すると必要なデータで応答します。リクエストへの応答として、loop() サブルーチンは標準的な HTTP レスポンス・ヘッダーを送信し、該当するピンからの読み取り値を収集し、そのデータ・パッケージをテキスト・フォーマットで送信します。この場合、提供されるデータはリクエストを受信した瞬間にアナログ・ピン 3、4、5、6 で測定された電圧です。ピン 1 と 2 のデータは送信されませんが、これはピン 1 と 2 が Arduino 基板とイーサネット・シールドとの間のインターフェースに使われているためです。使用しているピンのみを読み取るように、チャネルの範囲を変更してください。
レスポンスを出力するとリスト 2 のようになります。
リスト 2. Arduino からのレスポンス
3 : 292 4 : 288 5 : 286 6 : 280 |
この出力には、ピンの番号と、0 から 1023 の範囲の値が含まれており、2 つの数字はコロンで区切られています。出力は、単にアナログ・ピンの番号を指定するのではなく、もっと具体的なものにすることもできますが、汎用的な数字であれば特定のピンが特定の作業に結び付けられることはなく、柔軟性が高まります。
次に、データの保存方法を考える必要があります。この記事では MySQL をバックエンドとして使用します (リスト 3 を参照)。
リスト 3. バックエンド・テーブル
CREATE TABLE IF NOT EXISTS `readings` ( `readid` int(11) NOT NULL AUTO_INCREMENT, `tstamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `pin` int(11) NOT NULL, `value` float NOT NULL, PRIMARY KEY (`readid`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; |
このコードで作成されるテーブルには、ID フィールド、タイムスタンプ (デフォルトはそのエントリーのシステム時刻)、読み取り値に対応するピン、実際の読み取り値のフィールドがあります (この場合は読み取り値が浮動小数点数として保存されます)。
バックエンドを定義できると、PHP を使用して Arduino に問い合わせをすることや、そのレスポンスを分析すること、そして測定値をバックエンドに保存することができます (リスト 4 を参照)。
リスト 4. PHP によるデータ・ロギング・スクリプト
<?php
// reader for panel monitors
$fp = fopen("http://192.168.0.xxx","r");
$mysqli = new mysqli("$server",$username,$password,$mysolar);
while ($line = fgets($fp,32)) {
$line = str_replace(" |
このスクリプトではまず、読み取りのためのファイル・ポインターの中で Arduino への接続を開き、続いてデータの出力用として MySQL
バックエンドへの接続を開きます。次に Arduino からの応答を待ち、レポートされる行を読み取るためのループに入ります。レポートの出力として想定される 4
行のそれぞれには HTML (Hypertext Markup Language) の break タグが含まれているため、テストの際にブラウザーで容易に出力を読み取ることができます。このスクリプトは、その break タグを削除します。その結果、各行はピンの番号で始まり、その後に測定電圧が続きます。次にスクリプトではピン番号に注目して switch 構造に入り、ピンに接続されているセンサーに応じて異なるアクションを実行します。
このステップで校正が行われます。つまり、あるセンサーが常に一定量だけ大きい値を示していることがわかった場合には、その一定量を差し引いてから最終的な値として出力します。TMP36 で測定したミリボルトを摂氏の温度に変換するための特定の関数があり、その関数は 0-1023 の範囲を 1 から 5 の範囲に変更してからゼロの位置を合わせ、その結果を 100 倍します。そして最後に、四捨五入によって整えられた値をデータベースに保存します。センサーに補正が必要かどうかは、どのようにして知るのでしょう。1 つの方法は、同じような振る舞いをするセルを簡単な放射温度計で測定することです。
SQL の insert 文は 2 つの NULL 値で始まっており、バックエンドは最初の NULL をオートインクリメントの ID 番号で置き換え、2 番目の NULL を現在のタイムスタンプで置き換えます。次に、ピンの番号と、そのピンの読み取り値を渡します。このスクリプトを crontab のリストに指定して通常の処理をすることも、あるいは必要に応じてコマンドラインから実行することもできます。
バックエンドにデータを保存できたら、次はデータを読みやすいものにします。利用可能なチャート・ライブラリーはいくつもあり、それぞれに特有の長所と短所があります。Flotr (「参考文献」を参照) は JavaScript を使用してブラウザー・ウィンドウにチャートを表示するライブラリーの一例です。リスト 5 に示すコードは readings テーブルに保存されたデータを読み取り、温度データと光量データを別々のチャートに表示します。
リスト 5. PHP と Flotr を使用したチャート生成プログラム
<?php
// read solar data and display in flotr chart
$doctype = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'>
<head>
<title>LOG reader</title>
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8' />
<script language=\"javascript\" type=\"text/javascript\"
src=\"../flotr/lib/prototype.js\"></script>
<script language=\"javascript\" type=\"text/javascript\"
src=\"../flotr/lib/base64.js\"></script>
<script language=\"javascript\" type=\"text/javascript\"
src=\"../flotr/lib/canvas2image.js\"></script>
<script language=\"javascript\" type=\"text/javascript\"
src=\"../flotr/lib/canvastext.js\"></script>
<script language=\"javascript\" type=\"text/javascript\"
src=\"../flotr/flotr.js\"></script>
</head><body>";
$mysqli = new mysqli($server,$username,$password,$dbname);
// get temp and light data and chart it
$sensors = array('Temp'=>6,"Light"=>5);
foreach ($sensors as $label=>$sensor) {
$sql = "select tstamp,value from readings
where pin=$sensor order by tstamp asc";
$result = $mysqli->query($sql) or die($mysqli->error);
$mydata1 = "[ ";
while ($row = $result->fetch_array()) {
$cfdoy = $row[0];
$cfdoy = (strtotime($cfdoy)-(5*60*60))*1000;
$cfamt = $row[1];
$mydata1 .= "[ $cfdoy , $cfamt ] ,";
}
$mydata1 = substr($mydata1,0,-2)." ]";
$leg = ($sensor == 18) ? "dC" : "mV";
$title = ($sensor == 18) ? "Cell Temperature" : "Light";
$conth .= "<div>$label</div>\n
<div id=\"container$sensor\" style='width:600px; height:250px;'>
<script type='text/javascript'>
var f = Flotr.draw(
$('container$sensor'), [
{ // => first series
data: ".$mydata1.",
label: '$leg',
htmlText: false,
lines: {show: true}
}],
{
xaxis: {
title: 'Time',
mode:'time',
noTicks: 10,
labelsAngle:45
},
yaxis: {
title: '$leg',
noTicks: 8
},
title: '$title',
selection: {
mode: 'x',
color: '#B6D9FF',
fps: 20
},
mouse: {
track: true,
relative: true,
margin: 5,
trackFormatter: function(obj) {
var dd = parseInt(obj.x);
var d = new Date(dd);
return (d.getHours()+4) + ':'
+ d.getMinutes() + ' | ' + obj.y;
},
position: 'sw',
lineColor: '#FF3F19',
trackDecimals: 1,
sensibility: 2,
fillOpacity: 0.4
}
}
);
</script></div>";
}
echo "$doctype"."<html><body>".$conth."</body></html>";
?>
|
リスト 5 のコードではまず、XHTML (Extensible Hypertext Markup Language) 出力の先頭になるストリングを定義し、続いて JavaScript Flotr ライブラリーを読み込んでいます。次に、データが保存されている MySQL サーバーへの接続を開き、使われているピン番号を含む配列を設定し、その配列要素を順次処理して該当するセンサーのデータを取得し、そのデータを JavaScript スクリプトに入力します。
このスクリプトは両方のチャートに対し、24 時間表示の時計の時刻値として X 軸データを扱うように設定しています。またマウスに関する命令が含まれているため、生成されたラインの上でマウスをホバーすると、対応する座標が表示されます。
表示時に平滑化をしようとする場合には、移動平均を使用することも、極端な値を抑える重み付けに基づく方法を使用することもできます。
このチャート・スクリプトは、このセットアップで 5 分ごとにサンプリングされて生成される実際のデータを使用し、平滑化なしで図 4 の出力を生成します。条件としては、オンタリオでの 5 月の晴れ時々曇りの日です。このデータは「ダウンロード」セクションから入手することができます。
図 4. 出力の例
予想どおり、光のレベルとセルの温度との間には密接な相関関係があることに注意してください。
オープンソースの Arduino は、単純で幅広い適応性があるプロセッサーとして、太陽光発電のセンサー・データを利用する上で役に立ちます。利用可能なセンサーにはさまざまな種類があり、センサーが適切な電圧を出力するか、センサーにデジタル出力があって、その出力を Arduino が正確に記録できる限り、Arduino はデータを収集、出力することができます。この TMP36 と LED をセンサーとして使用する方法は、これ以上ないほど基本的です。本格的なユーザーは、これらの方法からアップグレードすることができます。
多様な条件下での太陽電池パネルの振る舞いを示すデータが十分に得られると、記録されたデータを観測のベース・データとして利用できるため、太陽電池パネルの管理者の役に立ちます。そうしたデータを基に、管理者は何らかの論拠や助言に従って変更を行った場合、パネルに加えられた操作が効果的であったかどうかを評価することができます。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Data sample | readings.sql.zip | 1KB | HTTP |
学ぶために
- 「Building an
Arduino-based laser game」(Duane O'Brien 著、developerWorks、2008年12月) は Arduino を紹介した優れた記事です。この記事には LED を光センサーとしてセットアップする方法も説明されています。
- LED Sensing のサイトを訪れ、なぜ LED が光センサーとして動作するかの背景にある物理学について学んでください。
- Arduino フォーラムを訪れ、他のユーザーから Arduino について学んでください。
- Arduino チュートリアルのサイトを訪れ、外部電源に関する助言を含めて Arduino のセットアップ方法を学んでください。
- Arduino Shield List でピンの使い方を調べてください。このサイトには、108 のメーカーから発売されている 244 種類のシールドの情報が記載されています。
- このページには Arduino と TMP36 を接続する方法の詳細が説明されています。
- Arduino のチュートリアルを読み、Ethernet シールドと Arduino を使用して単純な Web サーバーを作成する方法を学んでください。
- JavaScript によるチャート・ライブラリー、Flotr に関連する情報やサンプルについて調べてください。
- TMP36
電圧出力温度センサーの詳細な技術情報を入手してください。
- developerWorks
のサイトには PHP 関連のコンテンツが豊富に用意されています。
- Twitter で
developerWorks をフォローしてください。
- PHP project
resources を利用して PHP のスキルを磨いてください。
- IBM オープンソース開発者にとって関心のある、今後開催される会議や業界展示会、ウェブキャスト、その他のイベントについて調べてみてください。
- developerWorks の Open source ゾーンをご覧ください。オープンソース技術を使用した開発や、IBM 製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。
製品や技術を入手するために
- Arduino: Arduino のメイン・サイトを訪れてください。
- 無料でダウンロードできるオープンソースのデータベース、MySQL Community Edition を利用してください。
- 汎用のスクリプト言語、PHP の最新リリースを調べてみてください。
- 皆さんの次期オープンソース開発プロジェクトを IBM ソフトウェアの試用版を使って革新してください。ダウンロードあるいは DVD で入手することができます。
議論するために
- developerWorks
コミュニティーで開発者向けのブログ、フォーラム、グループ、ウィキなどを利用しながら、他の developerWorks
ユーザーとやり取りしてください。developerWorks コミュニティーの Real world open source グループを構築する作業を支援してください。