ラズパイPicoの4系統のシリアル通信(UART)の使い方

ラズパイPicoのシリアル(UART)通信

「RaspberryPi Pico」には外部通信用として2系統(UART0,1)のシリアル通信がありますが、他にもパソコンとの通信やシリアルモニタで文字を送受信して動作確認を行う時に使用する「USBシリアル」があります。

さらに「Arduinoのコマンド」を使用することでプログラムで任意の端子を割り付けてシリアル通信を行う「ソフトウェアシリアル」も使用することができます。

これら4系統のシリアル通信(UART)の使い方について詳しく紹介します。

開発環境は「C言語」を使用した「ArduinoIDE」を使用、ボード設定はPhilhower氏の「Raspberry Pi Pico/RP2040」を使用しています。

「Raspberry Pi Pico」のためのArduinoIDEのインストール方法は以下のリンクで詳しく紹介しています。

ラズパイPico/Pico WのArduinoIDEインストール方法と初期設定、使い方紹介
Raspberry Pi Pico/Pico WのC言語での開発環境 ArduinoIDEのインストールから初期設定、使い方、Lチカでの動作確認まで詳しく紹介します。
スポンサーリンク

1.シリアル通信(UART)とは

UART通信とは、SPIやI2C通信のような通信タイミングに必要なクロック信号が無いため「非同期通信」と呼ばれます。
クロック信号が無いので、通信を行うデバイス間で同じ通信速度(ボーレート)を設定しておく必要があります。

よく使用される通信速度(ボーレート)は以下になります。
1200 /2400 /4800 /9600 /19200 /38400 /57600 /115200 (単位:bps)

I2CやSPI通信とは異なり、マスター/スレーブのような関係はありません。


UART通信では以下の2つの信号線を使ってデータの送受信を行います。

・TX:データ送信(トランスファー)用
・RX:データ受信(レシーブ)用

送信用端子「TX」と受信用端子「RX」の2本線を使用しますが、お互いのGND(0V)を接続しておく必要があります。
2つのデバイス間で、以下のように送信用端子と受信用端子が交差するように接続します。

送信用端子「RX」↔︎ 受信用端子「TX」
受信用端子「TX」↔︎ 送信用端子「RX」
GND(0V)↔︎ GND(0V)
スポンサーリンク

2.ラズパイPicoの4系統のシリアル(UART)通信について

「Raspberry Pi Pico」には以下の4系統のシリアル通信があり、これらは同時に使用することができます。

・USBシリアル:プログラム書き込み、シリアルモニタでのデータ送受信用
・UART0:外部通信用1
・UART1:外部通信用2
・ソフトウェアシリアル:ソフトウェアで任意の入出力端子を割り付けて使用

「USBシリアル」はパソコンと通信するために使用するため通信速度以外はプログラムで操作することはできません。

「UART0,1」は使用する端子をプログラムで指定して使用しますが、使える端子は決まっています。

「ソフトウェアシリアル」は入出力端子であれば任意の端子をプログラムで指定して使用することができます。

スポンサーリンク

3.使用可能な端子について

「Raspberry Pi Pico」の端子配列は以下のようになります。(公式サイトより抜粋

ラズパイ(Raspberry Pi) Pico 端子配列

シリアル通信に使用可能な端子は以下表になります。

シリアル通信名送信用端子受信用端子
UART0UART0 TXUATR0 RX
UART1UART1 TXUART1 RX
ソフトウェアシリアルGP0〜GP22
GP26〜GP28
GP0〜GP22
GP26〜GP28

「UART0,1」は以下の端子が使用可能です。

・UART0(TX, RX):(GP0, GP1※初期値)/(GP12, GP13)/(GP16, GP17)
・UART1(TX, RX):(GP4, GP5)/(GP8, GP9※初期値)
全ての端子で試してはいませんが、並んで配置されているTXとRXの組み合わせだけでなく、離れた端子同士の組み合わせでも使用できるようです。
しかし、配線時に間違いの元になるので特に理由がなければ並んで配置されている組み合わせで使用した方が良いでしょう。

4.サンプルプログラム(コピペ)

プログラムは以下に2種類準備したので「コピペ」して書き込んでください。

1つ目の①は単純に4系統のシリアル通信の送信用端子(TX)から順番に文字データを出力するものです。
2つ目の②は送信用端子(TX)から出力した文字データを自分の受信用端子(RX)に入力して、データをリレーしていく、4系統のシリアル通信の送受信を確認するものです。

動作確認にはこの後で紹介する、自作の外付けシリアルモニタを使用すると簡単に確認できますが、LEDの点灯でもデータを送受信したことだけは確認できるようになっています。

① 4系統のシリアル通信データ送信のみ確認用

4系統のシリアル通信の送信のみのプログラムです。
送信のみの確認ですが、プログラム的には送受信両方使用可能な状態になっています。
各シリアル通信の使い方の確認用としてできるだけシンプルに作成しています。


サンプルプログラムは以下になります。コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

#include <SoftwareSerial.h>
SoftwareSerial mySerial(14, 15); // RX, TX(ソフトウェアシリアル)

// 初期設定 -------------------------------------------------------------------
void setup() {
  Serial .begin(9600);    // USB(シリアルモニタ)初期化
//  Serial1.setRX(17);    // 標準設定以外の端子を使用する場合(UART0)
//  Serial1.setTX(16);
  Serial1 .begin(9600);   // UART0初期化 TX:GP0 / RX:GP1
  Serial2 .begin(9600);   // UART1初期化 TX:GP8 / RX:GP9
  mySerial.begin(9600);   // ソフトウェアシリアル初期化
  
  pinMode(20, INPUT_PULLUP); // スイッチ GP20を入力端子(プルアップ)に設定
  pinMode(25, OUTPUT);       // LED GP25を出力端子に設定
}
// メイン処理(繰り返し)-------------------------------------------------------
void loop() {
  Serial.println("USB");        // USB(シリアルモニタ)出力
  delay(100);
  Serial1.println("Serial1");   // UART0出力
  delay(100);
  Serial2.println("Serial2");   // UART1出力
  delay(100);
  mySerial.println("mySerial"); // ソフトウェアシリアル出力
  
  digitalWrite(25, HIGH); // LEDを点灯
  delay(100);
  digitalWrite(25, LOW);  // LEDを消灯
  delay(600);
}

② 4系統のシリアル通信データ送受信確認用

4系統のシリアル通信の送受信を確認するプログラムです。

自分で送信したデータを自分へ入力してデータをリレーしていきます。
このために「UART0」と「UART1」「ソフトウェアシリアル」はそれぞれの送信端子と受信端子を接続しておきます。

「ArduinoIDE」のシリアルモニタ機能を使用して、入力した文字を「USBシリアル」で受信して「UART0」から送信します。この時にLEDを1回点灯させるようにしています。
「UART0」は受信したデータを「UART1」から出力してLEDを1回点灯させます。
「UART1」は受信したデータを「ソフトウェアシリアル」から出力してLEDを1回点灯させます。
「ソフトウェアシリアル」はデータを受信したらLEDを1回点灯させます。

最終的に「ソフトウェアシリアル」から入力した文字データが送信されてシリアルモニタ「BASIC」に表示されれば全てのシリアル通信が機能していることが確認できます。

データを受信するごとにLEDを点灯させているので、データの表示を確認しなくてもLEDが4回点灯すればデータの送受信が行われたことは確認できます。

サンプルプログラムは以下になります。コピペ(コピー&ペースト)して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

#include <SoftwareSerial.h>       // ソフトウェアシリアルのヘッダーファイルを準備
SoftwareSerial mySerial(14, 15);  // RX, TX(ソフトウェアシリアル)

// 変数宣言
String c; // 受信データ(文字)格納用

// 関数 ----------------------------------------------------------------------
void led() {  // LED点灯
  digitalWrite(25, HIGH); // LEDを点灯
  delay(200);             // 遅延時間
  digitalWrite(25, LOW);  // LEDを消灯
  delay(200);             // 遅延時間
}
// 初期設定 -------------------------------------------------------------------
void setup() {
  Serial .begin (9600);   // USB(シリアルモニタ)
//  Serial1.setRX(17);    // 標準設定以外の端子を使用する場合(UART0)
//  Serial1.setTX(16);
  Serial1 .begin (9600);  // UART0 標準設定 TX:GP0 / RX:GP1
  Serial2 .begin (9600);  // UART1 標準設定 TX:GP8 / RX:GP9
  mySerial.begin(9600);   // ソフトウェアシリアル
  
  pinMode(25, OUTPUT);    // LED GP25を出力端子に設定
}
// メイン処理(繰り返し)-------------------------------------------------------
void loop() {
  // 受信データ処理
  if (Serial.available()) {             // 受信データ(USBシリアル)がある間繰り返し
    c = Serial.readStringUntil('\n');   // 受信データを\nの手前まで取得(Serial)
    led();
    Serial.println(c);                  // 文字列出力(USBシリアル)
    Serial1.println(c);                 // 文字列出力(Serial1)
  }
  if (Serial1.available()) {            // 受信データ(Serial1)があれば
    c = Serial1.readStringUntil('\n');  // 受信データを\nの手前まで取得(Serial1)
    led();
    Serial2.println(c);                 // 文字列出力(Serial2)
  }
  if (Serial2.available()) {            // 受信データ(Serial2)があれば
    c = Serial2.readStringUntil('\n');  // 受信データを\nの手前まで取得(Serial2)
    led();
    mySerial.println(c);                // 文字列出力(mySerial)
  }
  if (mySerial.available()) {           // 受信データ(Serial2)があれば
    c = mySerial.readStringUntil('\n'); // 受信データを\nの手前まで取得(ソフトウェアシリアル)
    led();
  }
  delay(100); // 遅延時間
}

5.自作外付けシリアルモニタで動作確認

動作確認は下画像の自作のシリアルモニタを使用すると簡単に確認することができます。
これは「M5Stack社」の「BASIC」を使用して受信したシリアルデータを液晶表示器に表示できるようにしたものです。

ラズパイPicoのシリアル(UART)通信

「BASIC」では外部通信用として3系統のシリアル通信を使用することができます。
下画像は「BASIC」の端子配列で本体裏側に同じような表示があります。

ラズパイPicoのシリアル(UART)通信

「BASIC」の端子R0, R2, 21(GROVEコネクタG21共通)はデータ受信(RX)用端子です。
外部デバイスのデータ送信(TX)用端子を接続することで、受信したデータが「BASIC」の液晶画面に表示されます。
どれか1つでも3つ全部でも可(3つの場合それぞれに0.1s程度のタイムラグが必要)
※外部デバイスとお互いの0Vを接続する必要があります。


「M5Stack BASIC」を使用したシリアルモニタの作り方(コピペで書き込むだけ)は以下のリンクで詳しく紹介しています。

M5Stackをシリアルモニターに使用。パソコン不要でデータ確認Atom、Arduinoに便利
マイコンボードのシリアル出力を液晶やパソコンではなく、外付けして単体で確認できるシリアルモニタが欲しかったのでM5Stackで作りました。 ATOMやArduino等のマイコンボードのデータが手軽に確認できて便利と思うので紹介します。

実際に以下のように動作確認を行いました。

まず、①のサンプルプログラムの動作確認は以下のようになります。
自作のシリアルモニタ「BASIC」に下画像のように各端子を接続します。

ラズパイPicoのシリアル(UART)通信

シリアルモニタ「BASIC」のデータ受信(RX)端子にラズパイPicoのデータ送信(TX)端子「UART0(端子1)」「UART1(端子11)」「ソフトウェアシリアル(端子20)」と「GND(端子23)」を接続しています。


「BASIC」の電源を入れると下画像のようにプログラムで指定した文字データ「Serial1」「Serial2」「mySerial」が順番に表示され続けます。
「BASIC」に接続している配線を抜くと、それに対応した「ラズパイPico」からの送信データが表示されなくなるため、それぞれのデータが正しく送信されているのが確認できると思います。

ラズパイPicoのシリアル(UART)通信

パソコンに送信されている「USBシリアル」のデータも確認してみましょう。
「ArduinoIDE」のシリアルモニタ機能を使用して確認します。
下画像のように「ツール」→「シリアルモニタ」と選択します。

ラズパイPicoのシリアル(UART)通信

下画像のようにシリアルモニタのウインドウが表示され、プログラムで指定した「USB」という文字が表示され続けると思います。

ラズパイPicoのシリアル(UART)通信

これで全てのデータが正しく送信されていることが確認できます。
送信端子番号をいろいろ変えて動作確認してみましょう。


次に送信だけでなく受信の動作確認も行います。

確認方法は、自分で送信したデータを自分へ入力してデータをリレーしていきます。
このために下画像のように「UART0(端子1-2)」と「UART1(端子11-12)」「ソフトウェアシリアル(端子19-20)」はそれぞれの送信端子と受信端子を接続しておきます。
「ソフトウェアシリアル」の送信端子(端子20)と「GND(端子23)」はシリアルモニタの「BASIC」にも接続します。

ラズパイPicoのシリアル(UART)通信

接続したら、下画像のようにシリアルモニタを起動して、まずは右下でデータを送信する時の末尾に送信する「改行コード」を「LFのみ」に設定し、通信速度を「9600bps」に設定します。

設定したら送信データ入力部に「Hello」と入力してエンターを押してみましょう。

ラズパイPicoのシリアル(UART)通信

シリアルモニタに文字を入力してエンターを押すと入力した文字データを「USBシリアル」で受信して「UART0」から送信します。この時にLEDが1回点灯します。
「UART0」は受信したデータを「UART1」から出力してLEDを1回点灯させます。
「UART1」は受信したデータを「ソフトウェアシリアル」から出力してLEDを1回点灯させます。
「ソフトウェアシリアル」はデータを受信したらLEDを1回点灯させます。

最終的に下画像のようにシリアルモニタで入力した「Hello」という文字データが送信されていき、外付けのシリアルモニタ「BASIC」に表示されれば全てのシリアル通信が機能していることが確認できます。

ラズパイPicoのシリアル(UART)通信
データを受信するごとにLEDを点灯させているので、データの表示を確認しなくてもLEDが4回点灯すればデータの送受信が行われたことは確認できます。

送受信端子番号をいろいろ変えて動作確認してみましょう。


シリアルモニタの「改行コード」として「LF」を使用していますが「CR」というものもあります。この「改行コード」についても紹介しておきます。
「LF」はラインフィード「CR」はキャリッジリターンと言い、機械式の印字装置、タイプライターの動作に由来するものです。
タイプライターでは印字装置が固定で、紙の方が移動することで文字送りや行送りが行われ、紙を固定している部分をキャリッジと言いました。
キャリッジを左端に戻す(リターン)ことを「キャリッジリターン(CR)」と言い、行(ライン)を送る(フィード)ことを「ラインフィード(LF)」と言いました。
タイプライターでは「キャリッジリターン」して「ラインフィード」することで「改行」を行なっていました。
この名残からプログラミングの文字出力の表現として使用されています。
開発環境にもよりますが「ラインフィード(LF)」は特殊文字(エスケープシーケンス)で「’\n’」と書かれ、これだけで改行を表すものも多いです。

6.サンプルプログラムの詳細

サンプルプログラムのシリアル通信用プログラムについて紹介します。

まず、サンプルプログラムの 1行目でソフトウェアシリアルを使うためのヘッダーファイルを準備しています。

次に 2行目で「SoftwareSerial」を「mySerial」というコマンドで使用できるようにしています。(インスタンスの作成)
この時に以下のように送受信端子を指定します。

SoftwareSerial mySerial( RX端子番号, TX端子番号);  // RX, TX(ソフトウェアシリアル)

RX端子番号, TX端子番号:使用する入出力端子番号「GP〜」の「〜」の部分の数値で指定します。


シリアル通信(UART)を使用するには「通信速度」を指定して以下のように初期化を行うことで使用できるようになります。

Serial.begin( 通信速度 ) ;       // USBシリアル通信
Serial1.begin( 通信速度) ;      // UART0 初期値 GP0(TX),GP1(RX)
Serial2.begin( 通信速度 ) ;     // UART1 初期値 GP8(TX),GP9(RX)
mySerial.begin( 通信速度 ) ;  // ソフトウェアシリアル(設定した入出力端子を使用)

通信速度:通信速度(ボーレート)を数値で指定します。
  通信速度には以下のようなものがあるので通信相手と合わせます。(単位 bps)
  1200/2400/4800/9600/19200/38400/57600/115200
  ※省略すると9600bpsとなります。


通信端子として初期値以外の端子を指定する場合は以下のように設定します。

Serial1.setRX( RX端子番号); // 標準設定以外の端子を使用する場合(UART0)
Serial1.setTX( TX端子番号);
Serial1.begin( 通信速度);      // UART0
※UART1を設定する場合はSerial1のところをSerial2として設定します。

RX端子番号, TX端子番号:使用する入出力端子番号「GP〜」の「〜」の部分の数値で指定します。

「UART0,1」に使用できる端子は決められています。
どの端子が使用可能かは「3.使用可能な端子について」で確認しましょう。


シリアルデータの送受信には主に以下のようなコマンドを使用します。(他にもたくさんあります。)

Serial1. print ( データ) ;  // “データ(文字列)”を送信
Serial1.available( ) ;         // 受信データのバイト数(文字数)を取得
Serial1.read( ) ;                // 受信データを1文字取得
Serial1.readStringUntil( \n) ;  // 受信データを指定した文字の手前まで文字列で取得

今回は受信データの取得には 「Serial.readStringUntil(‘\n‘)」を使用しました。
これで、受信したデータを区切り文字「’\n‘」の手前まで変数(文字列)に格納することができます。

データの区切り文字として「\n(改行)」を指定しているため、パソコンのシリアルモニタから送信するデータにも「改行コード」として「LF」をつけて送信する必要があります。
\n」の手前までのデータを受信するため、受信データをそのまま送信すると次のデータには「\n」が付きません。
次のデータ受信のために「print」ではなく「println」で「\n(改行)」を付けて送信しましょう。

7.まとめ

「Raspberry Pi Pico」の4系統のシリアル通信について紹介しました。

「Raspberry Pi Pico」には標準で2系統(UART0,1)のシリアル通信とパソコン通信用の「USBシリアル」プログラムで任意の端子を割り付けられる「ソフトウェアシリアル」が使えます。

同時に全部使うことは稀だとは思いますが、UART0とUART1は使える端子が決まっているため、部品の配置によって、近い端子を使用したい時にどちらも使えると配線に自由度が出て便利です。

ソフトウェアシリアルは入出力端子を自由に割り付けられるのでもっと便利ですが、プログラム容量は少し大きくなります。「UART0,1」の端子がどうしても使えない場合にプログラムメモリに余裕があれば使用しましょう。

動作確認には「M5Stack BASIC」を使用した外付けのシリアルモニタで簡単に行えます。
作り方(コピペで書き込むだけ)は以下のリンクで詳しく紹介しています。

M5Stackをシリアルモニターに使用。パソコン不要でデータ確認Atom、Arduinoに便利
マイコンボードのシリアル出力を液晶やパソコンではなく、外付けして単体で確認できるシリアルモニタが欲しかったのでM5Stackで作りました。 ATOMやArduino等のマイコンボードのデータが手軽に確認できて便利と思うので紹介します。

コメント

タイトルとURLをコピーしました