mcommit's message

ソフトウェア開発の仕事をしているsimotinといいます。記事の内容でご質問やご意見がありましたらお気軽にコメントしてください\^o^/

Rubyを使ってRaspberry Pi3でシリアル通信(UART通信)をする

昨日はGPSモジュールを使って遊んでみました。

mcommit.hatenadiary.com

記事でも少し書きましたが、せっかくGPSモジュールが使えるのでRaspberryPIを使って遊んでみたいと思いました。

GPSモジュール(U-blox NEO-6M)のインターフェースはシリアルなので手始めにRaspberryPIでシリアル通信ができるようにする必要があるのですが少してこずりましたので設定等を書いておきたいと思います。

環境

OS

OSは公式サイトからダウンロードしたRaspbianです。

www.raspberrypi.org

注意点として、RASPBIAN JESSIEをつかったのですが、それまでのwheezyと設定方法が異なる点等があるようです。

UART通信のピン

ここでのシリアル通信というのは、RaspberryPiのピンヘッダにあるUARTのピンを使うことを指しております。
動作確認はUSB-シリアル変換ケーブルを使ってRaspberryPi-PC間で通信をさせます。

RaspberryPiのUARTのピン番号は、

6 :GND
8 :TXD0
10:RXD0

になります。

f:id:simotin13:20160908231238j:plain


$uname -a
Linux raspberrypi 4.4.13-v7+ #894 SMP Mon Jun 13 13:13:27 BST 2016 armv7l GNU/Linux

UARTを使う為の設定

結論ですが、SDにRaspbianをインストールして起動させただけではUARTの通信はできませんでした。

いろいろ試した結果以下の2点を行うことでうまくシリアル通信することができました。

必要な設定作業ですが、

  1. raspi-configによるSerialの有効化
  2. cmdline.txtの編集

の2点です。

raspi-configによるSerialの有効化


$sudo raspi-config
によりraspberrypiの設定画面が立ち上がりますので、

「9 Advanced Options」

「 A7 Serial Enable/Disable shell and kernel messages on the serial connection 」

を選択し、シリアル通信の有効化を行います。

「Would you like a login shell to be accessible over serial?」
と聞かれますのでYesを選択し、最後に「Finish」を選択すると自動的に再起動がかかります。

再起動後、上記の設定により、

/dev/serial0

というデバイスが追加されていると思います。


$ls /dev/*

などで確認してみてください。

cmdline.txtの編集

/dev/serial0
が問題なく追加されれば、次は/boot/cmdline.txtを編集します。

私の手元にあるファイルでは、


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

となっています。
上記のraspi-configでシリアル通信を有効化した後だと、

console=serial0,115200
という文字列が記載されていると思いますが、UARTを純粋にアプリケーションで使うにはこちらを削除しておく必要があります。

UARTをコンソールの入出力として使う場合は削除する必要は有りません。
UARTがシリアルコンソールとして有効になっている場合、TeraTerm等で接続すると、


raspberrypi login:
Raspbian GNU/Linux 8 raspberrypi ttyS0
というログインのための出力が表示されます。

cmdline.txtを編集後は本体を再起動する必要があります。

再起動後、いよいよUARTが使える状態になっています。

動作確認

Linuxでは、端末ソフトとしてminicomやscreenを使うことが一般的ですが、今回はRubyのSerialPortを使ってエコープログラムを書いてみました。
Rubyはデフォルトではインストールされていないので自力でインストールが必要です。
Rubyをインストールする前にlibssl-develを入れておく必要があります。

シリアルポート用のライブラリであるserialportはgemでインストールできます。


$gem serialport

受信した文字列をそのまま返すエコープログラムです。

require 'serialport'

# 9600bps
# データビット:8ビット
# ストップビット:1ビット
# パリティなし
sp = SerialPort.new('/dev/serial0', 9600, 8, 1, 0) 
sp.puts "serial0 open"

# echo loop
loop do
  line = sp.gets
  # 確認のため受信文字列を標準出力
  puts line
  sp.puts line
end

sp.close

PC側からTeraTermで文字を送信すると、送った文字がちゃんとRaspberryPiから返ってきました!よかったよかった!
※改行の初期値は[LF]になっているようです。

補足

ちなみにネットでいろいろ調べているとcmdline.txtに

rpitestmode=1 や enable_uart=1

といった記載をすれば動くという情報がありましたが、これらの記載はなくても問題なくシリアル通信できました。

最初に、/dev/ttyAMA0 で簡単にUART使えるだろうと思っていたのですがどうも /dev/serial0 がUARTに対応しているようです。

/dev/serial1 というデバイスファイルもありますが、こっちはなんなんだろう・・・

感想

Raspberrypiのユーザ用のピンは40ピンしかないのですが、改めてみてみると少ないですね、一般的なマイコンの基板だとUARTの口が2~3つくらい空いていたりするのですが、システム的に機能が豊富なのでユーザに提供できるUARTは1つだけになってしまったんだと思います。(でもUARTってシステム組む際に周辺モジュールとかと結構使うんだけどな・・・)

あとRaspberryPI3で追加されたWiFi機能は、分かっていたけど便利ですね。

無事シリアル通信も確認できたので明日からはGPSモジュールをつないで遊んでみたいと思います。

あと、FeliCaのリーダー・ライター(RC-S620S)も手元にあるのですが、RaspberryPiにつないでみたことが無かったのでこれを機につないで遊んでみたいと思います。

2017-07-09 追記

C言語でもシリアル通信を試してみた

上記の記事では、Rubyを使って書いてみたのですが、C言語でシリアル通信をするプログラムを書く際にRaspberry pi でも試してみました。

mcommit.hatenadiary.com