Arduinoでプログラムを作っているとコンパイルではエラーにならないものの、実際に意図した動作にならないことはよくあります。
このような不具合を一般的にバグといいます。
このバグを見つけて修正する作業のことをデバッグといいます。
デバッグの最も基本的な手法としてプログラムの要所で状態を表示するというものがあります。
Arduinoではシリアルモニタという機能を使って、Arduinoからパソコンに文字列を送ることでデバッグを行うことがしばしばあります。
本日はシリアルモニタの使い方を学んでみます。
前回はこちら
シリアル通信(送信)
Arduinoは、シリアル通信(UART)という通信機能を使ってパソコンなどの機器と文字列をベースの通信をすることができます。
以下のプログラムはArduino起動時(リセット直後)に、パソコンに対して「Start」という文字を送信し、その後、1秒おきにパソコンに対して「X」という文字を送信しつづけるプログラムです。
void setup() {
Serial.begin(9600);
Serial.print("Start");
}
void loop() {
delay(1000);
Serial.print("X");
}
Arduinoから受け取った通信データ(文字列)は、Arduino-IDEに付属するシリアルモニタを使って確認することができます。
2行目: Serial.begin(9600);
シリアル通信を利用するために必要な初期設定です。
通信を行なう前にプログラム内で1回だけ実行する(setup関数で設定するのが一般的です)。
引数の9600は、通信速度(bps)を表している。
受信する速度も合わせないといけません。IDEの通信速度設定も合わせて9600にしておきます。
9600bpsの以外に、よく利用される通信速度としては、19200bps、38400bps、57600bps、115200bpsがあります。
bpsは「bit per second」の略で、1秒間に何ビット送信するかを表わしています。
半角英数字は1文字が1バイト(=8bit)なので、(データビット8bit、スタートビット1bit、ストップビット1bitの通信設定の場合)、9600bpsでは1秒間に960文字を送信することができます。
3行目:Serial.print("Start");
引数に指定した文字列を送信します。
受信側で見やすいように改行を付加して文字列をする「Serial.println("Start")」という関数もあります。
送信可能な文字列は英数字と一部の記号のみで、「Serial.print("高専")」のようにして日本語等は送信することはできません。
変数の送信
シリアル通信では固定の文字列だけではなく変数に格納された数値等を送信することもできます。(変数については次回詳しく勉強します)
以下はnumという変数に格納された数字を1秒おきにシリアルモニタに表示するプログラムです。
int num = 0;
void setup() {
Serial.begin(9600);
Serial.println("Start");
}
void loop() {
delay(1000);
Serial.println(num,DEC);
num++;
}
8行目:Serial.printlnの第2引数
Serial.printlnの第2引数は数値の書式指定を行うものです。
- 指定なし:10進数 ex:Serial.print(78) →「78」出力
- DEC:10進数 ex:Serial.print(78, DEC) →「78」出力
- BIN:2進数 ex:Serial.print(78, BIN) →「1001110」出力
- HEX:16進数 ex:Serial.print(78, HEX) →「4E」出力
シリアルモニタ上に変数名も示した「num=12」のような表示を行いたい場合は、以下のように連続してSerial.print/Serial.printlnを利用すればできます。
int num = 0;
void setup() {
Serial.begin(9600);
Serial.println("Start");
}
void loop() {
delay(1000);
Serial.print("num=");
Serial.println(num,DEC);
num++;
}
シリアル通信(受信)
シリアル通信の受信は、送信よりもやや複雑なプログラムとなります。
次に示すプログラムはパソコンから「a」という文字を受信するたびにLEDを反転するプログラムです(「a」以外には反応しません)。
#define LED 13
char dat;
void setup(){
pinMode(LED,OUTPUT);
Serial.begin(9600);
Serial.println("Start");
}
void loop() {
if(Serial.available()>0){
dat=Serial.read();
if(dat=='a'){
digitalWrite(LED,!digitalRead(LED));
}
}
}
2行目:char dat;
char型の変数datを宣言しています。char型は、半角英数字を1文字だけ格納するための型です。
11行目:if(Serial.available()>0){
Serial.available は、通信によりArduinoに届いている文字の数を取得する命令です。(厳密には、受信バッファに何バイトのデータがあるかを取得する命令)。
⇒何も受信していなければSerial.availableの戻値は0
⇒何らかの文字を受信していれば、Serial.availableの戻値は1以上の数値
12行目:dat=Serial.read();
Serial.readは、受信した文字列から1文字を取得する命令です。
ここでは1文字を取得し、char型の変数datに格納しています。
13行目:if(dat=='a'){
13行目では文字の比較を行なっています。
「a」という1文字を表現するためには、'a' のように表記します。
1文字以上の文字列を表現する ”abc” とは表記が異なるので十分に注意してください。
⇒「if (dat==”a”)」「if (dat==’abc’)」「if (dat==”abc”)」のような表記は、すべてエラーとなるので注意
⇒「stopという文字列を受信したら○○をする」というような複数文字列の処理は簡単にはできません。
Arduino 実験⑤
デジタル13番ポートにアクティブHのLEDが接続されています。
シリアル通信で「X」という文字を受信するとLEDが点灯、「Y」という文字を受信するとLEDが消灯、「Z」という文字を受信するとLEDが反転、その他の文字を受信したときは「ERROR」という文字列を改行付きでシリアル通信で送信するプログラムを作成してください。
なお、初期状態でLEDは消灯しているものとします。
次回はこちら