より効率的なプロジェクトのためのカスタムArduinoライブラリを作成する方法

Maker.io Staff | 2022年8月3日

How To Create Custom Arduino Libraries for More Efficient Projects

多くのArduinoプロジェクトは、一般的なLCDに文字を送るなどの標準的なタスクを実行するために、再利用可能なコードパーツに依存しています。プログラムごとに通信コードを一から書くのではなく、そのような標準的なコードをライブラリとしてパッケージ化し、他のプログラマがインポートしてプロジェクトで活用できるようにするのです。ライブラリの構築と利用は、プログラマのツールボックスにある貴重なツールであり、このテクニックはArduinoのコードを書くときだけに役立つわけではありません。Arduinoのカスタムライブラリの作成方法と、作成したコードをパッケージ化して公開し、他のプログラマと共有する方法の基礎を学びます。

基本的な非ライブラリの例

この記事では、以下の短いArduinoのコード例を用いて、再利用可能なコードを外部ライブラリに移動するプロセスを説明します。次のコードを考えてみましょう。

#define DELAY_TIME 100
#define OUT_PIN 13

unsigned long lastMillis = 0;
boolean state = false;

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

void loop()
{
  unsigned long currentMillis = millis();

  if(currentMillis - lastMillis > DELAY_TIME)
  {
	state = !state;
	digitalWrite(OUT_PIN, state);
  }
}

この単純なプログラムは、ブロッキングdelay()関数を使用せずに、ArduinoのデジタルI/Oピンの1つの出力状態を切り替えます。このコードは、多くのプロジェクトでよく使用する標準的な方法の簡単な例です。

しかし、異なる遅延時間を使用して複数のピンを切り替えたい場合は、ほとんどのコードを複製する必要があります。したがって、この機能を外部クラスにアウトソーシングすることで、将来のプログラムの複雑さを大幅に軽減できます。

コードの再利用可能な部分を特定する

コードを外部ライブラリに移す前に、プログラムのどの部分を再利用できるかを確認することから始めましょう。上記の例では、setup()とdelay()関数から2つの変数とコードを外部ライブラリに移動させることができます。変数を修正せずにそのまま新しいファイルに移動することはできますが、ライブラリクラスの古いセットアップやループメソッドの内容については、新しい関数を導入する必要があります。通常、セットアップ関数の代わりにinit()、start()、またはbegin()などを呼び出します。しかし、以下のようにコンストラクタを作成することもできます。

ライブラリクラスの作成

外部ライブラリに移動できる部分を特定したら、いよいよクラスを作成します。C++では、クラスは2つのファイルから構成されています。ヘッダファイル(拡張子.h)とソースコードファイル(拡張子.cpp)です。ヘッダは、正確な動作や値を定義せずに、クラスに存在するすべてのメソッドと変数を定義します。これに対して、ソースファイルにはメソッドの具体的な実装が含まれています。

カスタムライブラリを作成するには、Arduinoライブラリフォルダに移動します。次に、NonBlockingToggleという名前のフォルダ、またはライブラリに付けたい名前を作成します。次に、その新しいフォルダ内に2つのファイルを作成し、「NonBlockingToggle.h」と「NonBlockingToggle.cpp」という名前を付けます。Arduino IDEではスケッチブックの外部にあるファイルを編集できないため、これらのファイルの内容を変更するには、Notepad++などの外部テキストエディタを使用する必要があります。

How To Create Custom Arduino Libraries for More Efficient Projects

ライブラリフォルダ内に新しいフォルダを作成し、カスタムArduinoライブラリのソースコードを格納する2つの新しいファイルを追加します。

ヘッダファイルの書き込み

前述のように、ヘッダファイルは、コンパイラがカスタムソースコードファイルで検出できる変数とメソッドのリストとして機能します。この例では、ヘッダファイルは次のようになります。

#ifndef NonBlockingToggle_h
#define NonBlockingToggle_h

#include "Arduino.h"

class NonBlockingToggle
{
  public:
	NonBlockingToggle(unsigned pin, unsigned long delay_time);
	void update();

  private:
	unsigned long lastMillis = 0;
	boolean  state = false;
	unsigned OUT_PIN;
	unsigned long DELAY_TIME;

};

#endif

ご覧のように、新しいクラスには2つの引数(トグルするピン番号と遅延時間)を取るシンプルなコンストラクタを作成しました。コンストラクタは、新しいオブジェクトを作成するときに呼び出す特別なメソッドです。この特殊関数は、常にクラスと同じ名前を持ちます。次に、ヘッダファイルは、メインコードがそのループ関数内から呼び出すことができるパブリック更新メソッドを定義します。最後に、ヘッダには、メインソースコードで以前に見られた4つの変数の定義が含まれています。

Nプリプロセッサステートメントの#ifndef, #define, #endifに注意してください。これにより、ユーザーが誤ってあなたのライブラリを2回以上インクルードすることを防ぐことができます。これは、ユーザーがあなたのコードを参照する他のライブラリをインクルードした場合に簡単に起こり得ることです。最後に、Arduinoのヘッダをカスタムヘッダファイルにインクルードしてください。そうすることで、Arduinoの標準的な関数をライブラリの中で使用することができます。なお、Arduino IDEは、Arduinoのプログラムにこのヘッダを自動的にインクルードしますが、カスタムライブラリや外部ファイルには適用されません。

CPPソースファイルの書き込み

最後に、元のArduinoプログラムからカスタムライブラリのCPPファイルにある新しい関数に内容を移動させることができます。

#include "NonBlockingToggle.h"

unsigned long lastMillis = 0;
boolean  state = false;
unsigned OUT_PIN;
unsigned long DELAY_TIME;

NonBlockingToggle::NonBlockingToggle(unsigned pin, unsigned long delay_time)
{
  OUT_PIN = pin;
  DELAY_TIME = delay_time;

  pinMode(OUT_PIN, OUTPUT);
}

void NonBlockingToggle::update()
{
  unsigned long currentMillis = millis();

  if(currentMillis - lastMillis > DELAY_TIME)
  {
	state = !state;
	digitalWrite(OUT_PIN, state);
  }
}

先に作成したヘッダファイルを必ずインクルードしてください。そして、ヘッダで定義された関数を作成します。すべての関数名の前にクラス名を記述し、2つの名前を二重コロンで接続する必要があることに注意してください。以上により、CPPファイルには、この記事の冒頭で紹介したメインのArduinoプログラムのコードが含まれるようになりました。ただし、カスタムライブラリを利用するには、元のファイルを更新する必要があります。

カスタムライブラリのインポートと使用

ArduinoのIDEに戻り、記事の冒頭のファイルを更新してください。

#include <NonBlockingToggle.h>

#define DELAY_TIME 100
#define OUT_PIN 13

NonBlockingToggle toggle(OUT_PIN, DELAY_TIME);

void setup()
{ }

void loop()
{
  toggle.update();
}

ご覧のように、コードは以前より大幅に短くなり、コードを書き換えることなく、好きなだけ多くのプログラムにわたって機能をインポートして使用することができるようになりました。カスタムライブラリは、Arduinoの外部ライブラリと同じようにインポートすることができます。

ライブラリにサンプルを追加する

一般的に、ダウンロードしてインストールするほとんどのArduinoライブラリには使用例があります。これらの短い例は、ユーザーがプロジェクトであなたのライブラリをどのように利用できるかを示しています。コードサンプルを使ってカスタムライブラリを拡張する場合、フォルダを作成してソースコードファイルを移動させるだけで、簡単に拡張することができます。

まず、カスタムライブラリのフォルダの中にサンプルフォルダを作成します。そして、ライブラリのインクルードや使用方法を紹介するArduinoスケッチをそのフォルダに移動させます。

How To Create Custom Arduino Libraries for More Efficient Projects

ライブラリにサンプルとして含めたいスケッチをすべて「examples」というフォルダに追加します。ユーザーは、Arduino IDEのメインメニューバーを使って、これらのサンプルスケッチにアクセスできます。

まとめ

ソフトウェアライブラリは、コードを再利用可能なユニットにパッケージ化し、それを必要とするあらゆるプロジェクトにインクルードすることができる素晴らしい方法です。これにより、同じソフトウェアを繰り返し書き直すことを避け、カスタムライブラリを他の開発者と共有することができます。

Arduinoプロジェクト用のカスタムライブラリの作成は、Arduino IDEの標準ライブラリフォルダ内の別フォルダにある外部クラスファイルやヘッダファイルにアウトソースしたいコードを移動するだけで、簡単に作成できます。ここでは、ライブラリが必要とする数のファイルを追加することができます。このチュートリアルでは、わかりやすくするために、1つのクラスだけを使用してプロセスを説明しました。

最後に、サンプルフォルダを追加し、スケッチブックからいくつかのスケッチをそのフォルダにコピーすることで、カスタムArduinoライブラリにサンプルを追加することができます。他の開発者は、Arduino IDEのメインメニューバーから、これらのサンプルスケッチにアクセスすることができます。GitHubなどのプラットフォームを利用してライブラリを配布したり、ライブラリを含むZIPアーカイブを作成し、個人のブログやウェブサイトにアップロードするなどして配布することができます。また、Arduino IDEライブラリマネージャに登録するために、こちらの投稿手順に従ってライブラリを投稿することもできます。 https://github.com/arduino/library-registry




オリジナル・ソース(English)