Arduinoの配列の使い方――複数センサーの値を一元管理する設計術。
センサーが増えるたびに変数を増やしていませんか。配列の基本構文から、構造体との使い分け、複数センサーをまとめて扱う実践手順までを解説します。
目次
01なぜ複数センサーの管理に配列が必要なのか
結論から言えば、同種のセンサーを3個以上扱うプロジェクトでは、センサーごとに変数を用意する書き方は破綻しやすい。temp1、temp2、temp3のように変数を増やしていくと、読み取り処理・平均化処理・しきい値判定処理をセンサーの数だけコピペすることになり、センサーを1個追加するたびに複数箇所を修正する必要が生じる。配列(array)を使えば、これらの値をひとつの変数名とインデックス番号でまとめて扱い、for文と組み合わせて処理を1箇所に集約できる。
実例として、Arduino UNOを使って温度・湿度・気圧・PM2.5・CO2という5種類の環境センサーからデータを取得する自作プロジェクトの事例がある。この事例では、センサーごとに読み取りタイミングや待ち時間の制約が異なる点が課題として挙げられており、複数のセンサーを効率よく扱うロジックの設計が必要になっている。Arduino UNOで複数の環境センサーからデータ取得を行った事例(t-hom’s diary)では、CO2センサーの計測待ち時間を利用して他のセンサーの読み取りを並行させる設計が紹介されている。
編集部見解:センサー1〜2個の小規模なプロジェクトでは、個別の変数のままでも十分読みやすい。配列化の効果が顕著になるのは、同種のセンサーが3個を超え、かつ「読み取る」「平均する」「しきい値と比較する」といった処理が全センサー共通になってきたタイミングだと考えられる。
― YOFUKASI AI編集部
本記事では、Arduinoにおける配列の基本構文から、複数の型を扱いたい場合の構造体との使い分け、そして複数センサーのデータを実際に配列でまとめる手順までを、初心者から中級者を対象に体系的に解説する。
02Arduinoにおける配列の基礎知識
配列(array)とは、同じ型のデータをインデックス番号でアクセスできる変数の集まりのことである。Arduino公式ドキュメントでも、配列はインデックス番号でアクセスされる変数の集まりであると定義されており、単純な配列の利用自体は比較的簡単に扱えると説明されている。
Arduinoにおける配列の一次情報は、Arduino公式 Language Reference「array」にまとまっている。公式リファレンスでは配列がインデックス番号でアクセスされる変数の集まりであり、Arduinoスケッチが書かれているC++言語における配列は複雑になり得るが、単純な配列を扱うのは比較的容易だと説明されている。また配列は0番から番号が振られる点についても配列は0から始まるインデックスを持ち、最初の要素はインデックス0にあると述べられている。
実際に配列を使ったサンプルスケッチは、公式のビルトイン例でも公開されている。Arduino公式「How to Use Arrays」では、複数のLEDピン番号を配列にまとめ、for文で順番に点灯させるサンプルが紹介されており、配列を使うことでピンの順序を自由に入れ替えられる利点が説明されている。
用語の整理
- 要素(element):配列を構成する1つ1つのデータ。
- インデックス(index):配列内の要素の位置を示す番号。Arduino(C++)では0番から始まる。
- 添字(そえじ):インデックスの別称。
sensor[0]の[0]部分を指す。
配列とあわせて理解しておきたいのがスコープの概念である。関数の中だけで有効なローカル変数と、プログラム全体で共有されるグローバル変数の違いについては、Arduino公式 Language Reference「scope」で解説されている。複数センサーの値をグローバル配列として保持するか、関数内のローカル配列として都度取得するかは、後述の第4章・第5章で扱う設計判断のポイントになる。
Arduinoの基礎文法や、関数の作り方をまだ体系的に学んでいない場合は、先に基礎を押さえておくとこの先の理解がスムーズになる。Arduinoのコードの書き方の基礎はこちらの記事で詳しく解説している。
03配列の仕組みと技術的背景
Arduinoの配列は、基本的に次の3通りの方法で宣言できる。
// (A) 要素数を指定して宣言のみ行う(値は未初期化)
int sensorValues[5];
// (B) 要素数を省略し、初期化リストで宣言と同時に値を設定する
int sensorPins[] = {A0, A1, A2, A3, A4};
// (C) 要素数を指定しつつ、初期化リストで値も設定する
float temperatures[3] = {21.5, 22.0, 20.8};
複数のセンサーを扱う際は、ピン番号の配列とセンサー値の配列をペアで用意し、for文で同じインデックスを使って両方にアクセスするのが基本形になる。
const int sensorPins[3] = {A0, A1, A2};
float sensorValues[3];
void readAllSensors() {
for (int i = 0; i < 3; i++) {
int raw = analogRead(sensorPins[i]);
sensorValues[i] = raw * (5.0 / 1023.0); // 電圧に変換
}
}
2次元配列と構造体という選択肢
センサーの「現在値」だけでなく「過去数回分の履歴」も持たせたい場合は、2次元配列を使うことで表形式のデータを扱える。2次元配列の宣言方法や添字の考え方については、日本語で図解付きに解説した記事がある。Arduino IDE(2次元配列の使い方)(NOBのArduino日記!)では、2次元配列が表のようなデータを扱うときに便利な変数であり、行と列を指定することで配列の要素に連続してアクセスできると説明されている。
温度・湿度・照度のように型もセンサーの性質も異なる複数のデータを扱う場合、単純な配列では「同じ型しか格納できない」という制約に突き当たる。この場合は
struct SensorReading { float value; int pin; unsigned long lastRead; };のような構造体を定義し、その構造体の配列を用意することで、型の異なる複数の値を1つの要素としてまとめて扱える。
一方で、配列のサイズを大きくしすぎるとメモリを圧迫する点には注意が必要である。Arduino UNOに搭載されているATmega328Pは、SRAM(変数を保持するための揮発性メモリ)の容量が非常に小さい。Arduino 入門 番外編11【搭載メモリについて】(おもろ家)では、SRAMのメモリサイズが小さいためプログラム作成時にはSRAMのメモリサイズを意識する必要があり、特に文字列や配列を使用する場合はメモリがすぐになくなってしまうため注意が必要だと説明されており、同記事内でUNOのSRAM容量が2キロバイトである点も紹介されている。センサー履歴を保持する2次元配列を大きくしすぎると、この上限に達しやすい。
圧力センサーや筋電センサーのように、複数チャネルのアナログ値を継続的に読み取るセンサーの実例は、以下の記事でも詳しく扱っている。配列を使った読み取り処理の実装イメージをつかむ際の参考になる。
04配列・構造体・個別変数の比較と選択肢
複数センサーの値をどう保持するかは、センサーの数と型の統一性によって最適解が変わる。以下に3つの選択肢を整理する。
| 項目 | A. 個別変数(配列不使用) | B. 単純配列 | C. 構造体の配列(struct配列) |
|---|---|---|---|
| 向いている規模 | センサー1〜2個 | 同種センサー3個以上 | 異種データを組にして扱う場合 |
| 扱えるデータの型 | 制約なし(個別に型指定) | 同じ型のみ | 異なる型を1要素にまとめられる |
| for文との相性 | 低い(個別に記述が必要) | 高い | 高い |
| 可読性 | 少数なら高い | センサー数が多いほど高い | 設計次第で高い |
※各手法の適用規模の目安は編集部見解を含む。配列と構造体の文法的な定義についてはArduino公式 Language Reference「array」を参照。
迷った場合の目安として、「今後センサーの種類・数が増える予定があるか」を基準にするとよい。将来的にセンサーが増える見込みがあるなら、最初から単純配列または構造体配列で設計しておくと、後からの拡張が容易になる。
05実践:複数センサーのデータを配列でまとめる5ステップ
ここでは「3個の温度センサーの値を配列で管理し、平均値としきい値判定を行う」という編集部想定シナリオを題材に、個別変数のべた書きコードを配列に置き換える具体的な手順を示す。
-
STEP1. 個別変数になっている箇所を洗い出す
現在のコードの中で、
temp1、temp2、temp3のように連番の変数名が使われている箇所を探す。同じ処理(読み取り・変換・比較)が変数ごとに繰り返し書かれていれば、配列化の候補になる。実例:温度センサー3個分の読み取り処理が、変数名だけ違う形で3回コピペされていることを確認した(合計約15行)。 -
STEP2. ピン番号配列とデータ配列をペアで宣言する
センサーが接続されているピン番号を
const int配列として固定し、読み取った値を格納する配列を別に用意する。要素数はセンサーの個数と一致させる。実例:const int tempPins[3] = {A0, A1, A2};とfloat temps[3];の2つの配列を宣言した。センサーを1個追加する場合も、この2箇所の要素数を変更するだけで済む構成にした。 -
STEP3. for文で読み取り処理を1箇所に集約する
sizeof(tempPins) / sizeof(tempPins[0])で要素数を取得し、for文の範囲として使う。これにより、配列の要素数を変更してもfor文の条件を書き換える必要がなくなる。実例:for (int i = 0; i < 3; i++) { temps[i] = readTemp(tempPins[i]); }という3行に、元は15行あった読み取り処理を集約した。 -
STEP4. 平均値・しきい値判定も配列ベースの処理に置き換える
個別変数を1つずつ比較していた判定処理を、配列を走査するループに置き換える。平均値の算出も同様に、合計値をfor文で積み上げてから要素数で割る形にする。
実例:3個の温度の平均を求める処理をfloat sum = 0; for (int i = 0; i < 3; i++) sum += temps[i]; float avg = sum / 3;という形に統一した。しきい値28.0℃を超えたセンサーの本数をカウントする判定も同じループ内に追加した。 -
STEP5. シリアル出力でセンサーごとの値を確認する
配列化した後も、デバッグ時にはどのセンサー(どのインデックス)の値が想定と違うかを個別に確認できるようにしておく。for文の中でインデックス番号とあわせてシリアル出力する。
実例:Serial.print("Sensor "); Serial.print(i); Serial.print(": "); Serial.println(temps[i]);という出力を追加したところ、3個中1個のセンサー(インデックス1)だけ配線の接触不良で異常値を返していたことが判明した(編集部想定シナリオ)。
センサー値をArduinoからPython側に送って可視化・分析する場合の実例は、以下の記事でも扱っている。配列でまとめたデータをシリアル通信で送信する際の参考になる。
ArduinoとPythonを組み合わせたリハビリ応用の実例はこちらの記事で紹介している。複数の圧センサー値を継続的に取得し、臨床データとして扱う構成の参考になる。
06注意点・よくある誤解
Arduino(C++)の配列は0番から始まる。要素数3の配列であれば有効な添字は0・1・2までで、3にアクセスすると配列の範囲外を読み書きしてしまう。for文の条件をi <= 3のように書き間違えると、この範囲外アクセスが発生しやすい。
将来の拡張を見越して配列サイズを必要以上に大きく確保すると、Arduino UNOのようにSRAM容量が小さいボードではメモリ不足の原因になりやすい。センサーの点数や履歴の必要件数から逆算し、必要最小限のサイズに留めるのが基本となる。
配列化のメリットが発揮されるのは、同じ処理を繰り返すセンサーが複数ある場合である。センサーが1〜2個で今後も増える予定がないなら、個別変数のままの方がコードの意図が伝わりやすいこともある。配列化は目的ではなく手段であることを意識したい。
07FAQ
参考文献
- Arduino公式ドキュメント編集チーム「array」Arduino Documentation, 2024年改訂. https://docs.arduino.cc/language-reference/en/variables/data-types/array/
- Arduino公式ドキュメント編集チーム「How to Use Arrays」Arduino Documentation. https://docs.arduino.cc/built-in-examples/control-structures/Arrays/
- Arduino公式ドキュメント編集チーム「scope」Arduino Documentation, 2024年改訂. https://docs.arduino.cc/language-reference/en/variables/variable-scope-qualifiers/scope/
- NOB「Arduino IDE(2次元配列の使い方)」NOBのArduino日記!, 2021年. https://nobita-rx7.hatenablog.com/entry/28004501
- おもろ家「Arduino 入門 番外編11【搭載メモリについて】(Flash SRAM EEPROM)」おもろ家, 2020年. https://omoroya.com/arduino-extra-edition-11/
- t-hom「Arduino UNOで複数の環境センサー(温度、湿度、気圧、PM2.5、CO2)からデータ取得」t-hom's diary, 2020年. https://thom.hateblo.jp/entry/2020/11/08/122302
- 本文中の具体的な削減行数・処理時間・故障原因等の数値は、断りのない限り編集部想定シナリオに基づく試算であり、実測データではありません。
関連記事(内部リンク)
- Arduinoのコードの書き方|基礎から応用まで全てがわかる初心者の手引き ― https://yofukasi-lab-wp.com/2025/03/07/arduino-cord/
- 圧センサーを用いた電子工作の基礎編|圧センサーの種類、配線、読み取り値など徹底解説 ― https://yofukasi-lab-wp.com/2025/03/08/pressure/
- Arduino×筋電センサー完全ガイド:配線・コード例からリハビリ応用まで徹底解説 ― https://yofukasi-lab-wp.com/2025/03/09/emg/
- ArduinoとPythonとセンサーを用いたリハビリテーションへの応用 ― https://yofukasi-lab-wp.com/2025/03/08/rehabilitation/
コメント