Arduino用ライブラリを書く

Arduinoの機能を拡張するために、ライブラリを作成します。スケッチからライブラリを作成する過程を通じて一歩一歩進んでいきます。


LAST REVISION: 2022/11/23 23:29


このドキュメントはArduino用ライブラリの作成方法を説明します。モールスコードを光らせるスケッチから始め、その機能をライブラリにする方法を説明します。これにより、あなたの書いたコードを簡単に使えるようになり、ライブラリを改善することで簡単に更新することができるようになります。

ライブラリで良いArduino形式のAPIを作成するには、ライブラリ作成用Arduinoスタイルガイドを参照してください。

簡単なモールスコードを作るスケッチから始めます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int pin = 13;

void setup()
{
  pinMode(pin, OUTPUT);
}

void loop()
{
  dot(); dot(); dot();
  dash(); dash(); dash();
  dot(); dot(); dot();
  delay(3000);
}

void dot()
{
  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
  delay(250);
}

void dash()
{
  digitalWrite(pin, HIGH);
  delay(1000);
  digitalWrite(pin, LOW);
  delay(250);
}

このスケッチを実行すると、13番ピンにSOS(緊急通報)のコードを光らせます。

スケッチには、ライブラリに持ち込む必要のあるいくつかの部品があります。最初は、もちろん、dot()dash()関数で、実際に点滅を行います。次に、どのピンを使うかを決めるのに使われるpin変数があります。最後に、ピンを出力に初期化するためのpinMode()の呼び出しがあります。

スケッチをライブラリにしていきましょう。

ライブラリには少なくとも二つのファイルが必要です。ヘッダファイル(拡張子は.h)とソースファイル(拡張子は.cpp)です。ヘッダファイルはライブラリの定義が書かれています。基本的には、内部にあるすべてのものの一覧です。一方、ソースファイルには実際のコードが書かれています。このライブラリを「Morse」と呼びましょう。なので、ヘッダファイルはMorse.hとなります。その中に何を書いていくのかを見ていきます。最初は少し不思議に思うかもしれません。関連のソースファイルを見ていくと、意味が分かってきます。

ヘッダファイルの中心は、必要な変数とともにクラスとしてまとめられた、ライブラリ内の各関数の行です。

1
2
3
4
5
6
7
8
9
class Morse
{
  public:
    Morse(int pin);
    void dot();
    void dash();
  private:
    int _pin;
};

クラスは、関数と変数の集合が一か所に集められたものです。これらの関数と変数は、ライブラリの利用者から利用できる公開(public)のものと、クラス自身からだけアクセスできる非公開(private)に分けられます。各クラスにはコンストラクタと呼ばれる特別な関数があり、クラスのインスタンスを作成するときに使われます。コンストラクタはクラスと同じ名前で、戻り値の型はありません。

ヘッダファイルには、いくつか必要なものがあります。一つは、#include指令で、Arduino言語の標準の型や定数を利用可能とします(これは通常のスケッチには自動的に挿入されますが、ライブラリには挿入されません)。以下のような形です。これは、先ほどのクラス定義の前に記述します。

1
#include "Arduino.h"

最後に、奇妙な形をした要素で、ヘッダファイル全体を囲みます。

1
2
3
4
5
6
#ifndef Morse_h
#define Morse_h

// the #include statement and code go here...

#endif

基本的には、これは誤ってライブラリを2回#includeしたときの問題を防ぎます。

最後に、通常は、ライブラリ名や何をするのかという短い説明、作成者名、作成日、ライセンスなどのコメントを、一番上に記述します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/*
  Morse.h - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
*/
#ifndef Morse_h
#define Morse_h

#include "Arduino.h"

class Morse
{
  public:
    Morse(int pin);
    void dot();
    void dash();
  private:
    int _pin;
};

#endif

次に、ソースファイル(Morse.cpp)の各部を見ていきましょう。

最初にいくつかの#include指令が来ます。これらは、後のコードが標準的なArduino関数とあなたのヘッダファイル内の定義を利用できるようにします。

1
2
#include "Arduino.h"
#include "Morse.h"

次にコンストラクタが来ます。これは、クラスのインスタンスを作成するときに起こることを説明するものです。この場合、ユーザはどのピンを使いたいのかを指定します。ピンを出力に設定し、他の関数で利用できるようにプライベート変数に値を保持します。

1
2
3
4
5
Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

このコードにはいくつか奇妙な点があります。最初は、関数名の前のMorse::です。これは、関数がMorseクラスの一部であることを示します。このクラスの他の関数でも再度出てきます。二つ目の通常とは異なる点は、プライベート変数名(_pin)の、アンダースコアです。実際には、この変数は、ヘッダファイルの定義に従っている限りは、好きな名前にすることができます。名前の前にアンダースコアをつけるのは、変数がプライベートであることを明確にするためによく行われることで、関数の引数名(この場合pin)と区別もしています。

次に、スケッチからライブラリに移す実際のコードが、ようやく来ます。関数名の前にMorse::がつくことと、pinではなく_pinとなっている以外は、ほとんど同じように見えます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
void Morse::dot()
{
  digitalWrite(_pin, HIGH);
  delay(250);
  digitalWrite(_pin, LOW);
  delay(250);  
}

void Morse::dash()
{
  digitalWrite(_pin, HIGH);
  delay(1000);
  digitalWrite(_pin, LOW);
  delay(250);
}

最後に、冒頭にコメントヘッダを入れることが一般的きです。全体を見てみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
  Morse.cpp - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
*/

#include "Arduino.h"
#include "Morse.h"

Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

void Morse::dot()
{
  digitalWrite(_pin, HIGH);
  delay(250);
  digitalWrite(_pin, LOW);
  delay(250);  
}

void Morse::dash()
{
  digitalWrite(_pin, HIGH);
  delay(1000);
  digitalWrite(_pin, LOW);
  delay(250);
}

必要なことは、以上で終了です。いくつか追加した方がいいものもありますが、それは後で述べます。ライブラリをどのように使うのかを見ていきます。

まず、スケッチブックディレクトリのlibrariesサブディレクトリ内に、Morseディレクトリを作成します。Morse.hとMorse.cppファイルをそのディレクトリにコピーもしくは移動します。その後、Arduino環境を立ち上げます。スケッチ > ライブラリをインクルード を開くと、その中にMorseがあります。ライブラリは、それを使うスケッチと一緒にコンパイルされます。ライブラリがビルドされないようであれば、ファイルが本当に.cppと.hで終わるか確認してください。例えば、.pdeや.txtの拡張子は不要です。

古いSOSのスケッチが、ライブラリを使ってどのようになったのか見てみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <Morse.h>

Morse morse(13);

void setup()
{
}

void loop()
{
  morse.dot(); morse.dot(); morse.dot();
  morse.dash(); morse.dash(); morse.dash();
  morse.dot(); morse.dot(); morse.dot();
  delay(3000);
}

いくつかのコードがライブラリへ移ったこと以外に、違いがあります。

まず、スケッチの最初に#include指令を追加しました。スケッチからMorseライブラリを利用できるようにし、ボードに送られたコードをインクルードします。スケッチでライブラリが不要となれば、容量を節約するために#include指令を削除する必要があることを示しています。

次に、morseというMorseクラスのインスタンスを作成します。

1
Morse morse(13);

この行が実行されると(これは実際にはsetup()関数よりも前に実行されます)、Morseクラスのコンストラクタが呼ばれ、ここで与えた引数(この場合、13です)が渡されます。

setup()には何も書かれていないことに注目してください。pinMode()の呼び出しがライブラリに移ったためです(インスタンスが作成されるときに実行されます)。

最後に、dot()dash()関数の呼び出しです。それらの前に、利用するインスタンス名であるmorseをつける必要があります。Morseクラスのインスタンスを複数持つことができ、それぞれのインスタンスの_pinプライベート変数にそれらのピンが格納されます。各インスタンスの関数を呼ぶことで、関数を呼んだ時に、どのインスタンス変数が使われるかを指定します。すなわち、以下の双方があったとき、

1
2
Morse morse(13);
Morse morse2(12);

morse2.dot()を呼んだときは、_pinは12です。

新しいスケッチを書くとき、環境は我々のライブラリを認識せず、色付けされていないことに気づくと思います。残念ながら、Arduinoソフトウェアは、ライブラリ内で何を定義したのかを自動的に認識することはできません(このような機能があれば素晴らしいのですが)。このため、いくつか設定する必要があります。このため、keywords.txtというファイルをMorseディレクトリ内に作成します。そのファイルは以下のようなものです。

1
2
3
Morse   KEYWORD1
dash    KEYWORD2
dot KEYWORD2

各行には、キーワード名を書き、その後にタブ(スペースではありません)と、キーワード種別が続きます。クラスはKEYWORD1でオレンジ色になります。関数はKEYWORD2で茶色になります。新しいキーワードを認識させるために、Arduino環境を再起動する必要があります。

あなたのライブラリを使うスケッチ例を提供することは素晴らしいことです。このため、examplesディレクトリをMorseディレクトリ内に作成します。そして、先ほど書いたスケッチを含むディレクトリ(SOSとします)をexamplesディレクトリに移動もしくはコピーします(スケッチは、スケッチ > スケッチフォルダを表示、で見つけることができます)。Arduino環境を再起動(これが最後です。約束します)すると、ファイル > スケッチ例 メニューに、スケッチ例のあるMorseが表示されます。ライブラリの利用方法をよく説明するコメントを追加してください。

完全なライブラリ(keywordsとexamplesを含む)を確認したければ、Morse.zipをダウンロードしてください。

Arduinoのライブラリマネージャでライブラリを使ってもらいたければ、library.propertiesファイルを追加する必要があります。これについてはライブラリ仕様を参照してください。Arduinoライブラリマネージャに関する一般的な質問は、FAQを見てください。

問題や提案がある場合は、Software Development forumに投稿してください。

ライブラリ用に良いArduino形式のAPIを作成するには、ライブラリ作成用Arduinoスタイルガイドを参照してください。

オリジナルのページ

https://docs.arduino.cc/learn/contributions/arduino-creating-library-guide

最終更新日

December 4, 2022

inserted by FC2 system