Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
Arduinoの入出力と通信

はじめに

Arduinoに接続した機器から情報を読み取ったり、機器の制御を行うための基本となる、入出力と通信の方法についての説明です。

入出力と通信の種類

Arduinoでは、以下の入出力を行うことができます。

入出力の種類 説明
デジタル入力 ピンに接続した機器が出力するデジタル値を読み取る。
デジタル出力 ピンに接続した機器にデジタル値を書き出す。
アナログ入力 ピンに接続した機器が出力するアナログ値(電圧)を読み取る。
アナログ出力(PWM出力) ピンに接続した機器にアナログ値(PWM)を書き出す。
アナログ出力(DAC。Arduino Due) ピンに接続した機器にアナログ値を書き出す。

アナログ出力(PWM出力)は、PWMによる疑似的なアナログ出力です。アナログ出力(PWM出力)は、デジタル入出力ピンを利用します。Arduino Dueでは、DAC0とDAC1の2つのピンで、本物のアナログ出力を行うことができます。

Arduino UNOには、デジタル入出力ピンは14本(PWM出力できるのはこのうち6本)、アナログ入力ピンは6本付いています。また、アナログ入力ピンはデジタル入出力ピンとしても利用可能です。

Arduino Dueには、デジタル入出力ピンは54本(PWM出力できるのはこのうち12本)、アナログ入力ピンは12本ついています。また、アナログ出力ピンが2本あります。アナログ入力ピン・アナログ出力ピンはデジタル入出力ピンとしても利用可能です。

Arduinoボード デジタル入出力(PWM出力) アナログ入力 アナログ出力(DAC)
Arduino Uno 14本(PWM出力6本) 6本 0本
Arduino Due 54本(PWM出力12本) 12本 2本

上記の基本的な入出力に加えて、Arduino本体では以下に示すシリアル通信もサポートしています。

  • UART
  • I2C
  • SPI

それ以外にも、ハードウェアを追加することで、EthernetやXBeeなどにより通信を行うことができます。

入出力とは少し違いますが、ピンの入力状態の変化を検出して、関数を呼び出すこともできます。これを割り込みと言い、この時呼び出される関数を割り込みハンドラや割り込みサービスルーチンと呼びます。

入出力

デジタルとアナログそれぞれで入力と出力を行うことができます。

デジタル入力

digitalRead()を用いて、ピンの状態(ピンに接続している外部機器の状態)が0(LOW)か1(HIGH)かを知ることができます。デフォルトでは、デジタルピンは入力用に設定されているため、特に準備することなくデジタル入力に利用することができます。ただし、プログラムのわかりやすさを考慮すると、メモリがひっ迫するなどの理由がない限りは、適切に記述するのがいいと思います。出力用に設定したデジタルピンを入力用に(再)設定するためには、pinMode()を使用します。digitalRead()の使用例を以下に示します。

int digitalPin = 3;
int val = 0;

pinMode(digitalPin, INPUT);     // digitalPin(3番ピン)を入力モードに設定する。
val = digitalRead(digitalPin);  // digitalPinの状態を読み取る。

上記のプログラムでは、pinMode()でデジタルピンの3番を入力モードにしています。digitalRead()を実行した後、デジタルピンの3番の状態に応じて、valにLOWもしくはHIGHが代入されます。これにより、例えば、ピンに接続したスイッチが押されているのかなどを知ることができます。

digitalRead()以外にも、shiftIn()pulseIn()を使ってデジタルピンから入力することもできます。

デジタル出力

digitalWrite()を用いてピンを0(LOW)か1(HIGH)に設定することができます。デフォルトでは、デジタルピンは入力用に設定されているため、出力に用いる際には、pinMode()を利用して設定を変更しておく必要があります。digitalWrite()の使用例を以下に示します。

pinMode(LED_BUILTIN, OUTPUT);     // LED_BUILTINを出力モードに設定する。
digitalWrite(LED_BUILTIN, HIGH);  // LED_BUILTINにHIGHを出力する。

上記のプログラムで、LED_BUILTIN(13番ピン)にHIGHを出力します。LED_BUILTINにはボード上のLEDが接続されているので、LEDが光ります。

digitalWrite()以外にも、shiftOut()を使ってデジタルピンに出力することもできます。

アナログ入力

analogRead()を用いて、アナログピンにかかっている電圧を知ることができます。知ることができるのは、Arduino Unoの場合、0から参照電圧の1024分の1023倍までの電圧で、この関数は0から1023の数値を返却します。0が0Vに、1024が参照電圧に相当します(が、返却されるのは1023までです)。以下のグラフは、参照電圧が5Vの場合のAnalogRead()の戻り値と実際の電圧との関係を示しています。

以下に、analogRead()の使い方を示します。

int val = 0;
val = analogRead(analogPin);  // analogPinの電圧を取得する。

これにより、valにアナログピンの0番の値が代入されます。

この数字を実際の電圧に変換するためには、参照電圧を用いて計算します。求める電圧をV、analogRead()の返り値をval、参照電圧をVrefとすると、以下のように表すことができます。analogRead()の返り値が0のとき0V、1024のとき参照電圧となります(ただしanalogRead()の返り値の最大値は精度が10ビットの場合は、1023です)。

V = val / 1024.0 * Vref;

実際にプログラムを書く際には、型に注意してください。上記の例では、valやVrefをint型の変数として宣言しているときに、1024.0ではなく、1024を使ってしまうと、思った通りの結果が得られません。

参照電圧は、analogRefererence()を用いて、(Arduino UNOの場合)5V、1.1V、外部入力の3種類から選ぶことができます。例えば、参照電圧を5Vに設定したときは、0Vから、4.995Vまでを測定することができます。

analogRead()の返却値を実際の電圧に変換する別の方法として、map()を使う方法もあります。map()は、小数を扱えないので、電圧を、例えば、ミリボルト単位で表記して、以下のように計算することができます。

V = map(val, 0, 1024, 0, 5000);

Arduino Dueは、10ビットではなく12ビットの精度を持っています。ただし、デフォルトでは10ビットの精度に抑えられています。.analogReadResolution()を利用することで、変換精度を変更することができます。この場合、実際の電圧に変換するには設定した変換精度を用いる必要があります。

アナログ出力

アナログ出力(PWM出力)

Arduino Unoでは、デジタルピンの3番と5番、6番、9番、10番、11番には、PWM出力を行うこともできます。PWMとは、Pulse Width Modulationの省略で、HIGHとLOWとを交互に出力することにより、平均的な電圧を制御するための仕組みです。本当のアナログ出力が必要な場合は、D/A変換回路を利用する必要があります。analogWrite()の中で、指定したデジタルピンを出力モードに変更しているため、初期設定は不要です。

以下の図のように、HIGHをThigh時間、LOWをTlow時間の間隔で繰り返すと、結果として、出力される平均電圧は、V0*Thigh/(Thigh+Tlow)となります。このとき、1周期の時間に対するHIGHの時間の比率 Thigh/(Thigh+Tlow) のことを、デューティー比と呼びます。

ArduinoでPWM出力を行うにはanalogWrite()を使います。analogWrite()で指定するデューティー比は、0から255までの整数で、0%が0、100%が255に対応します。以下に、analogWrite()の使用例を示します。

int ledPin = 9;
analogWrite(ledPin, 200);  // ledPinデューティー比 200/255 で電圧を出力する。

Arduino Dueは、8ビット(255)ではなく12ビット(4095)までの値を設定することができます。ただし、デフォルトで利用できるのは8ビットです。analogWriteResolution()を利用することで、変更することができます。

アナログ出力(DAC)

Arduino Dueでは、DAC0とDAC1に対して、本物のアナログ出力を行うことができます。使い方はPWM出力と同じです。

通信

Arduinoは、シリアル通信を利用した複数のプロトコルを提供しています。接続する機器が対応しているプロトコルを使い分けることになります。

UART

UARTは、Universal Asynchronous serial Receiver and Transmitterの略で、非同期シリアル通信を行うことができます。Arduinoでは、ハードウェアの機能を利用したHardwareSerialとソフトウェアで実装したSoftwareSerialの2種類が用意されています。

HardwareSerialはArduinoソフトウェアの本体に組み込まれています。Arduino Unoでは、HardwareSerialを利用するためのオブジェクトである「Serial」がデフォルトで定義されており、通信速度を設定するだけで利用できるようになります。

HardwareSerialはハードウェアの機能を利用しているため、特定のピンでしか利用することができません。他のピンでもシリアル通信を行うために、SoftwareSeiralが開発されました。

SoftwareSerialはライブラリの形で提供されています。利用するピンが増えますが、HardwareSerialと比べると制約が少しきつくなっています。

UARTの簡単な使い方はこちら(ページ移動後、タイトルをクリック)。

I2C

I2Cは、Inter-Integrated Circuitの略で、データとクロックの2本の信号線を使って通信する同期型のプロトコルです。TWI(Two Wire serial Interface)と呼ばれることもあります。Arduinoでは、ハードウェアの機能を利用したWireライブラリによって実装されています。

I2Cは、一つのマスターデバイスと一つ以上のスレーブデバイスが通信を行うことができます。Arduinoはマスターになることもスレーブになることもできます。

I2Cの簡単な使い方はこちら(ページ移動後、タイトルをクリック)。

SPI

SPIは、Serial Peripheral Interfaceの略で、4本の信号線を使って通信する同期型のプロトコルです。Arduinoでは、ハードウェアの機能を利用したSPIライブラリによって実装されています。

割り込み

ピンの状態の変化に応じて、関数(割り込みハンドラ)を起動することができます。ただし、Arduino Unoでは、2番ピンと3番ピンだけが対応しています。Arduino Dueでは全てのピンが対応しています。

状態の変化として利用できるのは、以下の通りです。

種類 意味 備考
LOW ピンの値がLOWのときに割り込みを発生する
CHANGE ピンの値が変化したときに割り込みを発生する
RISING ピンの値がLOWからHIGHに変化したときに割り込みを発生する
FALLING ピンの値がHIGHからLOWに変化したときに割り込みを発生する
HIGH ピンの値がHIGHのときに割り込みを発生する Arduino Du、Zeroeのみ

割り込みハンドラの登録には、AttachInterrupt()を利用します。登録した割り込みハンドラを削除するには、detachInterrupt()を利用します。

割り込みハンドラとして利用できるのは、戻り値も引数も持たない関数だけです。

また、一つのピンには一つの割り込みハンドラだけです。例えば、一つのピンにRISING用の割り込みハンドラとFALLING用の割り込みハンドラの二つを登録することはできません(二つ登録すると後から登録した割り込みハンドラが有効となるようです)。

まとめ

Arduinoの入出力を簡単にまとめると以下のようになります。

入力 出力
デジタル digitalRead() digitalWrite()
アナログ analogRead() analogWrite()

また、通信を簡単にまとめると以下のようになります。

通信方式 信号線数 同期/非同期 利用方法
UART 2 非同期 HardwareSerial/SoftwareSerial
I2C 2 同期 Wireライブラリ
SPI 4 同期 SPIライブラリ

バージョン

Arduino 1.6.11



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2011 garretlab all rights reserved.
inserted by FC2 system