どうも、なかしー(@nakac_work)です。
僕は自動車や家電製品のマイコンにプログラミングをする組み込みエンジニアとして働いています。
マイコンを扱う中でも難しいのが通信です!
通信は送信と受信に分かれて行いますが、タイミングが少しズレただけでデータが化けてしまうなんてこともあります。
シリアル通信を使う場面として想定されるのが
- Xbeeで無線通信をしたい時
- 他のArduinoとデータの送受信をしたい時
- Arduino IDEでデータをモニタリングしたい時
などがあると思います。
Arduinoでシリアル通信が出来るようになると、電子工作で実現できることがもっと広がることでしょう!
この記事では「Arduinoのシリアル通信の使い方」を解説します。
動画でも解説しています。
シリアル通信とは?
シリアル通信が一体なにか知っていますか?
シリアル通信と対になるのがパラレル通信です。
シリアル通信とパラレル通信の違いはデータの送受信を1本の配線で行うか複数本の配線で行うかの違いです。
シリアル通信のメリットは「配線本数を少なく出来ること」です。デメリットは「送信側と受信側でタイミングを同期しないとデータを正しく送れないこと」です。
ここでお伝えしたいことは「送信側と受信側でタイミングを同期する必要がある」ということです。
パソコンとのシリアル通信で使うアスキーコードとは
パソコンにArduinoから数値データを送っても、パソコン上では数字として表示されません。
パソコンで数値を表示したいならアスキーコードに変換する必要があります。
アスキーコードに変換するなら、一桁ごとに数値と0x30hの論理和を計算して送信すればOKです。
Arduinoのシリアル通信の関数
シリアル通信用の関数の使い方を紹介します。
Serial.begin(speed)
シリアル通信の通信速度を設定する関数です。
引数のspeedには300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200のいずれかが入ります。
この通信速度は受信側の機器もしくはICと合わせる必要があります。
もしも、受信側のICが9600bpsだったらSerial.begin(9600)となります。
通信速度の単位はbps(ビットパーセック)で表され、1秒間に何ビット送れるかを表します。
1ビットを送る速さを知りたいなら1秒をbpsの値で割ると計算出来ます。
Serial.end()
この関数を呼び出すことでシリアル通信を終了して、汎用の入出力ピンとして使えるようになります。
再度、シリアル通信を行う際はSerial.begin(speed)を実行すればOKです。
Serial.available()
受信したデータのバイト数を返す関数です。
受信できるバイト数は64バイトとなっています。
冒頭で「シリアル通信はタイミングを合わせる必要がある」とお伝えしましたが、Serial.available関数を使えば、通信途中でデータを読み込むことを防げます。
具体的な使い方は後ほど紹介します。
Serial.read()
受信したデータを1バイト読みだすことが出来ます。
もしも、データがあればそのデータを返しますが、データがなければー1を返します。
受信したデータを保持する変数のデータ型はint型を使用してください。
Serial.peek()
1バイト分のデータを読み出すのはSerial.read関数と同じですが、バッファを読み取る位置は変化しません。
同じ文字を繰り返し読み取ることになります。
Serial.read関数と同じく、データがないときにはー1を返します。
Serial.flush()
データの送信が完了するまで待つ関数です。
タイミングを合わせるために必須です。
Serial.write(val)
シリアル通信ポートから引数のvalをそのまま送るのがこの関数です。
文字列の場合を送る時にも使います。
Serial.print(data, format)
引数dataに入れたデータが数字であればアスキーコードに変換して送信することが可能です。
文字列を入れた場合は文字列としてそのまま送信されます。
この関数を使えば、いちいち数値をアスキーコードに変換しなくて済むので便利です。
引数formatには表示したい基数を入力します。
BIN(2進数)、OCT(8進数)、DEC(10進数)、HEX(16進数)に対応しています。
Arduinoとパソコンでシリアル通信をしてみる
いくつかプログラムを作成しました。
パソコンからのデータをそのまま返す
int data = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
data = Serial.read();
Serial.write("from Arduino\n");
Serial.write(data);
Serial.write("\n");
Serial.flush();
}
}
Arduinoのシリアルモニタの画面下にある「LFのみ」を「改行なし」に変更してコンパイルしてください。
シリアルモニタに文字を入力して送信を押すと下のような実行結果になります。
カウントアップタイマーの数値をパソコンに送信する
約1秒ごとにカウントアップするタイマーの数値をパソコンに送信します。
正確に1秒を計るにはシリアル通信の処理に掛かる時間を加味して、delayの値を変えてあげる必要があります。
unsigned char time = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print(time);
Serial.write("\n");
delay(1000);
time++;
}
実行結果はこんな感じです。
Arduinoのシリアル通信の使い方
この記事では「Arduinoのシリアル通信の使い方」について解説しました。
ポイントは
- シリアル通信は送受信間でタイミングを合わせる(同期させる)必要がある
- Arduinoからパソコンに数値を送るときはアスキーコードに変換する必要がある
- 通信スパンが短い場合はSerial.available関数とSerial.flush関数を使用してタイミングがズレるのを防止する
Arduino関連の人気記事
>>【Arduino入門キット】電子工作の勉強におすすめ【こんなに安くていいの?】
>>Arduinoでできることを紹介【逆にできないことは何?】
当ブログで人気のArduino入門キット