Raspberry Pi でシリアル通信

[投稿日] 2015年7月30日
[最終更新] 2016年11月2日

2016年9月11日:Raspberry Pi 3およびRaspbian Jessieに対応。

Raspberry Pi(以下RPi)でのシリアル通信について、やや情報が錯綜していたので調べたことをまとめます。Raspberry Piとモジュール間のシリアル通信を想定しています。USB変換を用いると、Mac <-> モジュールでも、同じように操作・表示できたり。

スポンサーリンク

GPIOかUSBか

RPiにはシリアルポートがありませんので、当然のことながらそれ以外のインタフェースからシリアル通信を行うことになります。基板上のGPIOピン経由のUARTか、USB端子かです。個人的には、相手先が5VトレラントであればUSBを利用したほうが良いと思います。設定が簡便で、ハードやソフトの影響を受けづらいからです。相手先の耐圧が3.3Vの場合でも、降圧させたほうが楽ではないかと思います。

GPIO

RPiにはGPIOピンが用意されています。旧型は26ピン、RPi 2以降はそれに14ピンを加えた40ピン。そのうちのいくつかは、シリアル通信のために用いられます。ピンアサインについては「RPi Low-level peripherals – eLinux.org」を参照。これにしたがって配線をします。たとえばTXはピン番号8、RXはピン番号10、5Vの電源供給が必要ならばそこはピン番号2、といった具合に。

配線はジャンパワイヤを使えばよいですね。楽です。見た目は線が飛び出て不格好かもしれませんが。TXとRXの指し間違えに注意です。通信相手のTX、RXと逆になるかと思います。電圧は3.3Vのピンと5Vのピンがあります。相手先の耐電圧には注意します。

USB

USB-TTLないし、USB-シリアルポートが使えます。便利ですが、電圧が5Vなので、相手先の耐電圧には注意しましょう。。。よくある市販のケーブルはだいたいPL2303搭載なので、Raspberry Piはドライバを新しく入れず、たいがいいけると思います。

USB-TTL

USB-TTLケーブルを使います。TX、RX、V、GNDをそれぞれ所定のピンに。

この製品は、カスタマーレビュー欄にもあるとおり、赤5V、黒GND、緑Tx(3.3V)、白Rx(3.3V)のようです。

USB-シリアル

相手の接続先がシリアルポートの場合。PCでもよく使います。Raspberry Piが接続するのはだいたい小型のモジュールだと思うので、出番は少ないかも。

これはIO-DATAの変換アダプター USB-RSAQ6で、ちょっと他のものに比べるといいお値段がするのですが、IO-DATAのサイトでサポート外ではあるもののUbuntu12.04とFedora13での動作確認が報告されていた(「USB-RSAQ6シリーズ | RS-232C | IODATA アイ・オー・データ機器」)ので、あまり悩まないで済むかなと思ったのです。実際、特に何もしないで使うことができました。まぁでも安いやつでも問題ないと思います。

GPIOピン(UART)を使う場合の前準備

GPIOピンを使用して通信する場合、設定ファイルの書き換えが必要です。「Using UART instead of USB | Adafruit Ultimate GPS on the Raspberry Pi | Adafruit Learning System」を参考にして書き換えます。

この設定を行うと、たとえばPCからRaspberry Piにシリアル通信でログインして操作することができなくなるので注意。

/boot/cmdline.txt

/boot/cmdline.txt を、以下のように書き換えます。

変更前

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

変更後

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

gettyの無効化

Raspbian JessieとRaspbian Wheezyでやり方が変わります。Jessieより、initプログラムがsystemdに変更された影響です。

Raspbian Wheezyの場合

/etc/inittab を、以下のように書き換えます。

変更前

#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

変更後

#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

終わったらrebootします。

Raspberry Pi 2 + Raspbian Jessieの場合

systemctlコマンドを用います。(参考:「Using UART instead of USB | Adafruit Ultimate GPS on the Raspberry Pi | Adafruit Learning System」)

sudo systemctl stop serial-getty@ttyAMA0.service
sudo systemctl disable serial-getty@ttyAMA0.service

終わったらrebootします。

Raspberry Pi 3 + Raspbian Jessieの場合

Raspberry Pi 3の場合、さらに手順が増えます。まず、Raspberri Pi 2の時と同じように、systemctlコマンドでdaemonを停止および無効化するのですが、ターゲットの名前が違います。

sudo systemctl stop serial-getty@ttyS0.service
sudo systemctl disable serial-getty@ttyS0.service

次に、/boot/config.txtに、次の一行を追記します。

enable_uart=1

そうしたらrebootです。どうやら、Raspberry Pi 3ではBluetoothが内蔵されたことによる影響のようです。

各種プログラム

配線だけしても、通信に手間がかかっては仕方ありません。しかしながら、簡単に読み出すことができます。ここではGPIOピンつまりUART経由で通信を行うものとして、ttyAMA0(Raspberry Pi 3ではttyS0)を叩きますが、USBを使う場合は、/dev以下のtty*を調べて、それらしいものを見つけます。

cat

catでデバイス名を指定すると、内容が出力されます。Unixの強さを見せつけられる思いです。読み出すだけなので、もちろん対話的な操作はできません。

$ sudo cat /dev/ttyAMA0

screen

いつまでもにわかな私にとって、screenはbyobuの元という印象でしかありませんでしたが、これでデータを受け取ることができます(参考:「serial – Mac の screen コマンドでシリアル通信 – Qiita」。対話的な操作も可能です。終了するときは「Ctrl-a Ctrl-k」と入力します。

$ screen /dev/ttyAMA0 9600

cu

cu コマンドは今回調べていて初めて知りました。Call up another system だそうです。色々あるものですね(参考:「<エレキジャック: 玄箱PRO (KURO-BOX/Pro),玄柴> http://www.eleki-jack.com/Kurobox-pro2/2007/08/cu.html」)。終了するときは「~.」と入力。マニュアル見る限りバイナリの転送も楽そうなので今度やってみたいと思います。

$ sudo apt-get install cu
$ sudo cu -s 9600 -l /dev/ttyAMA0

スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。