汎用の入力端子・出力端子は扱い易いですが、複雑なデータ(センサの測定値や液晶画面に表示するテキストなど)を送受信することは簡単ではありません。Arduinoには複雑なデータを送受信するための通信インタフェースがいくつか装備されています。今回は、その中でも一番基礎的なシリアル通信の通信方式やプログラミング方法について紹介します。
概要
シリアルインターフェースはコンピュータ同士がデータの送受信を行う最も古い方法の一つで、1960年代に開発されました。
RS-232(RS – 推奨標準、推奨標準)という名前でルールが作られ、2000年代に入ってUSBが広く使われるようになるまでの長い間、PC用の機器の接続などに広く利用されてきました。英語圏では使用されているモジュールの名前にちなんでUART(ユアート)とも呼ばれています。UARTは「Universal Asynchronous Receiver/Transmitter」の略称で、非同期シリアル通信とパラレル通信を相互に変換する回路を指します。
RS-232Cインタフェースの利点は、ほぼすべてのマイクロコントローラやコンピュータと接続できる点です(変換器が必要な場合もあります)。 しかし、クロック信号がないためにノイズによる干渉の影響を受けやすく、特に通信速度が速い場合やケーブルが長い場合には、影響を受けやすくなります。コンピュータ上でのテスト出力に限ってシリアルインタフェースを使用する場合もあります。
通信方式
データ伝送に必要なのは、送信・受信それぞれ1本の通信線(と共通のグランド接続)だけです。データビットは、負論理で順番に(直列に)送信していきます。負論理とは、Hiレベル(+3 Vから+15 V)が0、Loレベル(-3 Vから-15 V)が1を表していることを意味しています。
データ伝送は、ビットグループ(バイト)をビット単位で順番に伝送します。
通常、1バイト=8ビットとすることが多いですが、8ビットではない場合もあります。これに加えて、ビットグループの先頭にはデータの始まりを指定するスタートビット、末尾には通信エラーが起こっていないかを確認するためのパリティビットと、データの終わりを示すストップビットが付いています。
スタートビットを読み取ることにより、受信側は新しいデータが始まるタイミングを認識します。しかし、一つ一つのビットを間違いなく読み取るためには、スタートビットを受信してから一定の時間間隔で信号を読み取らなければならないため、伝送速度:1ビットの情報の送信に割り当てた時間を知っておく必要があります。受信側が送信側で使用した速度と異なる速度で読み取った場合、信号を正しく受け取れません。
Arduinoのシリアル通信
シリアルインタフェースの通常の通信速度は 300 ~115200 Baudが使われ、一般のアプリケーションでは9600 Baudが最高速度であるとされています。
コンピュータ上のArduino IDEは、コンパイラがマシンコードに変換した後に、スケッチをArduinoに転送するためにシリアルポートを使用します。そのために、Arduinoボード上にUSB-シリアル変換回路を搭載することで、コンピュータとArduinoがシリアル通信できるようになっています。USBケーブルでコンピュータと接続していない場合は、この変換回路は無視できます。
また、デジタル端子D0(Arduinoから出力)、D1(Arduinoへ入力)で、シリアル信号を送受信できます。この時、プログラムでシリアルインタフェースを使用している場合は、デジタル入出力ピンD0、D1は出入力ピンとしては使用できなくなります。
シミュレーション
2つのArduino間で文字列を送受信します。通信速度を合わせておかなければならないので、setup()関数内で両方とも9600 Baudに設定します。
送信側Arduino
送信側Arduinoは文字列「LED ON」をSerial.write()関数でシリアル送信します。Serial.write()関数は1バイトずつ、または複数バイトの送信が可能です。文字列送信後はLED接続ピンをHIGH出力にします。Serial.flush()はデータ送信が完了するのを待ちます。これを5回繰り返します。
#include <SoftwareSerial.h> //library //library is needed /* send and receive UART data */ char TX[8] = "LED ON"; // char data array void setup() { pinMode(2, OUTPUT); // LED pin output Serial.begin(9600); // set baudrate } int x = 0; // datatype whileloop void loop() { // do this while x is smaller then 5 for example while(x < 5){ Serial.write(TX,7); // send byte array digitalWrite(2, HIGH); // make IO logic HIGH delay(500); x++; // increament our var x Serial.flush(); // clear send buffer } digitalWrite(2, LOW); // make IO logic LOW }
受信側Arduino
受信側Arduinoはシリアルデータを受け取ると、「GOT IT」をシリアルポートに出力します。受信データがあるかどうかは、Serial.available()関数で確認できます。受信データはSerial.readBytes()関数で読み込めます。
#include <SoftwareSerial.h> // library is important /* send and receive UART data */ char RX[8]; // incoming data array void setup() { pinMode(12, OUTPUT); // set port output Serial.begin(9600); // set baud usb } void loop() { if (Serial.available() > 0) // check if there data in buffer { Serial.println("GOT IT\n"); // we got something Serial.readBytes(RX,7); // read the incoming data array[] digitalWrite(12, HIGH); // set pin high Serial.flush(); // clean out RX data if needed } else { digitalWrite(12,LOW); // set pin low } }
TINKERCADシミュレーション
シミュレーションを開始ボタンを押してください。シリアルモニタは、「コード」を開き、「シリアルモニタ」のタブを展開すると表示できます。もし表示されない場合は、TINKERCADのページに飛んでください。
コメントを残す