今回はArduino Microでシリアルモニタを使用する際の注意点を説明します。
シリアルモニタ
第21回の記事で「シリアルモニタ」の使い方を習得しました。
シリアルモニタの基本的な使い方は第21回の記事で説明した通りなのですが、Arduino Microでシリアルモニタを使用する際は注意点があります。
この補足記事ではその問題の中身と対処方法を説明します。
Arduino Microのシリアルの問題点
Arduino Microでシリアルモニタを使おうとして、次のようなスケッチを書いても実はうまく動きません。
/*
* シリアルモニタの動作確認用スケッチ
*/
void setup() {
Serial.begin(9600); // シリアル初期化
Serial.println("シリアルモニタを開始しました!"); // シリアルモニタにテキストを表示
}
void loop() {
// loopでは何もしない
}
このスケッチでは、setup
関数の中でSerial.println
を使って「シリアルモニタを開始しました!」というテキストを表示する、とてもシンプルな制御をしています。
もしお手間でなければ、実際にこのスケッチをコピペしてArduino Microで動作させてみてください。おそらくシリアルモニタに何も表示されないと思います。
しっかりとSerial.begin(9600);
と書いたあとにSerial.println
関数でテキストを表示しているのに、表示されないのは謎ですよね。
これから、この問題の原因と対処方法について説明していきます。
シリアルモニタに文字が表示されない原因
シリアルモニタはUSB経由でデータ通信を行っています。
ArduinoボードのUSBの通信方法は、大きく分けて2種類あるんです。
これからその2種類の特徴について説明します。
次のArduinoボードは「Arduino Uno R3」という製品で、2023年までは定番のボードでした。(現在は後継の「Arduino Uno R4」が定番ボードになっています)

このボードには、本体部品(マイコン)のほかに、外部とUSBで通信するためのUSB通信モジュールが搭載されています。

このように専用のUSB通信モジュールが搭載されているArduinoボードでは、先ほどのスケッチでシリアルモニタに文字が表示されない、ということはありません。
次に、Arduino Microボードを確認してみましょう。

Arduino Uno R3にくらべると、ずいぶんスッキリしてますよね。
Arduino MicroにはUSBで通信するための専用の通信モジュールが搭載されていないんです。
でも今まで、Arduino MicroをUSBケーブルでPCに接続してスケッチを送ったり、シリアルモニタに文字を表示したりしてましたよね。
これは、次のイラストのようにArduino Microのモジュール本体の中に、外部とUSBで通信する機能が入っているためです。

ただ、シリアルモニタでUSB通信をする場合、この組み込まれているUSB通信機能はすぐに使えない状態になっています。
このUSB通信機能をシリアルモニタで使うには、Serial.begin
関数によりUSB通信の機能が動作を開始して使えるようになります。
ただし、Serial.begin(9600);
の後、ほんのちょっとの時間(せいぜい数ms)、準備に時間がかかります。
このほんのちょっとの準備時間が、シリアルモニタに表示できない原因になっています。そこで、もう一度スケッチを確認してみましょう。
先ほどのスケッチがうまく動かなかった原因は、次のようにSerial.begin(9600)
でUSB通信機能を準備しますが、その準備が終わる前にSerial.println関数でテキストを表示しようとしたため、シリアモニタに何も表示されませんでした。

つまり、Arduino Microボードでシリアルモニタを使用する場合、Serial.begin
関数で「シリアルモニタを使いますよ!」と伝えた後、Arduino MicroがUSB通信機能の準備が終わるまで待つ必要があるんです。
それでは次に、「USB通信機能の準備が終わるまで待つ」という処理をスケッチにどのように書けばよいのか説明します。
シリアルが準備できるまで待つ処理
Arduino Microでシリアルを使用する場合、スケッチには次のように書きます。(setup関数のみ示しています)
setup() {
Serial.begin(9600); // シリアル初期化
// USB通信機能の準備ができるまで待つ
while( !Serial ) {
}
Serial.println("シリアルモニタを開始しました!"); // シリアルモニタにテキストを表示
}
「USB通信機能の準備ができるまで待つ」という処理は、このスケッチの6〜7行目の部分です。
つまり、Serial.begin関数のあと、Serial.println関数を使う前に次の2行を追加すればOKです!
while( !Serial ) {
}
この具体的な動作を完全に理解するには新しい知識が必要になりますので、ここではこの2行が何をしているのか簡単に説明します。
while
の条件として、Serial
という変数(のようなもの)を使っています。
Serial
はスケッチでは宣言していませんが、これはArduino IDEが裏で宣言してくれていますので、どのようなスケッチでも使うことができます。
このSerial
は、USB通信機能の準備ができていない場合は「0」、準備ができた場合は「1」になります。
また、Serial
の前についている!
は否定の意味の記号です。
ちょっとややこしくなりますが、USB通信機能の準備ができていないとき、Serial
の値は「0」ですので、!Serial
その否定で「1」になります。
while
は条件が0以外の時に繰り返す制御をしますので、while( !Serial )
は、準備ができていない間繰り返す、という意味になります。
つまり、次の処理は「USB通信機能の準備ができていない場合、何もしないをずっと繰り返す」という動作になります。
while( !Serial ) {
}
なんだかややこしいですが、Arduino Microでシリアルモニタを使う場合、深いことは考えずにこの2行が必要って覚えておけばOKです!
第21回の記事のスケッチはなぜ動いていたのか
第21回のシリアルモニタの解説記事で使用した次のスケッチでは、シリアルモニタの準備ができるまで待つ、ということをしていませんでした。
/*
* 内容: シリアルモニタのテスト
* 1秒に1回データを送信する
*/
void setup() {
Serial.begin(9600); // シリアルモニタの設定(データの速度は9600)
}
void loop() {
Serial.println("シリアルモニタのテスト"); // シリアルモニタにデータを送信する
delay(1000); // 1秒待つ
}
でもこのスケッチをArduino Microボードに送ってシリアルモニタを動作させると、問題なく「シリアルモニタのテスト」という文字が表示されます。
これはloop
関数により何度もSerial.println
関数で文字を表示しているためです。上のスケッチのケースでは、初めてのloop
関数の処理のSerial.println
による表示は失敗しています。
もう少し詳しく処理を追うと、次のようになっています。
setup
関数の中でSerial.begin(9600);
によりUSB通信機能の準備を開始します。
この段階ではUSB通信機能によるシリアルは使えません。- 次に
loop
関数を実行します。loop
関数の最初はSerial.println
関数によりシリアルモニタに文字列を表示しようとしますが、この段階ではまだUSB通信機能の準備できていませんので、この文字列は表示されません。 - 次に
delay(1000);
で1秒待ちます。
この間にUSB通信機能の準備が完了し、Serail.println
が正しく動作するようになります。 loop
関数は繰り返されますので、再度Serial.println
関数が処理されて文字が表示されます。delay(1000);
で1秒待ちます- このあと、❹と❺の動作の繰り返しなります
更新履歴
日付 | 内容 |
---|---|
2020.1.18 | 新規投稿 |
2021.8.27 | 新サイトデザイン対応 |
2025.1.17 | 説明内容一部変更 |
とてもわかり易いです!ありがとうございます!