6.1 PCとの通信

ここまで、MSP430でのプログラムを行うにあたり
USBケーブルでMSP430LaunchPadをPCに接続して
プログラムを書き込んできました。

このケーブルは、プログラムを書き込むだけではなく
ここまでのプログラムをMSP430LaunchPadで動作させるための電力も
USBケーブルにより供給しています。

このケーブルは、PCから情報を送るだけでなく
PCへ情報を返すこともできます。
このPCとの間の通信は、シリアル通信という部類の通信で行われます。
(場合によってRS-232やUARTなどと呼ばれたりもします。
 これらの規格は厳密には異なりますが、ここでは同じような仲間だと思ってください。
 良い例えでないかもしれませんが、サラブレッドもアラブ馬も道産子もシマウマも馬は馬です)

この通信を扱う命令としてSerial.~という命令が準備されています。
~の部分に具体的な命令がきます。
この通信で使う命令はシリアル通信に関する命令なので
必ずserial.で始まると覚えてください。

シリアル通信のサンプルプログラムとして、スケッチ例として準備されている
”ASCIITable”を見ていきます。図6-1の用にメニューからサンプルを開いてみましょう。

図6-1 サンプル”ASCIITable”の選択

なお、実際のサンプルプログラムと見比べる際に
コメント部分は省略していますので注意してください。

ASCIIコードとは、コンピュータが文字を扱うときのコードの一つです。
コンピュータは数値しか扱えないので、数値に文字を対応させて
文字の処理を行います。
その文字コードの中で最も基本的なコードがASCIIコードです
詳細はこちらを見るか、検索してみてください。

10進数で0~127までの数字に文字が割り当てられています。
なお、0~31までの32文字と127の33文字分は制御文字となっており
文字と言うより、文字を送受信する際の機能が割り当てられています。

つまり、具体的な文字は32の1文字分のスペース” ”から、126までの”~”までとなります。

さて、それでは、プログラムを見ていきたいと思います。

void setup() { 
  Serial.begin(9600); 

  Serial.println("ASCII Table ~ Character Map"); 


int thisByte = 33; 

void loop() { 

  Serial.write(thisByte); 

  Serial.print(", dec: "); 

  Serial.print(thisByte); 

  Serial.print(", hex: "); 

  Serial.print(thisByte, HEX); 

  Serial.print(", oct: "); 

  Serial.print(thisByte, OCT); 

  Serial.print(", bin: "); 

  Serial.println(thisByte, BIN); 

  if(thisByte == 126) { 

    while(true) { 
    continue
    } 
  } 

  thisByte++; 

}

コメントを省くと、命令のほどんどがシリアル通信に関する命令でできている
プログラムということがわかります。

まずは、setup関数を見ると

void setup() { 
  Serial.begin(9600); 

  Serial.println("ASCII Table ~ Character Map"); 


となっています。
シリアル通信を始めるには、Serial.beginで通信速度を設定し通信を始める準備をします。

命令の書式は、

Serial.begin( [通信速度(bps)] )

となります。
通信速度の部分には、300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200を設定できます。
bpsとはbits per secondの略で1秒間に何ビット送信するかということになります。
1文字は8ビットなので、1秒間に9600ビットということは、9600/8で1200文字を送受信できます。
この通信速度は、コンピュータ側の設定と同じにします。
基本的には、9600のままで大丈夫です。

次の命令として
Serial.println("ASCII Table ~ Character Map"); 

とあります。
これは、シリアルに文字列を出力する命令です。
文字列を出力する命令として
printなら単純に文字列を出力し
printlnなら文字列のを出力した最後に改行を出力します。

ですので、ここでは単純に
ASCII Table ~ Character Map
という文字列+改行を、コンピュータに出力します。

loop関数に入る前に

int thisByte = 33; 

としており、thisByteに33を代入しています。

loop関数の中では、順に以下のように表示を行っています

1. ここでは、thisByteに対応する文字を1文字だけ出力します。
   数値に対応する文字を1文字だけ出力する命令が、Serial.writeになります。
  Serial.write(thisByte); 


2. ここでは、”, dec:”の文字列を出力します。改行はしません。
  Serial.print(", dec: "); 


3. ここでは、thisByteの値を出力します。print命令の()内に変数名を記述すると
   変数の中身を10進数の文字列にして出力します。初回は33になります。
  Serial.print(thisByte); 


4. ここでは、”, dec:”の文字列を出力します。改行はしません。
  Serial.print(", hex: "); 


5. ここでは、thisByteの値を16進数で出力します。print命令の()内に変数名だけを記述すると
   変数の中身を10進数の文字列で表示しますが、変数名の後に”,HEX”と記述すると
   変数の中身を16進数の文字列にして表示します。
  Serial.print(thisByte, HEX); 


6. ここでは、”, oct:”の文字列を出力します。改行はしません。
  Serial.print(", oct: "); 


7. ここでは、thisByteの値を8進数で出力します。変数名の後に”,OCT”と記述すると
   変数の中身を8進数の文字列にして表示します。
  Serial.print(thisByte, OCT); 


8. ここでは、”, bin:”の文字列を出力します。改行はしません。
  Serial.print(", bin: "); 


9. ここでは、thisByteの値を2進数で出力します。変数名の後に”,BIN”と記述すると
   変数の中身を2進数の文字列にして表示します。
   この命令はprintlnなので、ここで改行します。
  Serial.println(thisByte, BIN); 


つづいて、loop関数の中では

  if(thisByte == 126) { 

    while(true) { 
    continue
    } 
  } 




  thisByte++; 

となっており、thisByteが126であればif文の{ }内の処理に移ります。
if文の{ }内では
while(true)
となっているため、このwhile文は( )内の条件が常に真となり、
while文の{ }内を永遠繰り返すことになります。
この、while文の{ }には、countinue;
とありますが、これはループ処理をスキップして1つ前の条件文に戻るときに使う命令です。
しかし、ループ処理をスキップしてもthisByteの値は126のままなので、
永遠ここでとどまることになります。

thisByteは126でないときは、
thisByte++;
を実行しthisByteが1増加してloopの最初に戻ります。

では、このプログラムを実行してみましょう。
…、これまで通り実行しただけでは、PC側にデータが届いたかどうか確認する術がありません
そこで、シリアル通信を行うウィンドウを開きます。

energiaの右上にある のアイコンをクリックしましょう。
このアイコンにマウスのカーソルを合わせると、白くハイライトし「シリアルモニタ」と表示されます。(図6-2)

図6-2 シリアルモニタのアイコン 

クリックすると、シリアルモニタ(図6-3)が開きます。

図6-3 シリアルモニタ

プログラムが動いていれば、図6-4のように次々と文字がシリアルモニタに出力されます。

図6-4 シリアルモニタへの表示例

表示は、プログラムの解説のところで見たように、各行で順番に
アスキーコードに対応した文字、10進数の値、16進数の値、8進数の値、2進数の値
の順となっています。
シリアルモニタ右側のスクロールバーを上にドラッグすれば、
アスキーコードの値が10進数で33から表示し始めていることが確認できます。

もう一度このプログラムを実行させたいときは、ボード上のリセットボタンを押してください。
再度アスキーコード33から126までを順に表示していきます。

ここまでで、LaunchPadからPCにデータを送信する流れを見てきました。

逆に、PCからマイコンにデータを送ることを考えます。
データを送るための基礎として、1文字だけ文字をPC→マイコンと送信します。
setup関数の中でP1_0はOUTPUTに設定し、loop関数を以下のようにします

void loop()
{
  char cc;

  if(Serial.available() > 0) {
    cc=Serial.read();
    Serial.write(cc);
    if(cc=='R') digitalWrite(P1_0,HIGH);
    if(cc=='C') digitalWrite(P1_0,LOW);
  }
}

ここで、Serial.available()はシリアル通信で送られてきた文字数
(厳密には、マイコンが受信したが、まだ読み出していない文字数)を返す関数です
これが0より大きいとき、つまり受信した文字があるときifの中で
Serial.read()によりchar型の変数ccに1文字読み込みます。

Serial.write(cc)とすることで、シリアルモニタから読み出した文字を
再びPCに送り、シリアルモニタに表示させます

続いて、ccの中身により赤LEDを点灯させるか消灯させるか処理を行います
このように、PCから文字を受信する場合はSerial.availableSerial.read()
使うことで文字を読み込むことができます。

次はLaunchPadでボタンを操作するのに合わせて、PCにデータを送信させるプログラムに取り組みます。

0 件のコメント:

コメントを投稿