2010年1月25日月曜日

Arduinoで温度を計測する -2 オペアンプ使用

この投稿は、建築発明工作ゼミ2009 『温度センサ』をもとに、新しく書き直したものです。

デュアルオペアンプLMC6032IN

オペアンプを使って、温度センサの最大出力電圧1Vを5V、五倍に引き上げてみます。
簡単に言うと、1℃につき10mV出力であったのを、回路をいじって1℃につき50mVの出力にしてやるということです。アナログ入力値1に対する分解能は、

100℃ / 1024 = 0.0976...

つまり、0.09℃単位で計測できるようになります。

図1 図2

G(増幅率) = 1 + (R1 / R2)

図1のように、オペアンプは基本的に5つのピンを持っています。
  1. プラス電圧入力「差動入力ピン」
  2. マイナス電圧入力「差動入力ピン」
  3. プラス電源ピン(オペアンプ自身のプラス電源ピン)
  4. マイナス電源ピン(オペアンプ自身のマイナス電源ピン)
  5. 出力ピン
プラスとマイナスの差動入力ピンの電圧差が増幅されて出力される、という電子部品です。
入力された電圧の増幅率(ゲイン)は、二つの抵抗値の比によって決まります。
オペアンプは、自身に入力される電源よりも高い電圧を出力することはできません。
例えば、オペアンプのプラス電源に5V、マイナス電源をGNDに接続するとします。入力が1V、増幅率を10倍に設定しても、理論的には出力は5Vまでしか増幅されません。
しかし、オペアンプの増幅率は105倍というような大きさのため、差動入力電圧がわずかでもあると出力は+か−の最大値しか出力できません。
実用的に使用するには、ネガティブフィードバックという方法を使います。

オペアンプの回路には、大別して「反転増幅回路」と「非反転増幅回路」の二種類があります。
非反転増幅回路は入力された電圧をそのまま増幅(プラスだったらプラス、マイナスだったらマイナス)して出力します。
反転増幅回路は入力された電圧を反転増幅(プラスだったらマイナス、マイナスだったらプラス)して出力します。
反転増幅回路を組む時はマイナス電源が必要になる(マイナス電源ピンに回路のGNDを基準としてマイナスの電圧をつなぐ)ため、簡単には回路を組めません。
非反転増幅回路をプラスの単源源で使用すれば、マイナス電源は回路のGNDに接続すればよいので扱いやすくなります。

図2は非反転増幅回路です。
プラスとマイナスの差動入力ピンの電圧差を極性をそのままに増幅して出力しますが、出力の途中で抵抗R1を通し、出力信号をマイナス差動入力ピンにフィードバックしています。
これにより、差動電圧差がなくなるように働き、結果として二つの抵抗R1とR2で設定した増幅率に落ち着きます。

outputV(出力電圧) = (1 + (R1 / R2)) × inputV(差動入力電圧)


温度センサLM35DZとオペアンプLMC6032INを使用し、回路を組んでみます。

図3
オペアンプはLMC6032を使用しました。
図3の通り、このLMC6032INには二つのオペアンプが内蔵されています。V+ピンは共通のプラス電源ピン、V-は共通のマイナス電源ピンです。今回は一つしか使いません。


回路図

考え方としては、まず計測温度範囲を決めます。0℃〜100℃とします。
温度センサLM35DZは1℃あたり10mV、100℃でちょうど1Vです。Arduinoのアナログ入力最大電圧5Vまでで、フルレンジで使いますから増幅率は5倍です。とすると、上記の式に当てはめて、

5V(出力電圧) = (1 + (R1 / R2)) × 1V(差動入力電圧)

これを解くと、抵抗の比は

R1 : R2 = 4 : 1

となります。
LM35DZの+VsピンとLMC6032のV+ピンに5Vの電圧をかけます。C というのはコンデンサです。電気を溜めて吐き出す役割があり、上下する不安定な電気の流れを安定化させるバイパスコンデンサとして機能します。
抵抗R0は、R1とパランスをとるために使っています。この回路では、オペアンプのマイナス入力端子をGNDにつないでいるので、入力も出力もGNDとの電圧差が基準となります。

スケッチ
/* 
  温度計測(0℃〜100℃)
*/

int   A_inPin = 0;  // アナログ入力ピン番号
float A_val;        // アナログ入力値(0〜1023)
float tempC   = 0;  // 摂氏値( ℃ )

void setup()
{
  // シリアル通信速度
  Serial.begin(9600);
}

void loop()
{
  // アナログピンから計測値を取得(0〜1023)
  A_val = analogRead( A_inPin );

  // 摂氏に換算
  tempC = (100 * A_val) / 1024;

  // 改行しながら出力
  Serial.println( tempC );

  // 1秒停止
  delay(1000);
}



シリアルモニタで表示してみると、以下のようになりました。

だいたい0.1℃単位で変化しているので、おおむね精密になったと思います。

ついでに、以下のようなスケッチも試してみます。
1秒ごとに摂氏温度を計測し、10秒ごとに平均摂氏、最大摂氏温度、最小摂氏温度をシリアルモニタに出力します。
日付時刻も表示するために、Datetimeライブラリを使ってみます。
DateTimeライブラリは標準でArduinoIDEにインストールされていないので、以下のスケッチをコピーして実行しようとするとエラーになります。
以下のリンクからDateTimeライブラリをダウンロードして解凍し、指定のディレクトリ内に配置しなければなりません。

こちらからダウンロード

ダウンロードして解凍したら、DateTimeというフォルダができます。
その中のDateTimeフォルダとDateTimeStringsフォルダを、以下の場所にコピーします。

(Macの場合)
○○○(ユーザディレクトリ)/書類/Arduino/library/

スケッチ
/* 
  1秒ごとに摂氏温度を計測
  10秒ごとに平均摂氏、最大摂氏温度、最小摂氏温度を
  シリアルモニタに出力
*/

// DateTimeライブラリをインポート
#include <DateTime.h>

// プログラム開始日付時刻
int    year       = 2010;  // 年
int    month      = 1;     // 月
int    day        = 25;    // 日
int    hour       = 18;    // 時
int    minute     = 3;     // 分
int    second     = 0;     // 秒

int    A_inPin    = 0;     // アナログ入力ピン番号
int    A_val;              // アナログ入力値(0〜1023)
int    outputTerm = 10;    // 計測結果出力ターム(10秒ごとに平均摂氏値を出力する)
float  v          = 5;     // 基準電圧値( V )
float  tempC      = 0;     // 摂氏値( ℃ )
float  tempCPlus  = 0;     // 10秒ごとの合計摂氏値( ℃ )
float  maxTempC   = 0;     // 10秒ごとの最大摂氏( ℃ )
float  minTempC   = 0;     // 10秒ごとの最小摂氏( ℃ )

void setup()
{
  // シリアル通信速度
  Serial.begin(9600);

  // DateTime ライブラリの makeTime() メソッドで日付時刻作成
  time_t prevtime = DateTime.makeTime(second, minute, hour, day, month, year);

  // DateTime ライブラリの sync() メソッドで初期設定(日付時刻設定)
  DateTime.sync(prevtime);
}

void loop()
{
  // 1秒に一回、10秒間分温度計測
  for (int i = 0; i < outputTerm; i++ ) {

    // アナログピンから計測値を取得(0〜1023)
    A_val = analogRead( A_inPin );

    // 摂氏に換算
    tempC = (100 * A_val) / 1024;

    // 現for文ループ内で使わなくなった変数は解放
    A_val = 0;

    // 平均値を取得するために1秒ごとの値を10秒分合計しておく
    tempCPlus += tempC;

    // 1秒過去の最大摂氏値と現在の摂氏値を比較
    // 大きい方を格納
    maxTempC = max( maxTempC, tempC );

    // 1秒過去の最小摂氏値と現在の摂氏値を比較
    // for文1ループ目のみ、現在の摂氏値を格納
    if (i == 0) minTempC = tempC;

    // 小さい方を格納
    minTempC = min( minTempC, tempC );

    // 現for文ループ内で使わなくなった変数は解放
    tempC = 0;

    // 1秒間ストップ
    delay(1000);
  }

  // 10秒間の平均摂氏値
  tempC = tempCPlus / outputTerm;

  // 日付時刻更新
  DateTime.available();

  // シリアルモニタに出力
  // 日付時刻
  Serial.print(DateTime.Year+1900,DEC);
  Serial.print("/");
  Serial.print(DateTime.Month,DEC);
  Serial.print("/");
  Serial.print(DateTime.Day,DEC);
  Serial.print(" ");
  Serial.print(DateTime.Hour,DEC);
  Serial.print(":");
  Serial.print(DateTime.Minute,DEC);
  Serial.print(":");
  Serial.print(DateTime.Second,DEC);

  // 10秒間の平均摂氏値
  Serial.print("  Temp / ");
  Serial.print( outputTerm );
  Serial.print("sec  |  Average : ");
  Serial.print( tempC );
  Serial.print(",  ");

  // 10秒ごとの最大摂氏値
  Serial.print("Max : ");
  Serial.print( maxTempC );
  Serial.print(",  ");

  // 10秒ごとの最小摂氏値
  Serial.print("Min : ");
  Serial.println( minTempC );

  // 次loop()ループの計測に影響を及ぼさないように変数の値を0に戻す
  tempCPlus = 0;
  maxTempC  = 0;
  minTempC  = 0;
}


DateTimeライブラリは、
// プログラム開始日付時刻
int year = 2010; // 年
int month = 1; // 月
int day = 25; // 日
int hour = 18; // 時
int minute = 3; // 分
int second = 0; // 秒

の部分で初期値をセットしなければなりません。スケッチを実行するごとに新しく日付を記述し直し、アップロードさせます。
また、Arduinoの水晶振動子で物理的にカウントしているため、一日に数秒のずれが出るそうです。


『作る・できる/基礎入門 電子工作の素』

電子工作に必要な電子回路と部品を網羅した本。これ一冊でだいたいの部品の使用方法がわかります。様々な電子部品の役割が一通り載っているので、困ったらとりあえず開く、といった使い方ができます。さらに、実用的に使えそうな実験用電源装置や太陽光発電パネルの作り方まで載っています。電子工作の初心者はとりあえず買っておいて損はないと思います。
『センサ活用の素』

上記の本の著者のセンサ本。記述がかぶるところがありますが、オペアンプについてはけっこうわかりやすく書いてあるのでおすすめ。PICで作る事を前提としていますが、Arduinoを使った回路に応用が効く記述が多いです。光・温度・湿度・超音波・ガス・圧力センサの実装回路が載っています。
『すぐに使える!オペアンプ回路図100』

オペアンプを使いこなしたい人は持っておいた方がいいと思われます。初心者向きではありませんが、覚えきれないほどのオペアンプ回路が載っています。センサ×Arduinoの回路を実装していくと、困った時に必ず役に立つ時が来ます。

Arduinoで温度を計測する -1

この投稿は、建築発明工作ゼミ2009 『温度センサ』をもとに、新しく書き直したものです。

図1 温度センサ LM35DZ
温度センサ LM35DZを使用し、Arduinoで温度を計測してみます。
温度センサといっても、温度計のように温度を表示してくれるわけではありません。センサの三本足のうち、左側(+Vs)はArduinoの5V電源につなぎ、右側(GND)をArduinoのGNDに接続します。Arduinoにスケッチを送り込んで処理を開始させると、真ん中のVoutから、温度に応じた電圧を出力します。これを温度換算し、Arduino Serial Monitorで表示させてみるということです。

この温度センサLM35DZは、0℃で0V、1℃当たり10mVの出力が得られます。25℃だと250mV、100℃だと1000mV(1V)の出力が得られます。Arduinoのアナログ入力最大電圧は5Vなので単純計算で500℃まで計測できる計算になりますが、LM35DZ自体の計測範囲が-55℃〜+150℃なので、ここでは余裕をもって、0℃〜100℃までを計測範囲として回路を考えてみます。

まずは図1のような回路を組んでみます。

回路1
この場合、LM35DZのVoutを直接Analogピンに入れていますから、

0℃で0V、1℃当たり10mV増加
よって、100℃で1V

となります。
Arduinoのアナログ入力最大電圧は5V、取得値は0〜1023(1024段階)の数値として取得できます。
100℃・1Vだと 1024 / 5 で0〜203(204段階)。つまり、

0℃ 〜 100℃ [ 0V 〜 1V ] = 0 〜 203.8(Analog入力値)

の範囲の値を取得できます。1℃当たりの分解能は約2.048(上記のAnalog入力値は小数で書きましたが、実際には0〜203)。
/* 
  温度計測(0℃〜100℃)
*/

int   A_inPin = 0;  // アナログ入力ピン番号
float A_val;        // アナログ入力値(0〜203)
float tempC   = 0;  // 摂氏値( ℃ )

void setup()
{
  // シリアル通信速度
  Serial.begin(9600);
}

void loop()
{
  // アナログピンから計測値を取得(0〜203)
  A_val = analogRead( A_inPin );

  // 摂氏に換算
  tempC = ((5 * A_val) / 1024) * 100;

  // 改行しながら出力
  Serial.println( tempC );

  // 1秒停止
  delay(1000);
}
スケッチ

上記のスケッチをArduinoにアップロードして、シリアルモニタで確認してみます。
PCとArduino はUSB で接続した状態で、スケッチを実行させた後にArduino IDE の一番右上の 『Serial Monitor』ボタンをクリックすると、別ウィンドウでシリアルモニタが表示され、スケッチ中の Serial.print()関数で指定した変数の中身が表示されます。
ちなみに、Serial.print()Serial.println()の違いは、改行するかしないかです。

温度が一秒毎に出力されています。

  // 摂氏に換算
  tempC = ((5 * A_val) / 1024) * 100;


xV : 取得した電圧値
aVal : 取得したアナログ値(0〜1023)

とすると、

xV : 5V = aVal : 1024

となり、

xV = ( 5V × aVal ) / 1024

これを×100した数値が温度になります。
画像の温度値をみてもらうとわかるように、18.55℃、19.04℃、15.63℃を行ったり来たりしています。この中間の値(例えば15.3℃など)は、計測できても表示はできません。最大1Vを出力する温度センサの値に対して、Arduinoは最大5Vまで感知できます。1Vには204まで、5Vには1023までの値を取得できます。最大1Vまでしか感知しないような回路を組んでいたので、0℃〜100℃までの温度を、たった204段階でしか表現できないことになります。

100℃ / 204 = 0.4901...

つまり、取得するアナログ値1は0.49℃単位となるため、18.55℃〜19.04℃の中間の温度は表示できません。もっと精密に温度を計測するには、

0℃〜100℃ 0〜203(204段階)...Arduinoの感知電圧範囲0V〜1V

を、

0℃〜100℃ 0〜1023(1024段階)...Arduinoの感知電圧範囲0V〜5V

と、アナログ値1に対する分解能を上げてやります。
オペアンプを使って、温度センサの最大出力電圧1Vを5V、五倍に引き上げてみます。

2010年1月24日日曜日

ArduinoでLEDを点滅させる

この投稿は、建築発明工作ゼミ2008を参考に、現在の仕様にあわせて新たに書き起こしたものです。
この投稿内容については、上記ブログ管理人のkousakuさんの許可を得ております。

Arduinoのスケッチは、基本的に以下のような構成になっています。

void setup(){

    //初期設定のプログラム
}

void loop(){

    //ループ処理のプログラム
}

setup()は、スケッチが実行される最初に、一回だけ実行される特別な関数です。『 { 』と『 } 』で囲い、その中に初期設定を記述します。
後述するスケッチでは、pinMode()を使って基盤上のどのピンを出力または入力で使いたいのかを設定しています。

setup()内の処理を終えると、次はloop()関数内の処理に移ります。
loop()は、setup()関数内の初期設定やsetup()上部で宣言された変数、defineで定義された定数などの設定値を使い、入力値の加工や、どのピンにどんな値をどのように出力すればよいかなどの計算をさせるための処理プログラムを記述します。
この中に記述された処理は、電源がつながっていてなんらかのトラブルがない限りループし続け、処理を続けます。

Arduino IDEでスケッチを書き、LEDを点滅させてみます。
まずは、以下のように、LEDをArduinoに直接セットします。
アノードはデジタル13ピン、カソードはGNDに接続します。


次にArduino IDEを起動させ、以下のようなスケッチを書いてみます。


スケッチの説明をします。
1. LEDのアノードを差し込むデジタルピンの番号を、任意でつけた "ledPin" という名前の変数に格納します。
変数とは、スケッチで扱う様々な値をいれておく箱のようなものと考えてください。この箱(変数)を使うと、スケッチ上のいろんな箇所で、変数名を記述するだけで入れておいた値を使う事ができます。もし変数を使わなかったら、上記の "ledPin" と記述されている箇所すべてに値(この場合は13という数値)を書き込まなければなりません。例えばもし「13」という値を変えてみたいと思った時に、"ledPin" と書かれている箇所すべてを書き直す事になります。変数を設定しておけば、1行目の「13」という値を書き換えるだけで済みます。
その他に様々な不便なことが出てくるのですが、今回は割愛します。

int ledPin = 13;

これは、整数型(integer)の値13を変数 ledPin に代入するという意味です。決してイコール(等号)ではないので、間違えないようにしてください。スケッチ内で等号を記述するときは、== と書きます。条件分岐の構文 if 文などでよく使います。プログラムでは、式の右辺から評価(大雑把に言うと計算するということ)し、左辺に代入もしくは比較します。

2. setup()関数(上記参照)

3. pinMode()関数で、"ledPin" の値(この場合は13)のピンを「OUTPUT」(出力)に設定します。

4. loop()関数(上記参照)。関数内の処理のループが始まります。

5. digitalWrite()関数で、"ledPin" の値(この場合は13)のピンを「HIGH」にします。つまり、13ピンに差し込んでおいたLEDのアノードに、5Vの電圧を出力します。そうすると、LEDが光ります。

6. delay()関数で、()内の指定したミリ秒だけ現状を維持します。1000ミリ秒、つまり1秒間LEDが光り続けます。

7. digitalWrite()関数で、"ledPin" の値(この場合は13)のピンを「LOW」にします。つまり、13ピンに差し込んでおいたLEDのアノードに、0Vの電圧を出力します。そうすると、LEDの光りが消えます。

6. delay()関数で、()内の指定したミリ秒だけ現状を維持します。1000ミリ秒、つまり1秒間LEDの光りが消え続けます。

-> 5. に戻って処理を繰り返します。


左側の数値はスケッチ説明用の行番号なので、実際に入力する必要はありません。
ArduinoをPCに接続し、ボードとシリアルポートの設定を確認します(ここの「Arduino ボードの選択」と「シリアルポートの選択」を参照)。
Arduinoボード上の「PWR」ランプが光っていることを確認したら、Arduino IDEの「Verify」ボタンをクリックします。スケッチに不備があれば、
スケッチ記述エリア下部のモニタにエラーメッセージが表示されます。
エラーがなければ、「Upload」ボタンをクリックしてArduinoボードにスケッチを送信します。
成功すれば、モニタに「Done uploading」と表示されます。
Arduinoに差し込んだLEDが、1秒のタームで点滅を始めるはずです。

電子回路の基礎 -4 LEDについて

この投稿は、建築発明工作ゼミ2008を参考に、現在の仕様にあわせて新たに書き起こしたものです。
この投稿内容については、上記ブログ管理人のkousakuさんの許可を得ております。


LEDライト

簡単にLEDを説明します。
LEDは電流を一方向にしか流さない特性があるため、+と-を電源に対して正しくつながないと発光しません(逆につないでも壊れるということは、ほぼありません)。上図のように、通常二つの端子(アノードとカソード)があります。アノード側をプラスに、カソード側をマイナス(GND)に接続します。

LEDの多くは2.5V前後の電源で発光するようにつくられています。正確に言うと、+から-にかけて、その両端にかかる電圧の差(電圧降下)が2.5V前後必要であるということです。単三乾電池は1.5Vですから、一つでは光らせる事はできません。そして、Arduino基盤上の5V電源とGND(0V)に直接つなぐと、電圧降下の差が大きすぎて壊れる恐れがあります。そのためにArduinoに接続する回路に抵抗をかませる必要があります。

Arduino基盤の13番ピンは特別で、抵抗なしで直接つなぐことができますが、0〜12番ピンに接続する際には、抵抗(220〜470Ω程度)を直列つなぎしてください。LEDによって特性が異なりますので、より精確に行いたい場合は、購入する際に使用電圧や最大電流についてメモしておくか、付属のデータシートを参考にしてください。


アノード側に抵抗をつないだ場合は、抵抗を通して5Vの電圧が2.5Vまで下げられ、LEDによって2.5Vから0Vに下げられます。
カソード側に抵抗をつないだ場合は、LEDを通過することで5Vの電圧が2.5Vまで下げられ、抵抗によって2.5Vから0Vに下げられます。
最初にプラス側で電圧をさげておくか、最後にマイナス側で電圧を下げるかという違いです。もし、抵抗を取付けなければ、LEDにおいて5Vから0Vに一気に下げられ、電位差が5Vになってしまい使用電圧である2.5Vをはるかに上回り破損してしまうという感じです。抵抗の取付けについては、回路設計やLED の特性に応じて使い分けてください。

2010年1月23日土曜日

電子回路の基礎 -3 回路の法則 -2

当投稿は、東北学院大学工学部 機械知能工学科講義「メカトロニクスIおよびII」の『電子回路の基礎』項目を参考にさせて頂きました。一見難しい記号や式が並んでいるように見えますが、よく読めば大変わかりやすく書いてあります。

Arduinoが感知できる範囲内に電圧と電流を整える為には、いくつもの電子部品を使う必要があります。その中の一つに抵抗器があります。回路の法則-1 で扱ったように抵抗は電気の流れをおさえる役目を持っており、その電気抵抗の単位は「オーム(Ω)」で表されます。

通常、電子工作においては、センサをとりあえず一つだけ使ってみるといった簡単な実験でもない限り、一つの回路内に抵抗器一つだけということはありません。「入力」->「処理」->「出力」の流れの中で、複数の抵抗を使って想定の電圧を調整していくのが普通です。二つ以上の抵抗を使った場合の電圧と電流の関係を求めるには以下の法則を使います。


合成抵抗
  • 複数の抵抗を直列に並べた場合の合成抵抗は以下のようになります。


R = R1 + R2

キルヒホッフの第ニ法則で考えてみます。
E = IR1 + IR2
E = I(R1 + R2)
E = IR
つまり、
R = R1 + R2
抵抗の直列つなぎは、その抵抗値の和に等しいことになります。

  • 複数の抵抗を並列に並べた場合の合成抵抗は以下のようになります。


R = (R1 × R2) / (R1 + R2)

この場合、抵抗R1とR2の両端には、等しく電圧E(5V)がかかります。
オームの法則により、
I1 = (E / R1)
I2 = (E / R2)
全体としては
I = (E / R)
キルヒホッフの第一法則により、
I = I1 + I2
だから、
(E / R) = (E / R1) + (E / R2)
(1 / R) = (1 / R1) + (1 / R2)
(1 / R) = (R1 + R2) / (R1 × R2)
よって、
R = (R1 × R2) / (R1 + R2)


分圧回路

E2 = (R2 / (R1 + R2)) × E

電圧を分ける回路です。電圧はA点において、もとの電圧(5V)より低い3V(マイナス電源を基準とする)となります。この3Vという値は、二つの抵抗R1R2の値の比率によって決まります。例えば、抵抗R1R2の比が 2 : 3 の時、5Vの3/(2+3)で3Vです。
なんとなく感覚でもわかるでしょうが、あえて法則化してみると、
オームの法則により、
E = IR1 + IR2
E2 = IR2
これを解くと、
E2 = (R2 / (R1 + R2)) × E
となります。

この分圧回路は、オペアンプという電子部品を使ってArduinoのアナログ入力端子にセンサからの値を適切な範囲内に整えて入力させる回路を作る時に重要な役割を果たします。
オペアンプは、センサによって変化する電圧の振り幅を一定の範囲(Arduinoの感知する0V〜5V)に整える時に使います。例えば、光センサの出力する電圧の範囲が0V〜1Vであるのを、0V〜5Vに変えてやると、Arduinoのアナログ入力値幅1024段階をフルに使えるようになります。つまり振り幅を5倍にするわけですが、この倍率を決める時に分圧回路が役にたつわけです。

電子回路の基礎 -2 回路の法則 -1


当投稿は、東北学院大学工学部 機械知能工学科講義「メカトロニクスIおよびII」の『電子回路の基礎』項目を参考にさせて頂きました。一見難しい記号や式が並んでいるように見えますが、よく読めば大変わかりやすく書いてあります。


電子回路ではおもに電圧電流を扱います。電圧(V -ボルト)というのは電気の流れる圧力、電流(A -アンペア)というのは電気の量です。リンク先にも記述があるのですが、電子回路は水の流れに例えると理解しやすいと思います。


オームの法則
電子回路の基礎法則です。電圧と電流と抵抗は以下の関係が成り立ちます。

E = IR [ 電圧(E) = 電流(I) × 抵抗(R) ]
I = E / R [ 電流(I) = 電圧(E) / 抵抗(R) ]
R = E / I [ 抵抗(R) = 電圧(E) / 電流(I) ]

水の圧力(電圧)
水の量(電流)
パイプの太さ(抵抗)

と例えると、

同じ水量(電流)の場合、パイプの太さを細くする(抵抗値を上げる)と水圧(電圧)が上がります。
同じパイプの太さ(抵抗)の場合、水圧(電圧)を上げると水量(電流)が増えます。
電子回路の場合、回路上の全ての点で「電位」という値が定義されます。この電位は、その回路に使う電子部品や抵抗、センサなどによって各点で異なる値を示します。ある回路上の二点の電位差が電圧として定義されます。

図1

図1の場合、電源は5V、250Ωの抵抗を使っているので、回路に流れる電流は
I(?) = E(5V) / R(250Ω)
0.020 = 5 / 250
つまり、0.02A(20mA)です。
抵抗Rの両端のA点とB点の電位差(電圧)は5Vとなります。


キルヒホッフの第一法則
ある回路において、入ってくる電流と出て行く電流の和は等しくなります。当たり前のことのようですが、これが後述する法則の基礎として重要な役割を果たします。

I1 + I2 = I3 + I4

図2

図2において、電流I1 + 電流I2 = 電流I3 + 電流I4 が成立します。


キルヒホッフの第二法則
ある回路において、電圧は一周したら0になる、という法則です。

E - I1R1 - I2R2 - I3R3 = 0

図3

図3は、E-A-B-C-D と輪になっている回路を、ある回路の一部から取り出したものとします。点A・点B・点C・点Dの先はもとの回路とつながっています。こうしないと、後述する合成抵抗の法則により、電流I1I2I3がすべて同じ値になってしまうからですが、とりあえずあまり気にしないものとします。

まず、A点の電圧(D点を基準とした電位差)は5Vです。

次に、抵抗R1にかかる電圧(B点を基準とした電位差)は、オームの法則によりI1R1となります。
つまり、B点の電圧(D点を基準とした電位差)は、E - I1R1 となります。

次に、抵抗R2にかかる電圧(C点を基準とした電位差)は、オームの法則によりI2R2となります。
つまり、C点の電圧(D点を基準とした電位差)は、E - I1R1 - I2R2 となります。

次に、抵抗R3にかかる電圧(D点を基準とした電位差)は、オームの法則によりI3R3となります。
つまり、D点の電圧(D点を基準とした電位差)は、E - I1R1 - I2R2 - I3R3 となります。
D点を基準にD点の電圧をみると、0Vになっているはずです。

電子回路の基礎 -1 Arduinoと電子回路


Arduinoを扱う上で、電子回路の知識は必須です。
Arduinoとはで説明した通り、Arduinoは様々なセンサとアクチュエータを繋げる便利なマイコンボードです。しかし、決して万能というわけではありません。
「入力」->「処理」->「出力」の流れの中の「処理」を担当する、人間で言えば脳の役割を果たしているのですが、脳は、それ自体では外部の情報を得たりものを動かしたりすることはできません。情報を得る時は目や耳などのセンサが必要になりますし、得た情報によってなんらかのアクションを起こしたい時には手や足などのアクチュエータが要ります。そして、脳に情報を送る、または手や足に命令を送るための経路も必要です。この経路が、エレクトロニクスの世界では電子回路になります。

電子回路ではさまざまな電子部品を使用し、電気の圧力(電圧)や量(電流)を制御します。電子部品にはそれぞれ明確な役割があり、それぞれの仕様に則って使わないと壊れてしまいます。Arduinoが受け取れる電圧の最大値も決まっていて、それを超えると壊れたり正しい値を受け取れなかったりします。いかに想定した範囲の電圧を精密にArduinoに送れるかがキーとなります。

例えば0℃〜100℃の温度を計測してArduinoに伝えたいとします。Arduinoへは温度の値を電圧に変換して送らなければなりません。デジタル入力ピンは0Vか5Vのどちらかしか伝える事はできないので、電圧を0〜1023の1024段階で受け取れるアナログ入力ピンを使います。Arduino自体の最大入力電圧は5Vです。つまり、0℃〜100℃の温度を電圧0V〜5Vの触れ幅に変換する回路を組む必要があります。0V〜5Vの電圧は0〜1023の値として、指定したアナログピンから取得できます。きちんと回路が組めれば、温度センサを使ってArduinoに送られた電圧が1.2Vだとすると、Arduinoはアナログピンから245(1.2V / 5V × 1024)という値を受け取るはずです。これは、1.2 / 5 × 100 で、約24℃という温度を計測したことになるわけです(『Arduinoで温度を計測する』参照)。

電子回路の基礎知識は、以下のサイトと書籍がたいへん参考になります。一見難しい記号や言葉が並んでいるようにみえますが、よく読むと、非常にわかりやすいです。
また、電子部品の販売店は主に以下の店がおすすめです。
初めてだとちょっと入りづらいかもしれませんが、気にする事なく通いつめましょう。

2010年1月22日金曜日

Arduino I/Oボード仕様概略

この投稿は、建築発明工作ゼミ2008を参考に、現在の仕様にあわせて新たに書き起こしたものです。
この投稿内容については、上記ブログ管理人のkousakuさんの許可を得ております。

Arduino Duemilanove 328(最もスタンダードなArduinoボード)

Arduino基盤には、大きく分けて以下のようなピンがあります。LED、センサ、アクチュエータ、その他電子部品を接続して使用します。
  1. デジタル入力ピン
  2. デジタル出力ピン
  3. アナログ入力ピン
  4. アナログ出力(PWM)ピン
  5. 5Vピン
  6. GND(グランド)ピン
1. デジタル入力ピン
基盤上方にあるDIGITAL0〜13番ピンについては、デジタル入出力の際に、使用するピンを出力用に使うのか、入力用に使うのかをプログラム上の pinMode()設定する必要があります。

digitalRead()では、HIGHかLOWの二段階の入力方法しかありません。LOWは0Vに、HIGHは5Vに対応します。あるいは、二進法ではLOWが0、HIGHが1、またboolean型変数におけるfalse/trueに対応します。(接続したセンサなどを通して、オンになっているのかオフになっているのかを読み取るときに使います)。
例えば、電源(5Vピン)からの電圧をスイッチでオン/オフ(0V/5V)できるような回路をデジタル入力ピンに接続すれば、スイッチの状態がオン(HIGH)かオフ(LOW)かをArduinoに伝える事ができます。

2. デジタル出力ピン
digitalWrite()も同様にLOW/HIGHの二段階の出力です。
例えば、LEDライトを付けたり消したりしたい時、デジタル出力ピンに抵抗とLEDを接続すれば、Arduinoで動いているスケッチ(プログラム)から、LEDライトをオン/オフできます。

Arduinoの5Vピンからの出力電圧は基本的には5V固定ですから、デジタル入力・出力とは、電気が流れている状態(5V)と、流れていない状態(0V)の二種類ということになります。スケッチ(プログラム)上では使われ方によって、下記のような記述方法を書き分ける必要があります。

3. アナログ入力ピン
analogRead()は、センサなどから0〜1023の1024段階の読み取りが可能です(0V〜5Vを1024段階に分けています)。
例えば、温度センサによって0℃ 〜 100℃を計測するとします。0℃ 〜 100℃の値はセンサと電子回路で0V〜5V(0〜1023)の1024段階に変換され、その電圧をアナログ入力ピンに入力すれば、温度センサがどれくらいの温度を感知したかをArduinoに伝えることができます。

4. アナログ出力(PWM)ピン
analogWrite()は、上方の3、5、6、9、10、11番ピンの6箇所に接続でき、0〜255の256段階の出力が可能です(0V〜5Vを256段階に分けています)。
例えば、温度センサからのアナログ入力によって得られた0〜1023の値(温度)によってモーターの回転数を変えたいとします。アナログ出力ピンに、入力値 / 4、つまり1024段階の値の1/4の値を出力させれば、アナログ出力とつながったモーターへ256段階のスピード調節の命令を伝えることができます。

アナログ入出力においては、pinMode()を設定する必要はありません。

5. 5Vピン
基盤の下方にある5Vピンからは、5V電圧をとることができます。

6. GNDピン
GNDピン(0V)は、上方13番ピンの隣と、下方5Vピンの隣に2つ、合計3箇所あります。

Arduino基盤では、基本的に、0〜5Vの電圧を扱います。参考までに、乾電池の基本電圧は1.5Vです。
通常は、USB接続によってパソコンから5V電源がArduino基盤に供給されます。外部電源から供給したい場合には、外部電源端子にバッテリやACアダプタ(6〜20V/推奨は7〜12V)などを接続します。


Arduinoを準備します

この投稿は、建築発明工作ゼミ2008を参考に、現在の仕様にあわせて新たに書き起こしたものです。
この投稿内容については、上記ブログ管理人のkousakuさんの許可を得ております。



Arduinoを使う準備をします。

1. Arduino I/Oボード、パソコン(MacintoshかWindows)、USBケーブル

まずは最もスタンダードなボードである Arduino Duemilanove 328 を手に入れましょう。
以下に主な販売店を明記します。


パソコンとArduino I/Oボードを接続するUSBケーブル(Aオス-Bオスタイプのもの)も必要です。


2. Arduino IDE(統合開発環境)ソフトウェアのダウンロード、インストール


Arduinoのトップページ(上画像)のDownload(上赤印)からダウンロードサイトへ行き、OS(Windows/MacOSX)に合わせて、ソフトをダウンロードして下さい(現在の最新版はArduino 0018です)。

  • MacOSXの場合

ソフトをダウンロード、解凍すると、Arduinoのアイコンと、PPC・Intel 用のUSBドライバパッケージが入ったフォルダが開きます。Arduinoのアイコンをアプリケーションフォルダ内にドラッグ&ドロップします。ドライバパッケージは、お手持ちのMacintoshにあわせて、PPCまたはIntelをダブルクリックすれば、インストールが始まります。その後、Arduino基盤をUSBケーブルでMacに接続します。

  • WindowsXPの場合

ソフトをダウンロード、解凍すると、指定した場所に auduino-0017 というフォルダができます。その中の auduino-0017 を、C:¥Program Files¥ にコピーしてください。その後、Arduino I/OボードをUSBケーブルでPCに接続するとUSBドライバインストール確認用ダイアログが表示されるので、それに従ってインストールします。Windows Updateに接続するように即された時は、「いいえ」を選択します。インストールする場所は、C:¥Program Files¥arduino-0017¥drivers¥FTDI USB Drivers¥ を指定します。

以上で、インストールは完了です。

次に、Arduino IDEを起動します。
使用するArduino ボードの選択と、シリアルポートの選択をします。
Macの場合はアプリケーションフォルダ内のArduino、Windowsの場合は C:¥Program Files¥arduino-0017¥arduino.exe をダブルクリックします。


  • Arduino ボードの選択
Arduino ボード(以下Arduino)には色んな種類があります。そのため、ソフトウェアでボードを選択指定しなければなりません。今回は Arduino Duemilanove 328 を使用するので、メニューバーのTools>Board> Arduino Duemilanove or Nano w/ ATmega328 を選択します。

  • シリアルポートの選択
MacOSXの場合、Tools>Serial Port>/dev/tty.usbserial-A4001Kjl(A4001Kjlという型番は、各基盤によって違います)を選びます。もし Tools>Serial Portに、「/dev/tty.usbserial-********(********は型番)」という項目が現れなければ、Arduino基盤がパソコンに接続されていないか、USBドライバのインストールに問題があるかもしれません。特にMacOSXの場合、旧型のPPC用のドライバとIntel 用のドライバがあるので、相応しい方をインストールする必要があります。

Windowsの場合は、コントロールパネル>システムを開き、「システムのプロパティ」の中の「ハードウェア」タブを選択、「デバイスマネージャ」を開き、「ポート(COMとLTP)」を広げると、「USB Serial Port(COM5)」と表示されているはずです(パソコンによってはCOM5以外の番号かもしれません)。COM5の場合、Arduinoの画面のメニューバーのTools>Serial Port>COM5を選択します。
動作確認として、以下のサンプルプログラムを試してみて下さい。

Arduino画面メニューバーのFile>Examples>Digital>Blinkを選択すると、「Blink(LEDの点滅)」のサンプルプログラムが現れます(Arduinoサイト内にも同じサンプルがあります)。

「Upload」ボタンをクリックすると、Arduino基盤にプログラムのアップロードが開始されます。画面の下の方にDone uploading.と表示されれば、アップロード完了です。

Arduino Duemilanove 328ボードの場合は、基盤上のリセットボタンを押す必要はありませんが、Arduino NGボード(旧型)以前の場合は、リセットボタンを押した直後に「Upload」ボタンを押して下さい。

問題なければ、Arduino上のLED(13番ピン用内蔵LED/13番ピンの真下あたりにある基盤上の小さいLED)が一秒ごとに点滅します。 Arduino NGボード(旧型)以前の場合は、LEDが内蔵されていないので、13番ピンとGNDピンにLEDを差し込む必要があります。
Arduinoサイト上のLearning(上画像/赤印)は、学習用のサンプルプログラムが記載されているページです。Reference(上画像/赤印)は、プログラムの各言語について説明してあるページです。それぞれ参照してみて下さい。

2010年1月21日木曜日

Arduinoとは


Arduino Duemilanove 328(最もスタンダードなArduinoボード)


Arduinoとは、複数の入出力ポートを備えたハードウェア基盤と、Arduino IDE(統合開発環境)ソフトウェアからなるシステム開発環境です。
使用するには、WindowsもしくはLinuxがインストールされたPC、もしくはMacと、Arduino IDEソフトウェアが必要です。

パソコンにインストールしたArduino IDEでスケッチ(プログラム)を書き、USBケーブルでArduinoボードと接続して、書いたプログラムをボードに送ります。
Arduinoボードの方ではセンサやアクチュエータなどの電子部品で回路を組んでおき、送られたプログラムによって様々な動作をさせることができます。
なお、一度プログラムを送ってしまえば、パソコンとArduinoボードは繋いでおく必要はなく、Arduinoボードとセンサやアクチュエータを含めた電子回路単体(スタンドアロン)で動作させ続けることができます。
ここに詳しいセットアップ手順がかかれていますので参考にしてください。
最新のArduino IDEのバージョンは0017となります。



Arduinoによる作品の大まかな流れは次のようになります。

  1. 入力(センサなど)
  2. 処理(Arduino)
  3. 出力(アクチュエータなど)

1 の「入力」では、センサなどの入力部品でセンシングした物理世界のデータを数値化してArduinoに送ります。

2 の「処理」では、送られて来たデータをプログラムによって処理し、命令を出力部品に送ります。

3 の「出力」では、Arduinoから送られて来た命令をもとに、セットしたアクチュエータを動かします。

人間で例えてみます。
身の回りの様々な環境情報を視覚・嗅覚・触覚・味覚・聴覚の五感によって感じることが「入力」で、
入力された情報を脳が「処理」して身体に伝え(命令を送り)ます。
その命令によって身体を動かすことが「出力」です。

例)道を歩いていると、前から車がやってきました。危ないので道路脇によけます。

この動作の中には、上記した「入力」->「処理」->「出力」がワンセット含まれています。
まず、車を見た(センサで察知した)、これが「入力」です。
視覚情報は脳に送られ、「よけないと危ないから道路の脇に行け」という命令を足(アクチュエータ)に伝えます。これが「処理」です。
最後に、足は伝えられた命令によって身体を道路の脇に移動させます。これが「出力」です。

Arduinoの面白いところは、この「入力」->「処理」->「出力」の流れのうち、様々な電子センサやオブジェクトを組み合わせることよって「入力」と「出力」の形態を自由に作りこむことができる点です。


【入力に属するもの】

光センサ
温度センサ
湿度センサ
距離センサ
衝撃センサ
傾きセンサ
曲げセンサ
マイク
色センサ
etc...


--->

【処理部分】





Arduino


--->

【出力に属するもの】

LEDライト
液晶ディスプレイ
DCモーター
サーボモーター
ソレノイド
スピーカー
ニクロム電熱線
バイオメタル人工筋肉
ポンプ
etc...


そして、「入力」と「出力」の間にある「処理」部分のArduinoボードには、「入力」と「出力」を繋げるための様々なスケッチ(プログラム)をコンピュータから事前に書き込む必要があります。

光センサと湿度センサで察知した光度と水分量によって与える水の量を変化させるポンプをプランターに設置したり、
手袋に付けた曲げセンサの曲がり方によって光の強さが変るライトセーバーを作っても良いし、
たたかれた衝撃を察知して液晶ディスプレイに「イタイ」と表示させたりと、結構いろいろなものが作れます。


2010年1月20日水曜日

ブログを始めます


当ブログでは、主に植物や農業・エレクトロニクス、音楽に関する実験とプロジェクト情報をアップしたいと思います。
テーマである農業とエレクトロニクスの技術に関しては決して明るい方ではないので、
少しずつ作業を積み重ねてやっていくことにします。そのため、記述に間違いがあるかもしれませんが、ご容赦ください。

デバイスはArduinoをメインに使います。
これは、自動化された物理的なオブジェクトシステムをわりと簡単に構築することができる開発環境です。
去年在籍していた建築農業工作ゼミブログを参考に、まずは内容を復習してゆきます。
上記のブログからの引用がかなり増えるかもしれませんが、ブログの管理人kousakuさんの許可を得ております。

当初の目標は、自宅のベランダで、エレクトロニクスによって制御・栽培された農作物を継続的に摂取するためのシステム開発です。
農作物は春から植えるので当初はArduino周りの実験が主になりますが、徐々に農地や自然環境にフィールドを移してゆく予定です。

私個人のプロジェクトで終始するのではなく、最終的にはベクトルのあった他の方々との合同プロジェクトにシフトしていけたら幸いです。
では、よろしくお願いします。